编程语言
首页 > 编程语言> > 关于ESP8266-NodeMCU和onenet通信传输学习总结

关于ESP8266-NodeMCU和onenet通信传输学习总结

作者:互联网

关于ESP8266-NodeMCU和onenet通信传输学习总结(一)

1.ESP8266-NodeMCU简介:

​ ESP8266-NodeMCU是一个开源硬件开发板,由于它支持WIFI功能,所以在物联网(IOT)领域,Arduino开发板最大的对手之一就是ESP8266-NodeMCU开发板。ESP8266-NodeMCU尺寸与Nano类似, 他并不是Arduino团队开发的,但是我们也可以使用Arduino IDE 对他进行开发。而且他还有一颗地道的“中国芯”—ESP8266模块

ESP8266-NodeMCU开发板

(这里我要感谢太极创客团队对这块开发板的教学制作,对很多新手玩家很友好);

开发板引脚:

开发板引脚资料

更多关于开发板资料可以到太极创客官网进行了解学习

http://www.taichi-maker.com/homepage/reference-index/arduino-hardware-refrence/nodemcu/

2.onenet物联网平台

该平台为广大物联网产品开发提供了免费的服务器进行数据存储和传输,更多详情可以到其官网进行了解,这里不累述。

对于新入门用户可能对其如何使用有很大疑惑,在半知半解的学习中,这里提供其中一种使用方法,通过mqtt协议建立使用:

第一步注册onenet账户:

在这里插入图片描述

第二步,进入控制台:

在这里插入图片描述

选择多协议接入:

在这里插入图片描述

这里选择mqtt旧版,创建产品,内容任意:

在这里插入图片描述

重点看下技术参数,按照自己的网络方式进行选择,可以参考如下方式:

在这里插入图片描述

然后生成产品后进入创建设备:

在这里插入图片描述

这里着重注意要留好设备ID,产品ID和你的Master-APIkey,该信息将作为esp8266连入onenet的设备ID,用户名和密码,创建完成后可以创建数据流,方式任意,记得数据流名字就ok了,到此onenet上的准备工作完成。

3.ESP8266-NodeMCU客户端设备开发

话不多说,先上代码:

/**
 * author: topthemaster
 * time: 2021.1.6
 * 
 */
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
#include <ArduinoJson.h>
#define PRODUCT_ID    "396066" //产品名
#define API_KEY    "tx6WM==zmW21Z2pt4susBRlHMuY="//产品密钥
#define DEVICE_ID "666259032"//设备名
#define TOPIC     "ceshitopic1"//订阅主题
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
const char* ssid = "Fishing WiFi ";
const char* password = "zheshiyigewifi";
const char* mqttServer = "183.230.40.39";//onenet地址
const uint16_t mqttPort = 6002;//mqtt接口端口
Ticker ticker;
int count;  
char msgJson[75];
char msg_buf[200];
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // 设置板上LED引脚为输出模式
  digitalWrite(LED_BUILTIN, HIGH);  // 启动后关闭板上LED
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  connectWifi();
  mqttClient.setServer(mqttServer,mqttPort);
  // 设置MQTT订阅回调函数
  mqttClient.setCallback(receiveCallback);
  connectMQTTServer();
  ticker.attach(1, tickerCount);  
}

void loop() {
  if (mqttClient.connected()) { // 如果开发板成功连接服务器
    // 每隔3秒钟发布一次信息  
    // 保持心跳
    if (count >= 3){
      pubMQTTmsg();
      count = 0;
    }  
    mqttClient.loop();
  } else {                  // 如果开发板未能成功连接服务器
    connectMQTTServer();    // 则尝试连接服务器
  }
}
void tickerCount(){
  count++;
}
void connectMQTTServer(){
  String clientId = DEVICE_ID;
  String productId=PRODUCT_ID;
  String apiKey=API_KEY;
  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str(),productId.c_str(),apiKey.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }   
}
// 订阅指定主题
void subscribeTopic(){
 
  // 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
  // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
  String topicString = "temperature";
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  if(mqttClient.subscribe(subTopic)){
    Serial.println("Subscrib Topic:");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}
 void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);
 //测试下发数据
  if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
    digitalWrite(BUILTIN_LED, LOW);  // 则点亮LED。
    Serial.println("LED ON");
  } else if((char)payload[0] == '0'){                           
    digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
    Serial.println("LED OFF");
  }
}
void pubMQTTmsg(){
  //onenet数据点上传系统主题
  String topicString = "$dp";
  char publishTopic[topicString.length() + 1];  
  strcpy(publishTopic, topicString.c_str());
  //json数据转换为数组
  DynamicJsonDocument doc(16);

  doc["temperature"] = 35.5;

  serializeJson(doc, Serial);
  // 建立发布信息。温度
  String jsonCode;  
  serializeJson(doc, jsonCode);
  Serial.print("json Code: ");Serial.println(jsonCode); 
  String messageString = jsonCode; 
  char publishMsg[messageString.length() + 1];   
  strcpy(publishMsg, messageString.c_str());
  int json_len=strlen(publishMsg);
  memset(msg_buf,0,200);
  msg_buf[0]=char(0x03);
  msg_buf[1]=char(json_len>>8);
  msg_buf[2]=char(json_len &0xff);
  memcpy(msg_buf+3,publishMsg,json_len);
  // 实现ESP8266向主题发布信息
  if(mqttClient.publish(publishTopic, (uint8_t*)msg_buf,3+json_len)){
    Serial.println("Publish Topic:");Serial.println(publishTopic);
    String msg_bufTotal;
    for(int i=0;i<sizeof(msg_buf)/sizeof(msg_buf[0]);i++)
    {
      msg_bufTotal+=msg_buf[i];
    }
    Serial.println("Publish message:");Serial.println(msg_bufTotal);    
  } else {
    Serial.println("Message Publish Failed."); 
  }
}

void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
}

​ 这里通过arduino进行开发,程序下载到开发板后,便可往onenet服务器传输数据点信息,onenet服务器亦可下发指令到客户端设备,下面进行演示:

在这里插入图片描述

成功连入onenet服务器后,会自动显示在线,这里原理涉及遗嘱机制,不展开说明,知道能看到状态就好,

通过串口信息,我们往服务器$dp系统主题发送json数据(这里有很多坑,容易踩跨自己),该发送模式采用了官方传入协议的第三种模式(不问为什么,简单方便,也只试过这种),代码详情如图,需要设置模式位,字节大小位,然后json数据转码发送才能收到;

void pubMQTTmsg(){
  //onenet数据点上传系统主题
  String topicString = "$dp";
  char publishTopic[topicString.length() + 1];  
  strcpy(publishTopic, topicString.c_str());
  //json数据转换为数组
  DynamicJsonDocument doc(16);

  doc["temperature"] = 35.5;

  serializeJson(doc, Serial);
  // 建立发布信息。温度
  String jsonCode;  
  serializeJson(doc, jsonCode);
  Serial.print("json Code: ");Serial.println(jsonCode); 
  String messageString = jsonCode; 
  char publishMsg[messageString.length() + 1];   
  strcpy(publishMsg, messageString.c_str());
  int json_len=strlen(publishMsg);
  memset(msg_buf,0,200);
  msg_buf[0]=char(0x03);
  msg_buf[1]=char(json_len>>8);
  msg_buf[2]=char(json_len &0xff);
  memcpy(msg_buf+3,publishMsg,json_len);
  // 实现ESP8266向主题发布信息
  if(mqttClient.publish(publishTopic, (uint8_t*)msg_buf,3+json_len)){
    Serial.println("Publish Topic:");Serial.println(publishTopic);
    String msg_bufTotal;
    for(int i=0;i<sizeof(msg_buf)/sizeof(msg_buf[0]);i++)
    {
      msg_bufTotal+=msg_buf[i];
    }
    Serial.println("Publish message:");Serial.println(msg_bufTotal);    
  } else {
    Serial.println("Message Publish Failed."); 
  }
}

串口发送信息:

在这里插入图片描述

此时,服务器端可见:

在这里插入图片描述

这里只用了测试数据,然后我们测试下发指令:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

发送一个1,我们开发板上会亮灯,发送0会熄灭,测试成功。

这是一个完整的onenet平台连接程序代码,如果需要使用可以直接copy,注意改一下自己的onenet信息即可,可以上传数据点和下发指令,传感器方面还未加入,现仅实现通过mqtt协议与onenet平台进行通信和数据传输,后续将加入一些实际开发数据完善项目。
这是一个完整的onenet平台连接程序代码,如果需要使用可以直接copy,注意改一下自己的onenet信息即可,可以上传数据点和下发指令,传感器方面还未加入,现仅实现通过mqtt协议与onenet平台进行通信和数据传输,后续将加入一些实际开发数据完善项目。

标签:onenet,ESP8266,json,char,msg,NodeMCU,println,Serial
来源: https://blog.csdn.net/TOPthemaster/article/details/112426922