中文 | English

【物聯網開發系列】基礎技能篇:如何視覺化聲音(下篇)

文/曹永忠、吳佳駿、許智誠、蔡英德

本篇是「物聯網開發」系列中「基礎技能篇」的第 2 篇專文之下篇:聲音是非常常見的一種媒介(曹永忠, 2016a, 2016b),如何視覺化聲音,一直是大家希望做到的一件關鍵工作,所以我們可以透過行動裝置,如手機、平板等裝置,可以察覺到我們知道聲音的強度,在物聯網領域中的應用,將會是一個非常好的開發典範,本文就是使用聲音輸入元件,取得使用者的聲音後(曹永忠, 吳佳駿, 許智誠, & 蔡英德, 2017b),使用開發板建立視覺化監控網站,提供使用者可以透過瀏覽器來查看聲音強度的機制為本文的主要重點。

前文提要

在物聯網開發系列(基礎技能篇):如何視覺化聲音(上篇)中(曹永忠, 吳佳駿, 許智誠, & 蔡英德, 2017a),我們已揭露電路,與 Google Developer  網路元件,並且也已完成透過使用 Ameba RTL8195AM 開發版來做顯示 Gauge 元件的網頁伺服器,然而我們還沒談到,這些元件如何使用的原理等等,這些都會在本文中提到,最後完成我們如何視覺化聲音的主要議題。

解析 Google  Gauge HTML Code

由下表所示,我們可以了解,必須將「 https://www.gstatic.com/charts/loader.js 」的 Google 網路元件的資源載入。

表 4 使用 Google 資源

<html>

<head>

<script type=”text/javascript” src=”https://www.gstatic.com/charts/loader.js”></script>

<script type=”text/javascript”>

google.charts.load(‘current’, {‘packages’:[‘gauge’]});

google.charts.setOnLoadCallback(drawChart);

由下表所示,我們可以了解要顯示 Google Gauge 元件,必須將 Gauge 的值給予 Google Gauge 元件。

表 5設定顯示資料

function drawChart() {

 

var data = google.visualization.arrayToDataTable([

[‘Label’, ‘Value’],

[‘Brother’, 68]

]);

 

 

由上表所示,我們可以了解,[‘Label’, ‘Value’] 為資料標題,第二列的 [‘Brother’, 68] 為資料第一筆,而前面為資料名稱,後面資料內容。

表 6 Gauge的值解析

[‘Label’, ‘Value’]è資料標題

第二列的[‘Brother’, 68] 為資料第一筆,

前面為資料名稱,後面資料內容

 

由下表所示,我們必須設定 Google Gauge 元件大小(寬度與高度),在 Google Gauge 元件上,還有警示區域的設定。

表 7 Gauge的大小設定與警示區域設定

var options = {

width: 800, height: 800,

redFrom: 80, redTo: 100,

yellowFrom:60, yellowTo: 80,

minorTicks: 5

};

由上表所示,我們可以了解 width: & height 為 每一個 Gauge 的寬與高,redFrom: 紅色區域開始, redTo:紅色區域結束,yellowFrom: 黃色區域開始, yellowTo: 黃色區域結束,而 minorTicks: 5  則表示最小刻度。

 

表 8 Gauge的值解析

width: , height 為 每一個Gauge的寬與高

redFrom: 紅色區域開始, redTo:紅色區域結束

yellowFrom:黃色區域開始, yellowTo:黃色區域結束

minorTicks: 5  最小刻度

 

由下表所示,我們可以了解產生一個 Gauge 元件,並顯示在 chart_div 的區域之中。

表 9 產生一個Gauge元件

var chart = new google.visualization.Gauge(document.getElementById(‘chart_div’));

 

chart.draw(data, options);

由上表所示,我們可以了解 new google.visualization.Gauge(document.getElementById(‘chart_div’)) 就是產 生Gauge 元件, 而chart.drw(data, options);畫出 Gauge 儀表板。

 

表 10 Gauge 產生命令解析

var chart = new google.visualization.Gauge(document.getElementById(‘chart_div’))產生儀表板

chart.draw(data, options);畫出儀表板

 

由下表所示,我們可以了解,真正產生瀏覽器動作的區域是在 <body>…</body> 之間,所以真正產生圖形的內容為 <div id=”chart_div” style=”width: 800px; height: 800px;”></div>。

表 11真正產生瀏覽器動作命令

<body>

<div id=”chart_div” style=”width: 800px; height: 800px;”></div>

</body>

由上表所示,我們可以了解,真正產生圖形的內容為 <div id=”chart_div” style=”width: 800px; height: 800px;”></div>,為了設定產生圖形的大小,需要一些參數,所以 width: 800px  為繪圖空間寬度,width: 800px 繪圖空間寬度。

表 10 Gauge元件之瀏覽器動作命令

<div id=“chart_div” style=“width: 800px; height: 800px;”></div>產生叫” chart_div”的 繪圖空間

width: 800px  繪圖空間寬度

height: 800px;繪圖空間高度

 

視覺化聲音

由於原來視覺化的Google Chart顯示三個資料,但是我們只需要顯示一個聲音資訊,所以我們修改Gauge的視覺化物件,Visualization: Gauge,(Developers, 2016),我們將原來 HTML 程式碼修改為可以見到下表所示之單一元件之視覺化 Gauge 之 HTML 程式碼。

我們將 Ameba RTL8195AM 開發板的驅動程式安裝好之後,我們打開 Ameba RTL8195AM 開發板的開發工具:Sketch IDE 整合開發軟體(軟體下載,安裝 Ameba RTL8195AM SDK 請至官網,Ameba RTL8195AM 安裝驅動程式),攥寫一段程式,如下表所示之建立聲音視覺化程式一,我們就可以視覺化聲音的資料。

表 3 建立聲音視覺化程式一

建立聲音視覺化程式一(WebServiceNoiseGauge)
#include <WiFi.h>

 

char ssid[] = “BruceSonyC5”;      // your network SSID (name)

char pass[] = “12345678”;     // your network password

 

// your network password

int keyIndex = 0;                 // your network key Index number (needed only for WEP)

 

int status = WL_IDLE_STATUS;

WiFiServer server(80);

 

#define SoundPin 1

int SoundValue = 0;

int SoundValue1 = 0;

void setup() {

Serial.begin(9600);      // initialize serial communication

// check for the presence of the shield:

if (WiFi.status() == WL_NO_SHIELD) {

Serial.println(“WiFi shield not present”);

while (true);       // don’t continue

}

 

String fv = WiFi.firmwareVersion();

if (fv != “1.1.0”) {

Serial.println(“Please upgrade the firmware”);

}

 

// attempt to connect to Wifi network:

while (status != WL_CONNECTED) {

Serial.print(“Attempting to connect to Network named: “);

Serial.println(ssid);                   // print the network name (SSID);

 

// Connect to WPA/WPA2 network. Change this line if using open or WEP network:

//    status = WiFi.begin(ssid);    //no pass

status = WiFi.begin(ssid, pass);    //wpa use

// wait 10 seconds for connection:

delay(10000);

}

server.begin();                           // start the web server on port 80

printWifiStatus();                        // you’re connected now, so print out the status

}

 

 

void loop() {

SoundValue = analogRead(SoundPin) ;

SoundValue1 = map(analogRead(SoundPin),0,1023,0,100)  ;

// wifi code here

// listen for incoming clients

WiFiClient client = server.available();

if (client)

{

Serial.println(“Now Someone Access WebServer”);

 

Serial.println(“new client”);

// an http request ends with a blank line

boolean currentLineIsBlank = true;

while (client.connected())

{

if (client.available())

{

char c = client.read();

Serial.write(c);

// if you’ve gotten to the end of the line (received a newline

// character) and the line is blank, the http request has ended,

// so you can send a reply

if (c == ‘\n’ && currentLineIsBlank)

{

// send a standard http response header

client.println(“HTTP/1.1 200 OK”);

client.println(“Content-Type: text/html”);

client.println(“Connection: close”);  // the connection will be closed after completion of the response

client.println(“Refresh: 5”);  // refresh the page automatically every 5 sec

client.println();

client.println(“<!DOCTYPE HTML>”);

client.println(“<html>”);

// output the value of each analog input pin

client.println(“<head>”);

client.println(“<script type=’text/javascript’ src=’https://www.gstatic.com/charts/loader.js’></script>”);

client.println(“<script type=’text/javascript’>”);

client.println(“google.charts.load(‘current’, {‘packages’:[‘gauge’]});”);

client.println(“google.charts.setOnLoadCallback(drawChart);”);

client.println(”  function drawChart() {“);

client.println(“var data = google.visualization.arrayToDataTable([[‘Label’, ‘Value’],[‘Noise’,”);

client.println(SoundValue1);

client.println(“],]);”);

client.println(” var options = {width: 700, height: 700,redFrom: 90, redTo: 100,yellowFrom:75, yellowTo: 90,minorTicks: 5};”);

client.println(“var chart = new google.visualization.Gauge(document.getElementById(‘chart_div’));”);

client.println(“chart.draw(data, options);”);

client.println(“}”);

client.println(“</script>”);

client.println(“</head>”);

client.println(“<meta charset=’utf-8′>”);

client.println(“<body>”);

client.println(“<div id=’chart_div’ style=’width: 700px; height: 700px;’></div>”);

client.println(“</body>”);

 

client.println(“</html>”);

break;

}

if (c == ‘\n’)

{

// you’re starting a new line

currentLineIsBlank = true;

} else if (c != ‘\r’)

{

// you’ve gotten a character on the current line

currentLineIsBlank = false;

}

}

}

// give the web browser time to receive the data

delay(1);

 

// close the connection:

client.stop();

Serial.println(“client disonnected”);

}

 

 

delay(800) ;

}

 

void printWifiStatus() {

// print the SSID of the network you’re attached to:

Serial.print(“SSID: “);

Serial.println(WiFi.SSID());

 

// print your WiFi shield’s IP address:

IPAddress ip = WiFi.localIP();

Serial.print(“IP Address: “);

Serial.println(ip);

 

// print the received signal strength:

long rssi = WiFi.RSSI();

Serial.print(“signal strength (RSSI):”);

Serial.print(rssi);

Serial.println(” dBm”);

// print where to go in a browser:

Serial.print(“To see this page in action, open a browser to http://”);

Serial.println(ip);

}

程式下載

 

如下圖所示,我們可以看到監控視窗之建立聲音視覺化程式一結果畫面。

圖 5建立聲音視覺化程式一結果畫面

由上圖所示,我們得知用 Ameba RTL8195AM開發版建立的網頁伺服器,其網址在:建立聲音視覺化程式一結果畫面,我們使用瀏覽器,輸入網址:192.168.88.103,可以看到下圖所示的建立聲音視覺化程式一之瀏覽器畫面。

 

圖 6建立聲音視覺化程式一之瀏覽器畫面

 

後續

本篇是「物聯網開發」系列中「基礎技能篇」的第 2 篇專文:如何視覺化聲音的上篇,主要告訴讀者,在物聯網開發之中,如何透過 Google Developer 網路資源來協助我們快速視覺化聲音強弱,本文就是使用聲音輸入元件,將其聲音使用網站(網頁)方式,可以提供使用者可以透過瀏覽器來查看聲音強度為本文的主要目的。

後續筆者還會繼續發表「物聯網開發」系列的文章,在未來我們可以創造出更優質,更具未來性的物聯網(Internet of Thing:IOT)產品開發相關技術。

敬請期待更多的文章。

 

作者介紹

曹永忠(Yung-Chung Tsao),目前為自由作家暨專業Maker,專研於軟體工程、軟體開發與設計、物件導向程式設計,商品攝影及人像攝影。長期投入創客運動、資訊系統設計與開發、企業應用系統開發、軟體工程、新產品開發管理、商品及人像攝影等領域,並持續發表作品及相關專業著作。

Email: prgbruce@gmail.com
Line ID:dr.brucetsao
臉書社群(Arduino.Taiwan):https://www.facebook.com/groups/Arduino.Taiwan/
Github網站:https://github.com/brucetsao/
Youtube:https://www.youtube.com/channel/UCcYG2yY_u0m1aotcA4hrRgQ

吳佳駿(Chia-Chun Wu),國立中興大學資訊科學與工程學系博士,現任教於國立金門大學工業工程與管理學系專任助理教授,目前兼任國立金門大學計算機與網路中心資訊網路組組長,主要研究為軟體工程與應用、行動裝置程式設計、物件導向程式設計、網路程式設計、動態網頁資料庫、資訊安全與管理。Email: ccwu0918@nqu.edu.tw

許智誠(Chih-Cheng Hsu),美國加州大學洛杉磯分校(UCLA) 資訊工程系博士,曾任職於美國 IBM 等軟體公司多年,現任教於中央大學資訊管理學系專任副教授,主要研究為軟體工程、設計流程與自動化、數位教學、雲端裝置、多層式網頁系統、系統整合。Email: khsu@mgt.ncu.edu.tw

蔡英德(Yin-Te Tsai),國立清華大學資訊科學系博士,目前是靜宜大學資訊傳播工程學系教授、靜宜大學計算機及通訊中心主任,主要研究為演算法設計與分析、生物資訊、軟體開發、視障輔具設計與開發。Email:yttsai@pu.edu.tw

 

參考文獻:

Developers, G. (2016, 2017/1/1). Visualization: Gauge.   Retrieved from https://developers.google.com/chart/interactive/docs/gallery/gauge

曹永忠. (2016a). 物聯網系列:讓電腦發出音效(基本原理篇). 智慧家庭.  Retrieved from https://vmaker.tw/archives/12788

曹永忠. (2016b). 物聯網系列:讓電腦發出音效(簡單揚聲器篇). 智慧家庭.  Retrieved from https://vmaker.tw/archives/12811

曹永忠, 吳佳駿, 許智誠, & 蔡英德. (2017a). 物聯網開發系列:基礎技能篇:如何視覺化聲音(上篇). 物聯網開發系列.

曹永忠, 吳佳駿, 許智誠, & 蔡英德. (2017b). 物聯網開發系列:基礎技能篇:透過聲音控制燈泡明滅. 物聯網開發系列.

 

分享到社群

曹永忠

曹永忠 (Yung-Chung Tsao) ,目前為自由作家暨專業Maker,專研於軟體工程、軟體開發與設計、物件導向程式設計,商品攝影及人像攝影。長期投入創客運動、資訊系統設計與開發、企業應用系統開發、軟體工程、新產品開發管理、商品及人像攝影等領域,並持續發表作品及相關專業著作。 Email:prgbruce@gmail.com Line ID:dr.brucetsao 作者網站:https://www.cs.pu.edu.tw/~yctsao/ 臉書社群(Arduino.Taiwan):https://www.facebook.com/groups/Arduino.Taiwan/ Github網站:https://github.com/brucetsao/ Youtube:https://www.youtube.com/channel/UCcYG2yY_u0m1aotcA4hrRgQ