目录
简介:
需要的库:
验证代码:
效果演示:
在使用阿里云物联网之前,我已经使用过了机智云的物联网功能,并且调通了(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
Crypto:https://github.com/rweather/arduinolibs
PubSubClient:https://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
#include
#include
#include
#include
#include
//定义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产品,添加按钮控件,并将其数据源配置为你的点灯产品:
上传程序:
点击开关,即可看到开发板: