由於蛋疼的緣故, 接觸了一下MQTT, 從一個大佬那裏據說了塗鴉這個牛逼平臺, 可是我正玩阿里的IoT呢, 就拿進行了一半的阿里IoT練練手吧.前端
目標是一句話: 用手機控制一個ESP8266的模塊上面的一個燈.node
這裏面涉及幾個問題:git
1. ESP8266固件編程
2. App如何訪問雲端? 直接MQTT?json
3. 小機端怎麼鏈接阿里的IoT? 這個問題是問題1的延續.windows
挨個來講, 個人模塊是某寶買的, (感受被坑了, 20塊錢).api
https://detail.tmall.com/item.htm?id=524942473974&spm=a1z09.2.0.0.459e2e8dI58meT&_u=b124ig73098服務器
排線竟然焊歪了.根據這個賣家的資料, 看得我一頭霧水, 一是所謂官方網站, 也就是這個http://www.nodemcu.com 啥雞毛都沒有, 幾年前我玩這個8266的時候, 依稀記得貌似用的是lua, 可是這個網站沒有提到lua, 反而說能夠像arduino同樣編程, 我有點兒糊塗了就.app
先是找了一個早就沒有人用的nodemcu studio 2015, 看名字就知道夠老了. 折騰了一番, 終於把init.lua刷進去了, 基本能連到我家的wifi上去.ide
後來一個偶然的機會據說了塗鴉, 進去一看文檔, 哎喲, 都是用的esp8266, 這樣我又從他們官網頂了兩個模塊, 後來發現徹底不必.
而後回到阿里這邊折騰, 發現了開發文檔裏面說到了, 這裏要先吐槽一下塗鴉的文檔, 壓根沒有寫任何有意義的關於mcu開發的例程, 甚至連固件的編譯都隻字不提, 且不提怎麼寫代碼, 我他媽怎把東西刷進去我都不知道, 搞毛線.
我後來記得貌似阿里的文檔中, 提到了8266的一個快速應用案例, 一看哎呦, 還有源碼, 再一看, 竟然是arduino的, 這麼說, esp8266真的如nodemcu.com網站上所說, 能夠看成arduino來編程?
後來google了一番, 誠不我欺也, ESP8266上真的能夠跑arduino, 連引腳都靠譜.
過程是, 先下一個adruino的ide, for windows版本.
記得前面根據倒黴賣家提供的資料百度盤, 下載安裝一下板子的usb驅動, cp2102, 我買的是廉價的cp2102的版本.
裝好以後, 去arduino的首選項裏面, 加上開發板的管理器地址, 就是一個repo源
https://www.arduino.cn/package_esp8266com_index.json
再在arduino的開發板管理器裏面, 下載NodeMCU 1.0的開發板
接着是兩個庫, 由於阿里的源碼裏面要引用這兩個庫: PubSubClient ArduinoJson
直接進庫管理裏面搜就好了. 注意版本最好跟阿里源碼裏面的版本一致.
#include <ESP8266WiFi.h> /* 依賴 PubSubClient 2.4.0 */ #include <PubSubClient.h> /* 依賴 ArduinoJson 5.13.4 */ #include <ArduinoJson.h> #define SENSOR_PIN 13 /* 鏈接您的WIFI SSID和密碼 */ #define WIFI_SSID "xxid" #define WIFI_PASSWD "password" /* 設備證書信息*/ #define PRODUCT_KEY "a1mBLX1dkbZ" #define DEVICE_NAME "tXQxE2VcYyZrYHubvw2h" #define DEVICE_SECRET "pGL6jQLhjlbQ24x0HbfMsNYp9y9Xe0" #define REGION_ID "cn-shanghai" /* 線上環境域名和端口號,不須要改 */ #define MQTT_SERVER "a1mBLX1dkbZ.iot-as-mqtt.cn-shanghai.aliyuncs.com" #define MQTT_PORT 1883 #define MQTT_USRNAME "tXQxE2VcYyZrYbvw2h&a1mBLX1dkbZ" #define CLIENT_ID "12345|securemode=3,signmethod=hmacsha1|" // 請使用以上說明中的加密工具或參見MQTT-TCP鏈接通訊文檔加密生成password。 // 加密明文是參數和對應的值(clientIdesp8266deviceName${deviceName}productKey${productKey}timestamp1234567890)按字典順序拼接 // 密鑰是設備的DeviceSecret #define MQTT_PASSWD "FCA9741899490E99BE661F504AFBA71099A0C520" #define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}" #define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post" #define ALINK_TOPIC_PROP_SET "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/set" unsigned long lastMs = 0; WiFiClient espClient; PubSubClient client(espClient); void callback(char *topic, byte *payload, unsigned int length) { StaticJsonBuffer<200> jsonBuffer; Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); payload[length] = '\0'; Serial.println((char *)payload); JsonObject& root = jsonBuffer.parseObject(payload); if (!root.success()) { Serial.println("parseObject() failed"); return; } const char* status = root["params"]["LightSwitch"]; Serial.println(status); if(status[0] == '0'){ //Serial.println("off"); digitalWrite(LED_BUILTIN, HIGH); }else{ //Serial.println("on"); digitalWrite(LED_BUILTIN, LOW); } } void wifiInit() { WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWD); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("WiFi not Connect"); } Serial.println("Connected to AP"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.print("espClient ["); client.setServer(MQTT_SERVER, MQTT_PORT); /* 鏈接WiFi以後,鏈接MQTT服務器 */ client.setCallback(callback); } void mqttCheckConnect() { while (!client.connected()) { Serial.println("Connecting to MQTT Server ..."); if (client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD)) { Serial.println("MQTT Connected!"); client.subscribe(ALINK_TOPIC_PROP_SET); } else { Serial.print("MQTT Connect err:"); Serial.println(client.state()); delay(5000); } } } void mqttIntervalPost() { char param[32]; char jsonBuf[128]; //sprintf(param, "{\"idle\":%d}", digitalRead(13)); //sprintf(jsonBuf, ALINK_BODY_FORMAT, param); Serial.println(jsonBuf); boolean d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf); Serial.print("publish:0 失敗;1成功"); Serial.println(d); } void setup() { pinMode(SENSOR_PIN, INPUT); /* initialize serial for debugging */ Serial.begin(115200); Serial.println("Demo Start"); pinMode(LED_BUILTIN, OUTPUT); wifiInit(); } // the loop function runs over and over again forever void loop() { if (millis() - lastMs >= 5000) { lastMs = millis(); mqttCheckConnect(); } client.loop(); }
編譯一下, 發現還行, 能連上MQTT的服務器.
而後就在阿里的控制檯, 建一個服務, 這裏很奇怪, 我發現了兩個IoT控制檯, 彷佛一個新一箇舊, 總之相互之間數據仍是不通的, 我大概是用舊的控制檯建了一個服務, 所謂服務就是把前端api, 好比app那邊的請求, 向設備端的topic進行了一個發佈publish, 若是你的設備正好訂閱了這個topic, 就會執行回調, 就是上面arduino固件裏面callback函數裏面執行的那樣,
畫圖通常作了一個服務出來.
Api輸入爲一個接口地址, 好比/switch, 而後傳參數進去, 後來就被這個傳參給攔住了, 把心一橫,直接幹一個app出來.
阿里估計是學塗鴉的, 或者塗鴉學阿里, 誰知道去了, 反正都是一個路子(不過感受塗鴉落地的項目更多, 界面都有不少模板選擇.), 配置好頁面, 直接出sdk
基本過程是傻瓜式的:
IoT的網頁就應該是傻瓜式的嘛, 可複製, 可複用, 有伸縮, 有彈性.
沒別的就作了一個開關, 而後這個開關能夠配置:
點幾下鼠標, 搞定了.
而後下載安裝到安卓上, 完成.
最終效果很簡單, 即便按屏幕上的按鈕, 燈能夠亮或者滅.
這就是IoT了...我滴天哪...
下一步是pwm...哈哈哈