Esp8266 nodemcu 使用PubSubClient连接阿里云物联网平台

之前写了一篇微信小程序使用MQTT.js连接阿里云IoT物联网平台,然后很多人问问题的时候顺带会问些硬件的问题,但是自己不会,没法回答。最近有些空闲的时间,自己也挺感兴趣,于是花了一个星期左右的时间看了c和c++入门,然后淘宝买了块esp8266 nodemcu开干,历经了许许多多的问题,终于是连接成功了。

开发环境

没有使用arduino官方的开发工具,因为太难用了,使用了vscode+platformio插件开发,很是方便,有代码提示还能看源码,非常推荐。具体的搭建就不多说了,网上很多教程,跟着来就行了。

开始编码

  1. 新建工程,点击最小角小房子,在弹出框中新建项目
    在这里插入图片描述
    板子选择的是esp-12e,应该都差不多,第一次新建项目比较慢,可以参考我的另一篇加速Visual Studio Code PlatformIo IDE 新建项目下载慢的解决办法

  2. 安装依赖库PubSubClient
    在这里插入图片描述
    点击libraries选项,输入PubSubClient搜索,第一个库就是,点进去
    在这里插入图片描述
    点击Add to Project 在弹出框中选择刚刚新建的项目等待安装完成即可
    在这里插入图片描述
    安装完成之后platformio.ini文件如下
    在这里插入图片描述

  3. 开始编码
    在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] = '\0';
  String message = String((char *)payload);
  Serial.println(message);
}

void loop()
{
  // put your main code here, to run repeatedly:
  if (client.connected())
  {
    client.loop(); //心跳以及消息回调等
  }
}

替换wifi信息以及对应的设备三元组和区域id,然后点击左下角右箭头上传代码即可
在这里插入图片描述
4. 验证
上传代码完成之后打开串口调试工具,如果信息正确,会看到如下
在这里插入图片描述
打开阿里云控制台,找打设备,切换到Topic列表,这里会显示订阅成功的主题
在这里插入图片描述
点击发布消息,输入hello word确认
在这里插入图片描述
查看串口输出
在这里插入图片描述
至此,esp8266连接阿里云物联网接收消息已完成。

PS:有一点需要特别注意的是PubSubClient库默认的KeepAlive为15s即心跳时间为15s,小于阿里云官方规定(30~1200s)的最小30s,所以如果不手动设置会被拒绝连接,导致连接不上服务器。

因为是基于arduino框架,所以上述代码也可以在arduino官方工具上使用,只需安装好PubSubClient库即可。

微信小程序连接请参考我的另一篇微信小程序使用MQTT.js连接阿里云IoT物联网平台

源码:https://gitee.com/megoc/esp8266_aliyun_iot

如果觉得有帮到你,可以左下角顺手点个赞支持一下。

### ESP8266 WiFi模块连接阿里云IoT平台使用教程 #### 准备工作 为了实现ESP8266 WiFi模块与阿里云IoT平台连接,需准备好以下材料和环境配置: - **硬件设备**: ESP8266开发板(如NodeMCU或Wemos D1 Mini)。 - **软件工具**: Arduino IDE用于编写程序[^2]。 - **网络设置**: 确保WiFi可用并已获取SSID和密码。 - **阿里云账户**: 注册阿里云账号,并创建产品及设备实例。 #### 创建阿里云IoT平台资源 登录阿里云控制台后,在物联网平台上完成如下操作: - 新建一个**产品**,定义其功能属性(例如上报数据类型),记录产品的ProductKey。 - 添加具体**设备**至该产品下,获得DeviceName以及对应密钥DeviceSecret。这些参数将在后续通信过程中起到身份验证作用[^3]。 #### 配置开发环境 下载安装最新版Arduino IDE,并通过Preferences->Additional Boards Manager URLs添加支持ESP8266芯片系列扩展包地址http://arduino.esp8266.com/stable/package_esp8266com_index.json 。之后打开Boards Manager搜索关键字"esp8266", 安装由ESP8266 Community维护的相关固件版本。 #### 编程实现联网过程 以下是基于Arduino框架下的核心代码片段展示: ```cpp #include <PubSubClient.h> #include <ESP8266WiFi.h> // 替换为实际Wi-Fi名称和密码 const char* ssid = "your_wifi_ssid"; const char* password = "your_wifi_password"; // MQTT服务器信息 #define IOT_ID "i91j8i57ZEu" #define IOT_SECRET "your_device_secret" #define PRODUCT_KEY "a1ZwKsOXXXX" unsigned long timestamp; char mqtt_client_id[128]; char sign[33]; void setup_wifi() { delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } randomSeed(micros()); Serial.println(""); Serial.println("WiFi connected"); } String getSignMethod(String productKey,String deviceName,String deviceSecret,unsigned long time){ String strToSign="deviceName"+deviceName+"productKey"+productKey+"timestamp"+String(time); unsigned char hash[32]; HMAC_SHA256((uint8_t*)strToSign.c_str(), strToSign.length(), (uint8_t*)deviceSecret.c_str(), strlen(deviceSecret),hash,sizeof(hash)); return bytesToHex(hash); } void buildMqttClientId(char *mqttId,char *signValue,unsigned long tStamp){ snprintf(mqttId,strlen(PRODUCT_KEY)+strlen(IOT_ID)+40,"%s.%s|securemode=2,signmethod=hmacsha256,timestamp=%lu|", PRODUCT_KEY,IOT_ID,tStamp); strcat(mqttId,",username="); strcat(mqttId,IOT_ID); strcat(mqttId,",password="); strcat(mqttId,signValue); } void setup() { Serial.begin(115200); setup_wifi(); // 获取当前时间戳 timestamp = millis()/1000; // 计算签名字符串 strcpy(sign,getSignMethod(PRODUCT_KEY,IOT_ID,IOT_SECRET,timestamp).c_str()); // 构造客户端ID buildMqttClientId(mqtt_client_id,sign,timestamp); client.setServer(PRODUCT_KEY".iot-as-mqtt.cn-shanghai.aliyuncs.com", 1883); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); } ``` 上述代码实现了基本的功能需求,包括但不限于建立无线局域网连接、计算HMAC-SHA256加密后的认证令牌、构建符合规范要求的主题订阅/发布路径等逻辑处理流程。 #### 测试验证效果 上传编译好的sketch文件到目标单片机上运行测试,观察串口监视器输出日志确认状态变化情况;同时返回查看云端接收消息队列是否存在预期格式的数据推送记录即可判断整个链路是否搭建成功[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值