這一篇玩玩Bridge程式庫裡的BridgeServer(舊稱YunServer)與BridgeClient(舊稱YunClient)這兩個類別,程式碼主要都來自於Arduino官方範例草稿碼Bridge。
我的Yún與開發主機位於同一個區域網路內,我的Arduino軟體開發環境是1.6.7版。首先從瀏覽器登入Yún,開啟REST API存取權限為OPEN。
#include <Bridge.h>
#include <BridgeServer.h>
#include <BridgeClient.h>
// Yún的網站伺服器,會把所有HTTP請求(/arduino)轉送給BridgeServer
BridgeServer server; // 預設會聆聽連接埠5555
void setup() {
Serial.begin(57600);
while(!Serial && millis() < 9000){
}
Serial.print("Starting Bridge...");
Bridge.begin();
Serial.println("done.");
// 只接受從localhost來的連線
server.listenOnLocalhost();
server.begin();
}
void loop() {
// 不斷呼叫accept,檢查是否有連線
BridgeClient client = server.accept();
// 若client有值,代表有連線
if(client){
process(client); // 處理請求
client.stop(); // 關閉連線,也會釋放掉相關資源
}
delay(50); // 暫停50毫秒
}
void process(BridgeClient client) {
// 讀取URL網址
String command = client.readStringUntil('/');
// 判斷,做該做的事情
if(command == "digital"){
digitalCommand(client);
}
else if(command == "analog"){
analogCommand(client);
}
else if(command == "mode"){
modeCommand(client);
}
}
void digitalCommand(BridgeClient client){
int pin, value;
pin = client.parseInt(); // 哪個腳位
if(client.read() == '/'){ // 若下個字元是'/'
// 代表這個URL應會類似於"/digital/13/1",要寫入
value = client.parseInt();
digitalWrite(pin, value);
}
else{ // 若不是,則是讀取
value = digitalRead(pin);
}
// 回送回應給瀏覽器
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to "));
client.println(value);
// 把腳位狀態儲存在內部的鍵值配對空間
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
void analogCommand(BridgeClient client) {
int pin, value;
pin = client.parseInt();
if(client.read() == '/'){
value = client.parseInt();
analogWrite(pin, value);
client.print(F("Pin D"));
client.print(pin);
client.print(F(" set to analog "));
client.println(value);
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
else{
value = analogRead(pin);
client.print(F("Pin A"));
client.print(pin);
client.print(F(" reads analog "));
client.println(value);
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
void modeCommand(BridgeClient client) {
int pin = client.parseInt();
// 下個字元必須是'/'
if (client.read() != '/') {
client.println(F("error"));
return;
}
String mode = client.readStringUntil('\r');
if(mode == "input"){
pinMode(pin, INPUT);
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as INPUT!"));
}
else if(mode == "output"){
pinMode(pin, OUTPUT);
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configured as OUTPUT!"));
}
else{
client.print(F("error: invalid mode "));
client.print(mode);
}
}
然後從別台電腦的瀏覽器,輸入類似底下的網址,請把arduino.local換成你的Yún的IP位址。當Yun看到網址「/arduino」時,不會做什麼處理,都會轉交給草稿碼(ATmega32U4)。
把腳位13設為輸出模式:
http://arduino.local/arduino/mode/13/output
瀏覽器上會看到回應:
Pin D13 configured as OUTPUT!
把腳位13設為高電位,其連接的LED會亮起:
http://arduino.loca/arduino/digital/13/1
瀏覽器上會看到回應:
Pin D13 set to 1
把腳位13設為低電位,其連接的LED會熄滅:
http://arduino.loca/arduino/digital/13/0
瀏覽器上會看到回應:
Pin D13 set to 0
腳位3輸出PWM128:
http://arduino.loca/arduino/analog/3/128
瀏覽器上會看到回應:
Pin D3 set to analog 128
讀取類比腳位A0(對應腳位編號18)的值:
http://arduino.loca/arduino/analog/18
瀏覽器上類似底下的回應:
Pin A18 reads analog 253
參考資料:
- Arduino官方文件,Guide to the Arduino Yún、BridgeServer類別與BridgeClient類別。
大大 您好!
ReplyDelete想像您請教問題
在下目前想要開發一個使用WI-FI控制和通訊的自走車(使用PC和Android)
目前遇到的問題是不知道要怎麼選控制板
使用Arduino YUN有內建WI-FI,但GPIO不夠用,可能要使用74HC595之類的來擴充
或是使用Arduino MEGA2560 的GPIO數量足夠,可是要再擴充WI-FI
想請問大大建議要用種哪種方式來開發較為容易?謝謝
沒有建議,根據你的需求自行選擇,各有好壞。
Delete或可根據你最看重的核心功能,假設是wi-fi連網,
然後選你最熟悉的wi-fi技術,例如yun。
接著再想辦法擴充腳位。能夠擴充腳位的IC,不只595,例如I2C介面的MCP23017。
另外可想辦法縮減所需腳位的數量,
如果連接一大堆LED,是否可採用更進階的LED模組,僅用幾個腳位、便可控制一大堆LED。
感謝大大的幫忙
ReplyDelete因為核心控制部份是WI-FI,而目前物連網資旋應該是YUN較多吧?
在下需要控制的IO約25~27個,其實也只比YUN的多一些
> 應該是YUN較多吧?
Delete不一定。
Yun滿貴的。
wi-fi有很多其他選擇,esp8266、linkit 7688、等。
感謝大大的建議!
ReplyDelete目前決定先用MEGA 2560 + MEGA SENSOR SHIELD + YUN SHIELD(或其他WIFI模組)
配合參考大大的書來做測試(這樣WIFI的部份如果不適合,就可以再做更換)
不好意思請問一下
ReplyDelete用另一個電腦去控制也要和YUN在同一個區域網路內在可以控制嘛??
麻煩了
能連得到就可控制。
Delete不在同一區域網路的話,要設定路由器。
大大您好!
ReplyDelete如果我想要讓兩個yun互傳訊號
請問可以用什麼方式嗎?
謝謝
紅外線、藍牙、wifi、I2C、SPI、序列介面、XBee、...
Delete