Más contenido relacionado La actualidad más candente (20) Similar a IoT 與 WoT 物聯網裝置實作:使用 Arch Pro 與 mbed (20) IoT 與 WoT 物聯網裝置實作:使用 Arch Pro 與 mbed1. Speaker: Jollen (陳俊宏)
Founder, Mokoversity
Founder, 仕橙3G教室 (Moko365)
<jollen@jollen.org>
www.mokoversity.com
IoT 與 WoT 物聯網裝置實作
Ben、Polo、Larry
<benshiue@orangicetech.com>
www.oranwind.com
使⽤用Arch Pro 與 mbed
2. Agenda
• Google 「 Physical Web」 計畫
• ARM mbed ⼊入⾨門
• Arch Pro 介紹
• Digital Interface 與 Sensor 數據讀取
2
6. Internet of Things
Web of Things
An Application Layer that simplifies the creation of
Internet of Things applications
* of Things
11. IoT OS
mbed OS
We are creating a modern full-stack operating system that is
designed specifically for ARM Cortex®-M-based MCUs; the
worlds leading 32-bit microcontrollers that already sell in the
billions.
mbed Device Server
Analogous to a Web Server that accepts connections from
mobile phones or web browsers, a Device Server handles the
connections from IoT devices.
mbed Tools
online compiler (Web IDE) etc.
13. Analogous to a Web Server that accepts connections from
mobile phones or web browsers, a Device Server handles
the connections from Internet of Things (IoT) devices.
A Device Server is a key enabler for cloud service providers, operators and
enterprises to access the IoT growth market with production deployments,
bringing end node devices in to the world of web services.
27. Introduction
27
• Arch Pro 是⼀一款⽤用於快速原型設計的 mbed 平台的
開發板,採⽤用 ARM Cortex-M3 內核的 NXP
LPC1768 微控制器,帶有以太網、USB Host/
Device 等接⼝口。
•Arch Pro 採⽤用 Arduino 的硬件接⼝口,並且帶兩個
Grove 接⼝口,可以很⽅方便的連接各種各樣的 Shield
和 Grove 模塊,再結合豐富的軟件庫,讓開發變得
快速、簡單。
31. Grove - Button
• 按鈕元件包含⼀一顆獨⽴立的「瞬
間開/關」按鈕。 「瞬間」是意
思是,當按鈕被按壓後,按鈕
會⽴立刻主動反彈。按下按鈕時,
按鈕元件會使 GPIO pin 得到⼀一
個 HIGH 信號,反彈時則輸出
LOW 信號。
32. Grove - Button
pinout 接法
sensor pin mbed pin
1 - SIG DigitalIn
2 - NC 不⽤用接 不⽤用接
3 - Vcc Vout - 3.3V Vout - 3.3V
4 - GND GND GND
33. 使⽤用 Button 控制 LED ,按鈕被按壓後 LED 亮,反彈時則 LED 不亮
#include "mbed.h"
DigitalOut myled(LED1);
DigitalIn button(p21);
int main()
{
while(1) {
if (button)
myled = 1;
else
myled = 0;
}
}
Grove - Button
範例:
34. Grove - Buzzer
• 蜂鳴器(Buzzer)元件主要由
⼀一個壓電式蜂鳴器組成。可以
將蜂鳴器連接到LPC1786 的數
位輸出(Digital Output),當
輸出為HIGH 時發出聲響。
• 亦可將蜂鳴器連接到類⽐比輸出,
此時可讓蜂鳴器產⽣生各種⾳音效。
35. Grove - Buzzer
pinout 接法
sensor pin mbed pin
1 - SIG DigitalOut
2 - NC 不⽤用接 不⽤用接
3 - Vcc Vout - 3.3V Vout - 3.3V
4 - GND GND GND
36. 使⽤用 Button 控制蜂鳴器,當 Button 的按鈕被按壓後,蜂鳴器會發出聲響,反彈時蜂鳴器則不
會發出聲響。
#include "mbed.h"
DigitalOut Buzzer(p20);
DigitalIn button(p21);
int main()
{
while(1) {
if (button)
Buzzer = 1 ;
else
Buzzer = 0;
wait(0.7); // simple debouncing
}
}
Grove - Buzzer 元件
範例:
37. Grove - Rotary Angle Sensor
• 旋轉⾓角度感測器元件提供類⽐比
輸出介於 0 -Vcc,可偵測⾓角度
為 0 - 300 度。
38. Grove - Rotary Angle Sensor
pinout 接法
sensor pin mbed pin
1 - SIG AnalogIn
2 - NC 不⽤用接 不⽤用接
3 - Vcc Vout - 3.3V Vout - 3.3V
4 - GND GND GND
39. 使⽤用 AnalogIn API 讀取旋轉⾓角度。
#include "mbed.h"
AnalogIn RotaryAngle(p15);
int main()
{
int value = 0 ;
value = RotaryAngle;
}
Grove - Rotary Angle Sensor
範例:
40. Grove - Light Sensor
• 光源感測器元件包含⼀一個光敏
電阻。當環境光源的強度上升
時,光敏電阻值將會下降。也
就是說,光亮時輸出訊號為
HIGH,⿊黑暗時為 LOW。
42. 使⽤用 Light Sensor 控制LED ,光亮時 LED 不亮,無光亮時則 LED 亮。
#include "mbed.h"
DigitalOut myled(LED1);
DigitalIn lighter(p21);
int main()
{
while(1) {
if(lighter == 1)
myled = 0 ;
else
myled = 1;
wait(0.2);
}
}
Grove - Light Sensor
範例:
45. 實作步驟
• 將 Base Shield 接在 Arch Pro
上
• 溫度感測器接 Universal 4 pin
Cable 線,並接在 Base Shield
的 A0
• 將四位數 LED 顯⽰示器接
Universal 4 pin Cable 線,並
接在 Base Shield 的 UART
• 記得將 Base Shield 切換⾄至 5V
VCC
45
46. Grove - Temperature Sensor
• 溫度感測器元件使⽤用溫敏電阻
偵測環境的溫度。當環境溫度
上升時,溫敏電阻值將會下降。
我們可以利⽤用這個特性去計算
出環境溫度。感測器可偵測的
範圍是 -40ºC - 125ºC,誤差為
±1.5ºC。
47. Grove - Temperature Sensor
pinout 接法
sensor pin mbed pin
1 - SCL AnalogIn
2 - SDA 不⽤用接
3 - Vcc Vout - 3.3V Vout - 3.3V
4 - GND GND GND
48. 使⽤用 AnalogIn API 讀取 Temperature Sensor 的資料,依 Temperature Sensor 的 datasheet 轉換出溫度。
#include "mbed.h"
AnalogIn device(p15);
int a;
float temperature;
int B = 3975; // B value of the thermistor
float resistance;
int main()
{
while(1) {
a = device * 675; // multiply ain by 675 if the Grove shield is set to 5V or 1023 if set to 3.3V
resistance = (float)(1023-a)*10000/a; // get the resistance of the sensor;
temperature = 1/(log(resistance/10000)/B+1/298.15)-273.15; // convert to temperature via datasheet ;
wait(0.8);
}
}
Grove - Temperature Sensor
範例:
50. ARM mbed pin 名稱定義
PinNames.h
PinNames.h,內容如下:
typedef enum {
// LPC Pin Names
P0_0 = LPC_GPIO0_BASE,
P0_1, P0_2, P0_3, P0_4, ….
// mbed DIP Pin Names
p5 = P0_9,
p6 = P0_8,
p7 = P0_7,
p8 = P0_6,
.
.
.
.
p27 = P0_11,
p28 = P0_10,
p29 = P0_5,
p30 = P0_4,
// Other mbed Pin Names
#ifdef MCB1700
LED1 = P1_28,
LED2 = P1_29,
LED3 = P1_31,
LED4 = P2_2,
#else
LED1 = P1_18,
LED2 = P1_20,
LED3 = P1_21, 50
52. GPIO
Analog I/O
• AnalogIn
• AnalogIn (Read/Getter/ADC)
• p15~p20
• AnalogIn(PinName pin)
• read(), [0.0, 1.0]
• read_u16(), [0x0, 0xFFFF]
• AnalogOut
• AnalogOut (Write/Setter/DAC)
• p18
• AnalogOut(PinName pin)
• write(float value)
• write_u16(unsigned short
value)
52
53. GPIO
Digital I/O
• DigitalIn I/O
• p5~p30
• DigitalIn(PinName pin)
• DigitalIn(PinName pin,
PinMode mode)
• read()
• mode(PinMode pull)
• is_connected()
• DigitalOut I/O
• p5~p30
• DigitalOut(PinName pin, int
value)
• write(int value)
• read()
• is_connected()
53
54. GPIO
Digital I/O
• BusIn
• BusIn(PinName p0, PinName
p1 = NC, PinName p2 = NC,
…, PinName p15 = NC)
• read()
• mode(PinMode pull)
• mask()
• BusOut
• BusIn(PinName p0, PinName
p1 = NC, PinName p2 = NC,
…, PinName p15 = NC)
• write(int value)
• read()
• mask()
54
55. GPIO
Digital I/O
• PortIn
• PortIn(PortName port, int
mask=0xFFFFFFFF)
• read()
• mode(PinMode mode)
• PortOut
• PortIn(PortName port, int
mask=0xFFFFFFFF)
• write(int value)
• read()
55
56. GPIO
Digital I/O
• PwmOut
• PwmOut(PinName pin)
• p21~p26
• write(float value)
• read()
• period(float seconds)
• period_ms(int ms)
56
57. GPIO
Digital I/O
• InterruptIn
• p5~p30, p19 and p20 除外
• rise (void(*fptr)(void))
• rise (T *tptr, void(T::*mptr)
(void))
• fall (void(*fptr)(void))
• fall (T *tptr, void(T::*mptr)
(void))
57
58. Grove - 3-Axis Digital
Accelerometer
• 數位三軸加速器元件,通常使
⽤用在需要偵測⽅方向、⼿手勢、動
作的應⽤用,能準確地反映物體
的運動性質。
59. Grove - 3-Axis Digital
Accelerometer
• 感測器本⾝身會回傳 0~63 的結果,我們可以透過此結果依表轉換成 G
值(1g=m/s^2)或者⾓角度(不建議使⽤用)。
• 數據解析對照表如下:
60. Grove - 3-Axis Digital Accelerometer
pinout 接法
sensor pin mbed pin
1 - DIO SCL
2 - CLK SDA
3 - Vcc Vout - 3.3V Vout - 3.3V
4 - GND GND GND
61. 使⽤用MMA7660FC Library,引⼊入MMA7660FC.h 標頭檔,來取得三軸加速器的數值,透過G 值對照表轉換成G 值。
#include "mbed.h"
#include "MMA7660FC.h"
#define ADDR_MMA7660 0x98 // I2C SLAVE ADDR MMA7660FC
MMA7660FC Acc(p28, p27, ADDR_MMA7660); //sda、cl、Addr,更換接⾓角時請務必更改此處
Serial pc(USBTX, USBRX);
// G 值對照表
float G_VALUE[64] = {0, 0.047, 0.094, 0.141, 0.188, 0.234, 0.281, 0.328, 0.375, 0.422, 0.469, 0.516, 0.563, 0.609, 0.656, 0.703, 0.750, 0.797, 0.844, 0.891, 0.938,
0.984, 1.031, 1.078, 1.125, 1.172, 1.219, 1.266, 1.313, 1.359, 1.406, 1.453, -1.500, -1.453, -1.406, -1.359, -1.313, -1.266, -1.219, -1.172, -1.125, -1.078, -1.031,
-0.984, -0.938, -0.891, -0.844, -0.797, -0.750, -0.703, -0.656, -0.609, -0.563, -0.516, -0.469, -0.422, -0.375, -0.328, -0.281, -0.234, -0.188, -0.141, -0.094, -0.047};
int main()
{
Acc.init(); // Initialization
pc.printf("Value reg 0x06: %#xn", Acc.read_reg(0x06)); // Test the correct value of the register 0x06
pc.printf("Value reg 0x08: %#xn", Acc.read_reg(0x08)); // Test the correct value of the register 0x08
pc.printf("Value reg 0x07: %#xnr", Acc.read_reg(0x07)); // Test the correct value of the register 0x07
while(1)
{
float x=0, y=0, z=0;
float ax=0, ay=0, az=0;
Acc.read_Tilt(&x, &y, &z); // Read the acceleration
wait_ms(100);
//換算成 G值
ax = G_VALUE[Acc.read_x()];
ay = G_VALUE[Acc.read_y()];
az = G_VALUE[Acc.read_z()];
wait(0.2);
}
}
Grove - 3-Axis Digital Accelerometer
範例:
63. Web of Thing
63
• 對 WoT 來說,最重要的觀念,就是以 URL 來表⽰示
IoT 裝置;為 IoT 加⼊入 URL 的觀念,就是 Google 提
出的 Physical Web 計畫。所以說,WoT 與 Physical
Web 是⼀一體兩⾯面的觀念,都是 IoT 正進⼊入的新發展
階段。
64. 準備⼯工作
• 使⽤用 Seeed Studio 設計與⽣生產的 Arch Pro 開發板
• LPC1768 本⾝身沒有 PHY 功能
• 使⽤用 LPC1768 + mbed shield ⼦子板
• 使⽤用 LPC1768 + wifi shield
64
65. 連接有線網路-⾃自定 IP 與 DHCP
使⽤用
EthernetInterface
Library
先匯⼊入 ARM mbed 提供的
EthernetInterface Library 後,
引⼊入 EthernetInterface.h 標頭檔,
即可設定 Static IP 位址或使⽤用
DHCP 進⾏行網路組態。
65
66. 連接有線網路-⾃自定 IP 與 DHCP
#include "mbed.h"
#include "EthernetInterface.h"
int main(void) {
eth = new EthernetInterface;
// eth->init(); Use DHCP
eth->init("192.168.21.81",
"255.255.255.0",
"192.168.21.2" );
eth->connect() ;
printf("IP Address is %srn", eth->getIPAddress());
}
66
67. 連接無線網路熱點-
⾃自定 IP 與 DHCP
使⽤用
WiflyInterface Library
先匯⼊入 ARM mbed 提供的
WiflyInterface Library 後, 引⼊入
WiflyInterface.h 標頭檔,即可設定
Static IP 位址或使⽤用 DHCP 進⾏行網
路組態。
67
68. 連接無線網路熱點-⾃自定 IP 與 DHCP
#include "mbed.h"
#include "WiflyInterface.h"
WiflyInterface wifly(p13, p14, p19, p26, "SSID",
"password", WPA);
int main(void) {
wifly.init(); // Use DHCP
wifly.init("192.168.21.45",
"255.255.255.0",
"192.168.21.2");
while (!wifly.connect());
printf("IP Address is %srn", eth->getIPAddress());
}
68
70. mbed 遇上 REST API
70
• 要讓 ARM mbed 裝置具備 REST API 能⼒力,最重要
的就是練習撰寫 httpd 功能。ARM mbed 提供 httpd
程式庫,能在裝置上⽣生成⼀一個輕量級的 Web
Server。
• 稍後將介紹 httpd 的使⽤用,並將 Dust Sensor 的即時
數據封裝為 REST API。⽤用⼾戶可透過瀏覽器,即時取
得 Dust Sensor 的數值。Dust Sensor 是空氣微粒的
感測器,並不包含在 Grove Starter Kit for mbed 套
件裡,需額外取得。
72. Grove - Dust Sensor
• 當空氣中的顆粒物進⼊入 Dust
sensor 時,顆粒物本⾝身的⼤大
⼩小、單位時間內進⼊入的數量會
影響感測器的電壓狀態,造成
⼀一⼩小段時間維持在低電壓。所
以在我們指定的某⼀一段測量時
間裡,藉由每⼀一次低電壓脈衝
佔⽤用的時間,可以計算出空氣
中顆粒物的濃度,檢測出空氣
品質。此感測器可檢測出直徑
> 1μm 的顆粒。
72
74. Dust Sensor 硬件原型製作
• 步驟如下:
• 將 ARM mbed LPC1768 開發版插在 mbed shield(須依照
mbed shield 上的圖⽰示⽅方向)。
• 將⿈黃⾊色跳線之⼀一端接在 Grove - Dust Sensor 的⿈黃⾊色⺟母頭端,⿈黃
⾊色跳線另⼀一端接在 mbed shield P5~P30 DigitalIn 任⼀一腳位
上,除了 P19、P20 腳位。
• 將紅⾊色跳線之⼀一端接在 Grove - Dust Sensor 的紅⾊色⺟母頭端,紅
⾊色跳線另⼀一端接在 mbed shield 5V 腳位上。
• 將⿊黑⾊色跳線之⼀一端接在 Grove - Dust Sensor 的⿊黑⾊色⺟母頭端,⿊黑
⾊色跳線另⼀一端接在 mbed shield GND 腳位上。
74
76. #include "mbed.h"
Serial pc(USBTX, USBRX);
InterruptIn probe(p8);
DigitalOut led(LED1);
Timer timer;
Ticker ticker;
uint32_t low_time = 0;
void down();
void up();
void down() {
probe.rise(&up); // 當電壓發⽣生由 LOW 狀態轉移到 HIGH 狀態時,呼叫 “up” function
timer.start(); // 開始計時
}
void up() {
timer.stop(); // 結束計時
probe.fall(&down); // 當電壓發⽣生由 HIGH 狀態轉移到 LOW 狀態時,呼叫 “down” function
low_time += timer.read_us(); // 取得已經歷的時間(毫秒)
timer.reset(); // 將計時器歸零
}
int main() {
...
probe.fall(&down) // 當電壓發⽣生由 HIGH 狀態轉移到 LOW 狀態時,呼叫 “down” function
ticker.attach(tick, 30); // 指定中斷事件觸發時要執⾏行的動作(呼叫 “tick” function),以及特定時間區間(本範例為 30 秒)
}
空氣品質偵測元件
範例:
76
77. REST API 設計
• 這裏所設計的空氣品質偵測器,將以 REST API ⽅方式提供 sensor
data。基本觀念:
• 需移植⼀一個 httpd ⾄至 LPC1768
• 需要製作⼀一個 frontend
• Frontend 以 data pull ⽅方式調⽤用空氣品質偵測器的 REST API
• 當 REST API 被調⽤用時,再即時讀取空氣指數,並以 JSON 格式返
回數據
• 這個設計當有幾個技術議題,後⾯面將會加強:
• Sensor device 應以 data push ⽅方式,即時推送 sensor data
77
79. 重要的資訊交換格式:
JSON
• 傳統 Backend 的做法,會提供 Client 端⼀一份 HTML5 的⽚片斷⽂文
件,⽽而不是格式化後的資料(Formatted),這是⼀一個缺點。
• 如果 Server 回傳的是格式化後的資料,Client 端就可以更有效
率地利⽤用這些資料。試想,如果 Google 傳回的搜尋結果是⼀一
堆 HTML5,那我們不就還要再去 Parse 這份⽂文件,才能取出真
正的結果,然後才能再次利⽤用這些資料(例如:再儲存為 CVS
格式)。
• 為了解決這個問題,必須要有⼀一個標準,不能⼤大家都⽤用⾃自已的
HTML5 ⽂文件,或是⾃自定的格式。軟體⼯工程師設計了⼀一些標準。
⼀一開始提出的做法,是制定標準的 XML 標籤,這樣⼤大家就可以
統⼀一⽂文件格式了。但是還有⼀一個問題,就是「資料量太⼤大」。
79
80. 傳統 XML 表⽰示
• 試想,Dust Sensor 要回傳⼆二筆資料,這⼆二筆資料都是低電
壓脈衝佔⽤用的時間:
• 0.12345
• 0.2468
• 然後⽤用XML來表⽰示,就變成:
80
<DustSensor>
<Item>0.12345</Item>
<Item>0.2468</Item>
</DustSensor>
82. Lightweight Web Server
• 匯⼊入 EthernetInterface Library,引⼊入
EthernetInterface.h 標頭檔,來設定網路組態
• 匯⼊入 HTTPD Library,引⼊入 HTTPD.h 標頭檔,來實
做 Http Web Server
82
83. #include "mbed.h"
#include "EthernetInterface.h"
#include "HTTPD.h"
EthernetInterface *eth;
HTTPD *httpd;
Serial pc(USBTX, USBRX);
InterruptIn probe(p8);
LocalFileSystem local("local");
DigitalOut led1(LED1), led2(LED2);
uint32_t low_time = 0;
void callback_api(int id) {
int i, n;
char low_time_buf[256];
char buf[256];
sprintf( low_time_buf, "%f", low_time / (30.0 * 1000000));
strcpy(buf, "{");
strcat(buf, "success: true,");
strcat(buf, "data: {");
strcat(buf, "lowpulseoccupancytime: ");
strcat(buf, low_time_buf);
strcat(buf, "}");
strcat(buf, "}");
httpd->send(id, buf, i, "Content-Type: text/plainrn");
}
撰寫程式碼
83
int main() {
pc.baud(115200);
pc.printf("Dust Sensor testrn");
probe.fall(&down);
ticker.attach(tick, 30);
printf("HTTP Server...rn");
eth = new EthernetInterface;
eth->init("192.168.21.81", "255.255.255.0",
"192.168.21.2" );
eth->connect();
printf("IP Address is %srn", eth->getIPAddress());
httpd = new HTTPD;
httpd->attach("/1/mbed/lpc1768/sensor/dust/
sen12291p", &callback_api);
httpd->attach("/", "/local/");
httpd->start(80);
printf("httpd readyrn");
led2 = 1;
}
86. Websocket
• WebSocket 是 HTML5 裡的⼀一個標準,它是⼀一種 TCP 的
連線技術。在協定部份,則是基於 HTTP(Over HTTP)
協定。因此,WebSocket 標準定義了⼀一些 HTTP Headers
來進⾏行 Client/Server 的通訊。
• Websocket 能讓 client 與 server 能建⽴立永續性的 TCP 連
線。簡單來說,有了 Websocket,就能實作出 real-time
data streaming 機制。
• 以下將說明 IoT 第 4 階段,也就是 WoT 最重要的⼀一個觀
念:使⽤用 Websocket channel server 來封裝 IoT objects,
讓 IoT devices 成為抽象化的 Websocket server
86
87. 關於 IoT 與 Websocket
• ⼀一般來說,Websocket 的使⽤用案例(use case)是 server
push(data push)機制,也就是說,ARM mbed 物件本
⾝身,應該是扮演 Websocket server 的⾓角⾊色。但現實層⾯面,
讓 IoT 扮演 Websocket server 的話,會有幾個技術問題:
• ARM mbed 要管理 client 端的 connections
• 需要更多的內存來維護 client connections
• 需要實作 Data push 的演算法,例如:round-robin
• 要考量 error handling 與 exception handling
87
88. Websocket 情境
• 最簡單的 scenario 設計如下:
• 佈署專⽤用的 Websocket channel server
• ARM mbed 將 data 即時推送(push)到 Websocket channel
server
• ⽤用⼾戶(user)與 Websocket channel server 建⽴立 Websocket
connection
• ⽤用⼾戶接收 Websocket channel server 的即時資料(經由 server
push)
• 抽象上來看,ARM mbed 仍然是 server 端,⽽而不是 client 端;真正的
client 端是⽤用⼾戶。
88
89. 認識 Websocket channel
service
• Websocket channel server 扮演封裝 IoT 物件的⾓角
⾊色,對 Websocket server 來說,只要能定義好
「channel」的結構,就能封裝數以萬計、千萬計的
IoT 物件。「抽象上來看,ARM mbed 仍然是 server
端」,就是這樣的觀念。
• ARM mbed 官⽅方就提供了 Websocket channel
server 的服務:
• http://sockets.mbed.org
89
90. ARM mbed 與 Websocket
Client
• 了解上述觀念後,技術的實作就能區隔為⼆二個部份:
• Websocket channel server 服務,後續範例將使
⽤用 sockets.mbed.org
• ARM mbed 的 Websocket client 實作
90
91. 使⽤用 Websocket Library ,引⼊入 Websocket.h 標頭檔後,建⽴立 Websocket 連線後傳送 "WebSocket Hello World over Ethernet" ⾄至
Websocket channel server 。
#include "mbed.h"
#include "EthernetInterface.h"
#include "Websocket.h"
int main() {
char recv[1024];
EthernetInterface eth;
//eth.init(); // Use DHCP
eth.init("192.168.21.33", "255.255.255.0", "192.168.21.2"); // Use static ip
eth.connect();
printf("IP Address is %snr", eth.getIPAddress());
Websocket ws("ws://sockets.mbed.org/ws/mbedschool/viewer");
ws.connect();
while (1) {
wait(1.0);
ws.send("WebSocket Hello World over Ethernet");
wait(1.0);
}
}
Data Push
ARM mbed 的 Websocket client 實作
91
93. Dust Sensor 與 WebSocket
Client
93
#include "mbed.h"
#include "EthernetInterface.h"
#include "Websocket.h"
EthernetInterface *eth;
InterruptIn probe(p8);
Timer timer;
Ticker ticker;
DigitalOut led1(LED1);
Websocket ws("ws://wot.city/object/dust/send");
uint32_t low_time = 0;
void down();
void up();
void tick()
{
char low_time_buf[256];
char buf[256];
sprintf( low_time_buf, "%f", low_time /
(30.0 * 1000000));
strcpy(buf, "{");
strcat(buf, ""lowpulseoccupancytime":");
strcat(buf, low_time_buf);
strcat(buf, "}");
ws.send(buf);
low_time = 0;
}
void down()
{
probe.rise(&up);
led1 = 0;
timer.start();
}
void up()
{
led1 = 1;
timer.stop();
probe.fall(&down);
low_time += timer.read_us();
timer.reset();
}
int main() {
probe.fall(&down);
ticker.attach(tick, 30);
eth = new EthernetInterface;
eth->init(); //DHCP
if (eth->connect()) return -1;
}
95. AutomationJS
• 前端使⽤用 Backbone.js 實做 Virtual DOM。
• 下圖為 Dust Sensor 及 Temperature Sensor 透過
Websocket 傳送 Sensor 數值到 Websocket
channel server ,再由 Frontend 接收 Websocket
channel server 的即時資料(經由 server push)
後,顯⽰示在網⾴頁上。
95
96. • Virtual DOM 讓下圖⼆二個 Sensor 資料呈現區塊都是獨⽴立
的,當其中⼀一個 Sensor 資料有變動時,只會更新單⼀一區
塊,⽽而不是更新整個畫⾯面。
96
99. section
.container(style='margin-top: 30px; margin-bottom: 80px;')
section.spot-box
.row.text-center
.col-md-3.text-right
.col-md-12#demo-spot
section
.container(style='width: 80%;')
.or-spacer
.mask
|
span
i 智慧家庭
section
.container(style='margin-top: 20px; margin-bottom: 80px;')
section.spot-box
.row.text-center#test-up
script(type='text/template', id='tmpl-dust')
.col-md-4
a.text-center.btn-mbed-spot-news
img.img-responsive(src!='/images/gallery/timeline-1.jpg')
.info
h2 空氣污染
h2 <%= lowpulseoccupancytime %>
script(type='text/template', id='tmpl-spot-news')
.col-md-3
a.text-center.btn-spot-news(href!='#', data-cid!='<%= cid %>')
img.img-responsive(src!='<%= img %>')
.info
h2 <%= city %> / <%= temp %>°C
AutomationJS
Jade(畫⾯面)
99
100. Model:從 API (api.openweathermap.org)取得北京溫度
app.BeijingNews = Backbone.Model.extend({
url: function() {
return 'http://api.openweathermap.org/data/2.5/weather?q=Beijing,cn' ;
},
defaults: {
success: false,
errors: [],
errfor: {},
city: '',
country: '',
img: '',
temp: 0
},
// AutomationJS plugins
parseJSON: function(response) {
// parse response
var f = Math.round((response.main.temp - 273.15) * 1.8 + 32)
, c = Math.round((response.main.temp - 273.15));
this.set('temp', c);
}
});
AutomationJS
Backbone-Model
100