IoT改變世界之 Arduino+ESP8266+阿里MQTT+App控制


因為蛋疼的緣故, 接觸了一下MQTT, 從一個大佬那里聽說了塗鴉這個牛逼平台, 但是我正玩阿里的IoT呢, 就拿進行了一半的阿里IoT練練手吧.

目標是一句話: 用手機控制一個ESP8266的模塊上面的一個燈.

這里面涉及幾個問題:

1. ESP8266固件

2. App如何訪問雲端? 直接MQTT?

3. 小機端怎么連接阿里的IoT? 這個問題是問題1的延續.

挨個來說, 我的模塊是某寶買的, (感覺被坑了, 20塊錢).

https://detail.tmall.com/item.htm?id=524942473974&spm=a1z09.2.0.0.459e2e8dI58meT&_u=b124ig73098

排線居然焊歪了.根據這個賣家的資料, 看得我一頭霧水, 一是所謂官方網站, 也就是這個http://www.nodemcu.com 啥雞毛都沒有, 幾年前我玩這個8266的時候, 依稀記得貌似用的是lua, 但是這個網站沒有提到lua, 反而說可以像arduino一樣編程, 我有點兒糊塗了就.

先是找了一個早就沒有人用的nodemcu studio 2015, 看名字就知道夠老了. 折騰了一番, 終於把init.lua刷進去了, 基本能連到我家的wifi上去.

后來一個偶然的機會聽說了塗鴉, 進去一看文檔, 哎喲, 都是用的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...哈哈哈

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM