概述
之前写了一篇微信小程序使用MQTT.js连接阿里云IoT物联网平台,然后很多人问问题的时候顺带会问些硬件的问题,但是自己不会,没法回答。最近有些空闲的时间,自己也挺感兴趣,于是花了一个星期左右的时间看了c和c++入门,然后淘宝买了块esp8266 nodemcu开干,历经了许许多多的问题,终于是连接成功了。
开发环境
没有使用arduino官方的开发工具,因为太难用了,使用了vscode+platformio插件开发,很是方便,有代码提示还能看源码,非常推荐。具体的搭建就不多说了,网上很多教程,跟着来就行了。
开始编码
-
新建工程,点击最小角小房子,在弹出框中新建项目
板子选择的是esp-12e,应该都差不多,第一次新建项目比较慢,可以参考我的另一篇加速Visual Studio Code PlatformIo IDE 新建项目下载慢的解决办法 -
安装依赖库PubSubClient
点击libraries选项,输入PubSubClient搜索,第一个库就是,点进去
点击Add to Project 在弹出框中选择刚刚新建的项目等待安装完成即可
安装完成之后platformio.ini文件如下
-
开始编码
在main.cpp中编写如下代码
#include <Arduino.h>
#include <Crypto.h>
#include <ESP8266WiFiMulti.h>
#include <PubSubClient.h>
using experimental::crypto::SHA256;
// 实例化一个对象 wifiMulti
ESP8266WiFiMulti wifiMulti;
WiFiClient espClient;
PubSubClient client(espClient);
void connetMqtt();
String signHmacSha256(String deviceId, String productKey, String deviceName, String deviceSecret, uint64_t timestamp);
void callback(char *topic, byte *payload, unsigned int length);
const String productKey = "***";
//替换
const String deviceName = "***";
//替换
const String deviceSecret = "***"; //替换
const String subTopic = "/" + productKey + "/" + deviceName + "/user/get";
const String pubTopic = "/" + productKey + "/" + deviceName + "/user/update";
const String regionId = "cn-shanghai"; //替换自己的区域id
const String serverUrl = productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com";
const int serverPort = 1883;
const char wifiName[] = "***";//替换
const char wifiPassword[] = "***";//替换
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
wifiMulti.addAP(wifiName, wifiPassword);
Serial.println("");
Serial.println("start connecting wifi...");
while (wifiMulti.run() != WL_CONNECTED)
{
Serial.print(".");
delay(1000);
}
Serial.println("============connect wifi success============");
Serial.print("WiFi:");
Serial.println(WiFi.SSID());
Serial.print("localIP:");
Serial.println(WiFi.localIP());
connetMqtt();
}
void connetMqtt()
{
Serial.println("start connect mqtt ....");
client.setKeepAlive(60); //注意:PubSubClient库的默认keepalive是15s,而官方要求(30~1200s)最小30s,否则会拒绝连接
client.setServer(serverUrl.c_str(), serverPort);
String deviceId = String(ESP.getChipId()); //设备芯片唯一序列号
uint64_t timestamp = micros64();
String clientId = deviceId + "|securemode=3,signmethod=hmacsha256,timestamp=" + timestamp + "|";
String password = signHmacSha256(deviceId, productKey, deviceName, deviceSecret, timestamp);
String username = deviceName + "&" + productKey;
Serial.print("clientId:");
Serial.println(clientId);
Serial.print("username:");
Serial.println(username);
Serial.print("password:");
Serial.println(password);
client.connect(clientId.c_str(), username.c_str(), password.c_str());
while (!client.connected())
{
/* code */
delay(2000);
client.connect(clientId.c_str(), username.c_str(), password.c_str());
Serial.println("try connect mqtt...");
}
Serial.println("ok, mqtt connected!");
client.subscribe(subTopic.c_str());
client.setCallback(callback);
}
String signHmacSha256(String deviceId, String productKey, String deviceName, String deviceSecret, uint64_t timestamp)
{
const char *key = deviceSecret.c_str();
String data = "clientId" + deviceId + "deviceName" + deviceName + "productKey" + productKey + "timestamp" + timestamp;
Serial.print("sha256:");
Serial.println(data);
return SHA256::hmac(data, key, strlen(key), SHA256::NATURAL_LENGTH);
}
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
payload[length] = '