2016年元旦當天,收到Arduino S.R.L公司(arduino.org)創辦人Federico Musto先生寄來的聖誕禮物:Arduino UNO WiFi控制板。
跟新的Arduino系列控制板一樣,UNO WiFi板的排插外側有印上接腳的編號(所以我們不用自己搞貼紙DIY了):
這張控制板的尺寸和UNO一樣,板子上整合了Arduino UNO和ESP8266(具備Wi-Fi網路連線的系統級晶片)。它採用ATmega328微控器執行Arduino程式,並且同樣採用ATmega16U2作為USB序列埠通訊晶片。廣告一下,ESP8266的說明和程式設計請參閱《超圖解物聯網IoT實作入門》第12和13章。
ESP8266晶片透過序列通訊介面連接其他微控器(如:Arduino板),但由於Arduino控制板的序列埠肩負接收程式碼的重責大任,因此,UNO WiFi板採用NXP(恩智浦半導體)的SC16IS750IBS序列轉I2C/SPI介面的晶片,把EP8266的序列介面轉換成I2C,再連接到Arduino的ATmega328微控器。
平時,Arduino UNO的網路資料經由I2C介面(亦即:A4和A5腳)傳送到SC16IS750IBS,再從這個晶片的序列埠,轉送給ESP8266晶片,反之亦然。
上傳程式給Arduino時,除了透過控制板的USB介面,也可以用Wi-Fi無線方式上傳。透過無線上傳程式時,程式檔將從ESP8266的序列埠直接傳入Arduino的序列埠。ESP8266的序列埠和I2C介面通訊會依照使用情況自動切換,我們的程式碼無須介入。
設置Wi-Fi網路和ESP8266的運作模式
Arduino Uno WiFi板子上的16M bit(2MB)快閃記憶體,用於儲存ESP8266的韌體,此網路晶片的預設工作模式為AP+STA,也就是同時充當網路基地台(Access Point)和無線終端設備(Station)。
若要啟用OTA(Over The Air,無線上傳程式碼)功能,ESP8266必須先設置成STA(無線終端)模式。Arduino UNO WiFi的無線網路參數,都是用瀏覽器設置。設置參數之前,要先透過Wi-Fi連接此控制板。
接上電源之後不久,即可探尋到此控制板的Wi-Fi訊號:
連上Arduino Uno WiFi基地台,再透過瀏覽器連接到http://192.168.240.1/網址,即可進入此控制板的無線網路設置畫面。
這個網頁程式存在EP8266韌體中,可顯示無線網路的運作狀況和資訊,例如,IP位址、MAC位址、工作模式…等等,也有提供一個相當於無線版「序列埠監測視窗」的WiFi Console(WiFi控制台)。
在WIFI設定畫面,設定讓無線網路連接到家裡的無線路由器之後,再按下右上角的SWITCH TO STA MODE(切換到連線終端模式),詳細的操作說明可參閱arduino.org網站的Getting started with Arduino UNO WiFi。
設定成STA模式,UNO WiFi板便失去無線基地台(AP)的能力,但仍具備網路連線功能。連接UNO WiFi板的電腦,必須和它連線到相同的無線網路環境。UNO WiFi板預設的主機名稱是“arduino”,透過“arduino.local”網址,即可開啟它的網路設定頁面:
http://arduino.local/
使用Arduino IDE 1.7.10版撰寫程式
Arduino UNO WiFi控制板是Arduino S.R.L公司的產品,請使用該公司的新版Arduino IDE(目前是1.7.10版)來編寫程式。Arduino S.R.L公司的Jeff告知,在今年五月舊金山Maker Faire會展中,該公司宣佈計劃未來會透過add-on platform packages(外掛平台套件)來支援arduino.cc的Arduino IDE,減少開發者使用Arduino IDE的困擾。
先在IDE主功能表的「工具→板子」選擇Arduino Uno WiFi板,再從「工具→序列埠」選擇有線序列埠(如下圖中的COM5),或者網路埠(如下圖中的arduino at 192.168.7.185)。
這項「網路埠」連線功能,可讓開發人員在遠端更新Arduino控制板的軟體。
Arduino UNO WiFi網路程式入門
以往,Arduino都是透過乙太網路或者Wi-Fi無線網路擴展板(像Arduino官網的這一款WiFi Shield)連接網際網路,這兩種方案都使用SPI介面與Arduino控制板相連。
Arduino UNO WiFi板的ESP8266晶片則是經由I2C連接Arduino微控器,加上每個網路晶片的控制方式都不一樣,所以UNO WiFi板的網路程式也不同於乙太網路程式;若不使用Wi-Fi網路功能,這塊板子的程式設計方式和普通的UNO相同。
在連接乙太網路模組的情況下,Arduino UNO板的數位10~13腳無法挪作他用;Arduino UNO WiFi則是犧牲了A4和A5兩個類比腳。
底下的程式將使用Arduino IDE內建的WebSever(網站伺服器)範例,說明UNO WiFi板的程式架構。上傳此程式碼之後,使用者將能透過底下的網址讀取UNO WiFi板的自製網站:
我們自訂的網路程式路徑,始終被附加在arduino.local/arduino/後面。底下是WiFi網站伺服器程式的架構,由於無線網路的IP、閘道器(gateway)位址…等參數,都是透過瀏覽器設置,所以我們的程式碼裡面不需要設定:
其中負責處理前端資料的WiFiData類型,定義在ArduinoWiFi程式庫資料夾裡的SC16IS750.h檔案中。每當有用戶連接此控制板時,process()自訂函式將讀取URL網址最後面的參數,其值若是“webserver”,則呼叫WebServer()自訂函式輸出網頁,若非“webserver”,ESP8266會自行在網頁上輸出“Not found.”(查無此資源)。
修改自Arduino IDE內建的WebSever(網站伺服器)範例的完整程式碼如下:
#include <Wire.h> #include <ArduinoWiFi.h> /* 開啟瀏覽器,輸入此網址: http://<IP>/arduino/webserver/ 或者 http://<hostname>.local/arduino/webserver/ 相關說明請參閱: http://labs.arduino.org/WebServer */ void setup() { Wifi.begin(); Wifi.println("WebServer Server is up"); // 輸出訊息到(網頁的)WiFi控制台 } void loop() { while (Wifi.available()) { process(Wifi); } delay(50); } void process(WifiData client) { // 讀取命令 String command = client.readStringUntil('/'); if (command == "webserver") { WebServer(client); } } void WebServer(WifiData client) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Refresh: 5"); // 每5秒自動更新(重新整理)網頁 client.println(); client.println("<html>"); client.println("<head> <meta charset=\"utf-8\"><title>UNO WIFI物聯網</title> </head>"); client.print("<body>"); for (int analogChannel = 0; analogChannel < 4; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("類比輸入 "); client.print(analogChannel); client.print(" 的值為 "); client.print(sensorReading); client.print("<br/>"); } client.print("</body>"); client.println("</html>"); client.print(DELIMITER); // 中斷與用戶的連線 }
乙太網路和WiFi擴展板程式,都是透過底下的語法中斷用戶端的連線:
client.stop();
UNO WiFi控制板則是透過這個敘述中斷連線,其中的DELIMITER常數也是定義在SC16IS750.h檔案裡面:
client.print(DELIMITER);
老師您好,我當初就是參閱您的MQTT教學(九):使用ESP8266上傳資料到ThingSpeak MQTT伺服器。
想請問一定要設置
const char* ssid = “你的Wi-Fi網路名稱”;
const char* password = “你的Wi-Fi網路密碼”;
const char* mqttServer = “mqtt.thingspeak.com”; // MQTT伺服器位址
const char* mqttUserName = “cubie”; // 使用者名稱,隨意設定。
const char* mqttPwd = “你的MQTT API Key”; // MQTT密碼
const char* clientID = “yard001”; // 用戶端ID,隨意設定。
上述這些東西才可以使用下面這兩行程式嗎?
WiFiClient espClient;
PubSubClient client(espClient);
因為ESP-13E設置網路的方式是用Web Server的方式去設置的,我不知道能不能直接使用
WiFiClient espClient;
PubSubClient client(espClient);
感恩老師
「因為ESP-13E設置網路的方式是用Web Server的方式去設置的…」不正確,「網路」是一種通訊工具或晶片,”Web Server”是一種應用軟體。你可以編寫各種通訊程式(如:HTTP, FTP, MQTT,…等),放到ESP-13E或其他ESP8266晶片上執行。
補充說明,ESP8266大致可分成兩種控制方式:
相關說明請參閱:
燒錄與執行ESP8266 AT指令韌體/固件(一):使用UNO+WiFi R3 ATmega328P+ESP8266控制板
燒錄與執行ESP8266 AT指令韌體/固件(二):連結與上傳資料到ThingSpeak網站
thanks,
jeffrey
老師您好,這是我嘗試寫的code。由於無線網路的IP、閘道器(gateway)位址…等參數,我都是透過瀏覽器設置,所以我的程式碼裡面沒有設定。上傳時卻出現
warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
的錯誤,能請您指點一下嗎?
這是我使用的板子Arduino UNO R3 ESP8266 Web Sever ESP-13E
萬分感恩
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
#define DHT11PIN 5 // DHT11資料接腳
const char* mqttServer = “xxxxxxxx”; // MQTT伺服器位址
const char* clientID = “xxxxx”; // 用戶端ID,隨意設定。
const char* topic = “xxxxx”;
unsigned long prevMillis = 0; // 暫存經過時間(毫秒)
const long interval = 20000; // 上傳資料的間隔時間,20秒。
String msgStr = “”; // 暫存MQTT訊息字串
int temp; // 暫存溫度
WiFiClient espClient;
PubSubClient client(espClient);
dht11 DHT11;
void reconnect() {
while (!client.connected()) {
if (client.connect(clientID)) {
Serial.println(“MQTT connected”);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(” try again in 5 seconds”);
delay(5000); // 等5秒之後再重試
}
}
}
void setup() {
Serial.begin(9600);
Wifi.begin()
client.setServer(mqttServer, 1883);
}
void loop() {
while (Wifi.available()) {
process(Wifi);
}
if (!client.connected()) {
reconnect();
}
client.loop();
// 等待20秒
if (millis() – prevMillis > interval) {
prevMillis = millis();
// 讀取DHT11的溫濕度資料
int chk = DHT11.read(DHT11PIN);
if (chk == 0) {
temp = DHT11.temperature;
}
// 組合MQTT訊息;field1填入溫度、field2填入濕度
msgStr = msgStr + “{\”temp\”:” + temp”}”;
// 宣告字元陣列
byte arrSize = msgStr.length() + 1;
char msg[arrSize];
Serial.print(“Publish message: “);
Serial.println(msgStr);
msgStr.toCharArray(msg, arrSize); // 把String字串轉換成字元陣列格式
client.publish(topic, msg); // 發布MQTT主題與訊息
msgStr = “”;
}
}
看來你不太了解我的意思,也不太熟悉你購買的東東。煩請聯繫廠商,他們應該可以提供範例檔讓你修改。
thanks,
jeffrey
老師您好,我透過USB方口連接線,連接電腦與Arduino Uno,提供電源以及電腦燒錄程式的端口後,在上面疊上擴充板(UNO R3 ESP8266 Web Sever ESP-13E)。我想參考 MQTT教學(九):使用ESP8266上傳資料到ThingSpeak MQTT伺服器,經由Wi-Fi網路和MQTT協定傳送DHT11的溫濕度值到我的mqtt broker上。由於我的擴充板是基於Web Server 配置WiFi 參數和串口參數,所以在程式碼裡面不需要設定這些參數。想請教若要完成我需要的功能我的開發板是要選擇Arduino Uno還是選擇Generic ESP8266 Module呢?
我為此苦惱了許久,希望老師能指點我。
Thanks
你的控制板是Uno,ESP8266是無線網路卡,
你的程式執行在Uno板,不能使用Wi-Fi程式庫,
而是要透過AT命令操控ESP8266聯網,
相關說明請參閱:
燒錄與執行ESP8266 AT指令韌體/固件(二):連結與上傳資料到ThingSpeak網站
thanks,
jeffrey
老師您好,商品說明寫說不須額外安裝軟體來下達複雜的AT指令,即可完成WiFi和串口的設定。所以當我基於Web Server 配置WiFi 參數和串口參數後,不是應該已經連上網了嗎?
因此我是否只需要使用AT指令連接並傳遞資料到我的MQTT Broker即可?
Thanks
這樣啊…拍謝,沒用過類似的擴展板,再麻煩洽詢廠商。
thanks,
jeffrey
老師您好,
關於arduino uno wi-fi Rev2 要連線OTA那段沒有說明得很清楚,
找了很多網路上的資訊也沒有說到底要如何用arduino uno wi-fi Rev2 開啟OTA模式,
只有看到 https://www.arduino.cc/en/Guide/ArduinoUnoWiFi#programming-via-ota這篇連接OTA的方式,
但好像不適用在arduino uno wi-fi Rev2 ,
能否請您解惑! 感謝您
Uno WiFi的技術文件不足,缺乏彈性,所以我很少使用,也沒用過Rev. 2版。
thanks,
jeffrey