《ESP8266 學習筆記》 之 將ESP8266連接到 阿里雲,實現簡單的點燈測試,並創建網頁控制端

目錄

簡介:

需要的庫:

驗證代碼:

效果演示:


簡介:

在使用阿里雲物聯網之前,我已經使用過了機智雲的物聯網功能,並且調通了(STM32+ESP8266)AT指令方式和(獨立ESP8266)SDK開發方式 ,並且已經可以正常的上報和下發信息,可以完成智能配網。

之後,便想去試試國內的大佬——阿里雲,但阿里雲的物聯網保密性很強,需要對每個設備進行預註冊,且在程序中還要加入三元數 ,並將三元數 轉換爲 哈希值 ,以加強保密措施,但不能每個設備我們都去計算 哈希值 吧!,於是,便引入另一個Arduino庫——Crypto,此庫可以將三元數在程序中直接轉換爲 SHA256 值,是不是方便了很多,哈哈哈!

需要的庫:

AliyunMqttArduino: https://github.com/legenddcr/aliyun-mqtt-arduino

ArduinoJson V5版本:https://github.com/bblanchon/ArduinoJson.git

U8g2 :https://github.com/olikraus/U8g2_Arduino

Cryptohttps://github.com/rweather/arduinolibs

PubSubClienthttps://github.com/knolleary/pubsubclient

注:

請將這些庫下載好放進你的Arduino的庫目錄中,然後修改 PubSubClient 庫文件中的 PubSubClient.h 文件的 第26行 的緩存大小由:

#define MQTT_MAX_PACKET_SIZE 128

改爲:

#define MQTT_MAX_PACKET_SIZE 1024

原因是阿里雲的MQTT數據包有點大,128不夠,所以修改大一些,防止緩存空間不夠用~

驗證代碼:

/*
*功能:ESP8266連接阿里雲服務,並簡單的點個燈!
*作者:劉澤文
*時間:2020/4/10
*/

#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <aliyun_mqtt.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <SHA256.h>

//定義OLED型號
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

//定義DHT11引腳和型號,暫時沒用到!
//#define DHT11_PIN 12

//定義LED燈
#define LED0 D4

//初始化次態
int redLedState0 = 0;

//初始化現態
int last0 = 0;

//上雲時間現態
unsigned long lastSend = 0;
unsigned long back_time = 0;
unsigned long BACK_TIME = 1*100;

//你的wifi
#define WIFI_SSID "***********"
#define WIFI_PASSWD "************"

//阿里雲三元組
#define PRODUCT_KEY "***********"
#define DEVICE_NAME "MYLED"
#define DEVICE_SECRET "*************"

//Alink JSON所需
#define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
//屬性上報Topic---發佈
#define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
//屬性設置Topic---訂閱
#define ALINK_TOPIC_PROP_SET "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"

#define ALINK_METHOD_PROP_POST "thing.event.property.post"

//創建WiFiClient實例
WiFiClient espClient;

//創建MqttClient實例
PubSubClient mqttClient(espClient);


//連接Wifi
void initWifi(const char *ssid, const char *password)
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("WiFi does not connect, try again ...");
    delay(1000);
  }

  Serial.println("Wifi is connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


//連接Mqtt並訂閱屬性設置Topic
void mqttCheckConnect()
{
    bool connected = connectAliyunMQTT(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET);

    if (connected)
    {
        Serial.println("MQTT connect succeed!");

        //訂閱屬性設置Topic
        mqttClient.subscribe(ALINK_TOPIC_PROP_SET); 
        Serial.println("subscribe done");
    }
}


// 上報屬性Topic數據
void mqttIntervalPost() 
{
    char param[256];
    char jsonBuf[512];
   
    sprintf(param, "{\"S_D0\":%d}", !digitalRead(LED0));
    sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
    //jsonBuf = "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":"\{\"S_D0\":%d}\"}"

    Serial.println(jsonBuf);

    mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf); 
}


//監聽雲端下發指令並處理 
void callback(char *topic, byte *payload, unsigned int length)
{
     
    Serial.println();
    Serial.println();
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    Serial.println();
    //雲端下發屬性設置topic = "[/sys/你的密鑰/你的設備密碼/thing/service/property/set]"

    payload[length] = '\0';
    Serial.println((char *)payload);
    //payload = "{"method":"thing.service.property.set","id":"282860794","params":{"S_D0":1},"version":"1.0.0"}"


  if (strstr(topic, ALINK_TOPIC_PROP_SET))
    {
        //json解析payload
        StaticJsonBuffer<400> jsonBuffer;
        JsonObject &root = jsonBuffer.parseObject(payload);

        //判斷json解析是否成功
        if (!root.success())
        {   
            Serial.println("parseObject() failed");
        } 
        else
        {
            Serial.println("parseObject() success");

            //redLedState0  = json解析後的"S_D0"的值
            redLedState0 = root["params"]["S_D0"];

            Serial.print(redLedState0);
            Serial.println(" set  sucess");
            Serial.println();
     
            Serial.print("LED0 State: ");
            Serial.println(redLedState0);

            digitalWrite(LED0, !redLedState0);

        }
    }
}

void u8g2_faution()
{
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_wqy16_t_gb2312);
    u8g2.setCursor(0, 16);
    u8g2.print("   阿里雲測試   ");//一行共8個漢字
    u8g2.setCursor(10, 55);
    u8g2.print("燈1狀態:");
    u8g2.setFont(u8g2_font_open_iconic_all_4x_t);
    if(!digitalRead(LED0))
      u8g2.drawGlyph(85,64,120);//開燈
    else
      u8g2.drawGlyph(85,64,121);//關燈
    u8g2.sendBuffer();
}

void setup() 
{
    Serial.begin(9600);

    u8g2.begin();
    u8g2.enableUTF8Print();
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_wqy16_t_gb2312);
    u8g2.setCursor(40, 40);
    u8g2.print("阿里雲");
    u8g2.sendBuffer();

    pinMode(LED0, OUTPUT); 
    digitalWrite(LED0, HIGH); /*LOW*/

    initWifi(WIFI_SSID, WIFI_PASSWD); 

    Serial.println();
    Serial.println();

    mqttCheckConnect(); //初始化首次鏈接
    mqttIntervalPost(); //上報初始化數據

    Serial.println();
    mqttClient.setCallback(callback); // 回調,監聽雲端下發指令,當ESP8266收到訂閱Topic後調用callback函數

    back_time = millis();
}


void loop()
{
    if(millis()-back_time >= BACK_TIME){
      back_time = millis();
      u8g2_faution();
    }
    //每隔1s嘗試連接一次雲
    if (millis() - lastSend >= 50000)
    {
        mqttCheckConnect(); 
        lastSend = millis();
    }

    //判斷燈現態與次態的關係,減少無意義的上報  
    if (last0 != redLedState0)
    {
        last0 = redLedState0;
        
        mqttIntervalPost(); 
        Serial.println();
    }

    mqttClient.loop();
}

在使用代碼時,請注意修改WIFI賬號和三元數信息!

效果演示:

在阿里雲的IOT Studio 添加Web產品,添加按鈕控件,並將其數據源配置爲你的點燈產品:

 上傳程序:

點擊開關,即可看到開發板:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章