• 【LWM2M协议传输ADC到ONENET移动云】


    Arduino教程传送门🧭🏔🌋🛤🏞🏜

    1. 简介

    采用移远的BC20物联网模块,实现NB-IOT的LWM2M协议透传,接下让我们开启ONENET的NB-IOT物联网开发吧!😀😀😀

    LwM2M协议是OMA组织制定的轻量化的M2M协议,主要面向基于蜂窝的窄带物联网(Narrow Band Internet of Things, NB-IoT)场景下物联网应用,聚焦于低功耗广覆盖(LPWA)物联网(IoT)市场,是一种可在全球范围内广泛应用的新兴技术。具有覆盖广、连接多、速率低、成本低、功耗低、架构优等特点。
    LwM2M协议适用于轻量级的协议适用于各种物联网设备,LwM2M定义了三个逻辑实体:
    LwM2M Server 服务器;
    LwM2M Client 客户端,负责执行服务器的命令和上报执行结果;
    LwM2M 引导服务器 Bootstrap Server,负责配置LwM2M客户端。
    LwM2M协议架构及协议栈如下图所示:
    在这里插入图片描述

    2. 实验准备

    实验准备包括硬件和软件两部分。

    2.1 硬件

    你要实现用ESP 8266+ONENET物联网你需要准备以下材料

    1. 移远的BC20物联网模块(外加数据线);
    2. ST-LINGK下载器
    3. 四根母母杜邦线

    在这里插入图片描述

    2.2 软件

    1. Keil 5.31版本;
      2.10.LWM2M协议传输ADC到ONENET移动云程序;
    2. 浏览器登录onenet平台
      在这里插入图片描述

    3. 实验步骤

    首先搭建onenet平台,记录对应创建的产品相关参数,以便后期程序端口接入开发。👩👩👩

    3.1 搭建onenet监控平台

    1. 登录onenet平台,选择控制台🎈
      在这里插入图片描述

    2. 来到控制台首页,选择全部产品服务,采用NB-IOT接入🎈🎈
      在这里插入图片描述

    3. 立即添加设备,完善相关信息,点击添加完成设备添加🎈🎈🎈🎈

    在这里插入图片描述
    在这里插入图片描述

    IMSI:460043331905774
    //自己串口查询卡号
    IMEI:862177042740673
    //自己串口查询卡密
    
    • 1
    • 2
    • 3
    • 4

    具体可参照:【BC20开发板的NB和GPS的硬件调试】

    1. 这样就添加产品和设备都完成了,然后点击详情🎈🎈🎈🎈🎈
      在这里插入图片描述

    3.2 为ESP8266-NodeMCU烧入程序

    1. 硬件连接,ESP8266-NodeMCU硬件连接非常简单,只需将DHT11数据线接入D6引脚就好,具体接线如下
    ESP8266-NodeMCU -----> USBtoTLL
    VCC -----> 3.3V 
    GND -----> GND
    out -----> D6
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    2. 程序设计,程序有三部分esp8266_mqtt、OneNet和smartConfig,其中:

    文件名功能
    esp8266_mqtt程序初始化调用和主程序调用;
    OneNet初始化系统、连接OneNet、云端下发、发布温湿度信息
    smartConfig自动连接、一键配网、延时重启

    在这里插入图片描述

    esp8266_mqtt代码如下,只需要修改对应的wifi和onenet的三个参数;

    /**
       The blue LED on the ESP-01 module is connected to GPIO1
       1.实现ESP8266通过MQTT协议连接ONENET
       2.实现DHT11温湿度数据的获取,串口发送调试,并将数据上发ONENET平台,于平台控件中显示数据
       3.实现ONENET平台对ESP8266板载LED亮灭的控制
       4.实现可以通过WIFI_DEBUG选择是使用一键配网功能还是使用代码中写入的无线账号密码连接,该功能主要考虑程序的通用性
       @author 234vor参考https://blog.csdn.net/weixin_43278295/article/details/114900553
       @date 2021/10/30
    */
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define WIFI_DEBUG 1          //1:使用一键配网,其它值则使用默认无线账号密码
    #define DHT11PIN 12           //设置DHT引脚为Pin 12(D6)
    #define ONENET_DISCONNECTED 1 //已经断开
    #define ONENET_CONNECTED 2    //已经连接上
    #define ONENET_RECONNECT 3    //重连成功
    #define VER  "ESP8266_MQTT_V1.0"  //版本号
    
    #define AP_SSID "J09 502" //需要修改你的wifi名字
    #define AP_PSW  "qwertyuiop111"//需要修改你的wifi密码
    
    
    /*OneNet*/
    PubSubClient mqttClient;
    const char* mqttServer = "183.230.40.39";//mqtt服务器
    const uint16_t mqttPort = 6002;       //端口号
    #define onenet_productId   "466002" //需要修改产品ID
    #define onenet_deviceId    "804892296" //需要修改设备ID
    #define onenet_apiKey      "EQbaLsJlXRaIG8gD7w5Dsc6i3hc=" //需要修改API_KEY
    
    int state;
    Ticker delayTimer;
    WiFiClient espClient;
    dht11 DHT11;
    
    
    /* 初始化ONENET通信 */
    void initOneNetMqtt() {
      mqttClient.setServer(mqttServer, mqttPort);
      mqttClient.setClient(espClient);
      mqttClient.setCallback(callback);
    }
    
    
    /* 初始化 */
    void setup() {
      initSystem();
      initOneNetMqtt();
    }
    
    /* 主函数 */
    void loop() {
      ESP.wdtFeed();
      DHT11.read(DHT11PIN);
      state = connectToOneNetMqtt();
      Serial.println(WiFi.status());
      if (state == ONENET_RECONNECT) {
        mqttClient.loop();
      }
      else if (state == ONENET_CONNECTED) {
        printf("temp:%d \r\n", DHT11.temperature);
        printf("humi:%d \r\n", DHT11.humidity);
        Temp_pubMQTTmsg(DHT11.temperature);
        Humi_pubMQTTmsg(DHT11.humidity);
        mqttClient.loop();
      }
      delay(2000);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    OneNet代码如下

    /**
     * The blue LED on the ESP-01 module is connected to GPIO1
       初始化系统、连接OneNet、云端下发、发布温湿度信息
    */
    
    /* 初始化系统 */
    void initSystem() {
      int cnt = 0;
      Serial.begin (115200);
      Serial.println("\r\n\r\nStart ESP8266 MQTT");
      Serial.print("Firmware Version:");
      Serial.println(VER);
      Serial.print("SDK Version:");
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.println(ESP.getSdkVersion());
    
      ESP.wdtEnable(5000);
    
      if (WIFI_DEBUG == 1) //开启一键配网模式
      {
        if (!autoConfig())
        {
          Serial.println("Start smartConfig");
          smartConfig();
        }
      }
      else
      {
        WiFi.begin(AP_SSID, AP_PSW);
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          cnt++;
          Serial.print(".");
          if (cnt >= 40) {
            cnt = 0;
            //重启系统
            delayRestart(1);
          }
        }
      }
      Serial.print("WIFI Connect \r\n");
    }
    
    /* 连接OneNet */
    int connectToOneNetMqtt() {
      int cnt = 0;
      while (!mqttClient.connected()) {
        ESP.wdtFeed();
        cnt++;
        Serial.println("Connect to OneNet MQTT...");
    
        if (mqttClient.connect(onenet_deviceId, onenet_productId, onenet_apiKey)) {
          Serial.println("connect success!");
          return ONENET_RECONNECT;
        } else {
          Serial.print("connect fail!");
          Serial.println(" try again in 5 seconds");
          delayNs(5);
        }
        if (cnt >= 10) {
          //只做10次连接到OneNet,连接不上重启8266
          cnt = 0;
          delayRestart(1);
        }
      }
      return ONENET_CONNECTED;
    }
    
    /* 云端下发 */
    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");
      for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
      }
      Serial.println();
    
      if ((char)payload[0] == '1') {
        digitalWrite(LED_BUILTIN, LOW);
      } else {
        digitalWrite(LED_BUILTIN, HIGH);
      }
    }
    
    /* 发布温度信息 */
    void Temp_pubMQTTmsg(uint32_t data) {
      long lastMsg = 0;
    
      char msg[50];
      char tmp[28];
      char d[3];
      snprintf(tmp, sizeof(tmp), "{\"Temp\":%d}", data);
      uint16_t streamLen = strlen(tmp);
    
      d[0] = '\x03';
      d[1] = (streamLen >> 8);
      d[2] = (streamLen & 0xFF);
      snprintf(msg, sizeof(msg), "%c%c%c%s", d[0], d[1], d[2], tmp);
      mqttClient.publish("$dp", (uint8_t*)msg, streamLen + 3, false);
    }
    /* 发布湿度信息 */
    void Humi_pubMQTTmsg(uint32_t data) {
      long lastMsg = 0;
    
      char msg[50];
      char tmp[28];
      char d[3];
      snprintf(tmp, sizeof(tmp), "{\"Humi\":%d}", data);
      uint16_t streamLen = strlen(tmp);
    
      d[0] = '\x03';
      d[1] = (streamLen >> 8);
      d[2] = (streamLen & 0xFF);
      snprintf(msg, sizeof(msg), "%c%c%c%s", d[0], d[1], d[2], tmp);
      mqttClient.publish("$dp", (uint8_t*)msg, streamLen + 3, false);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118

    smartConfig 代码如下

    
    /**
     * The blue LED on the ESP-01 module is connected to GPIO1
       自动连接、一键配网、延时重启
    */
    
    /* 自动连接 */
    bool autoConfig()
    {
      delay(2000);
      for (int i = 0; i < 20; i++)
      {
        Serial.println("Setup start");
        //启动STA模式,并连接到wifi网络
        WiFi.begin(AP_SSID, AP_PSW);
        Serial.print(String("Connecting to ") + AP_SSID);
        if (WiFi.status() == WL_CONNECTED)
        {
          Serial.println("AutoConfig Success");
          Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
          Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
          WiFi.printDiag(Serial);
          return true;
        }
        else
        {
          Serial.print("AutoConfig Waiting......");
          Serial.println(WiFi.status());
          delay(5000);
        }
      }
      Serial.println("AutoConfig Faild!" );
      return false;
    }
    
    /* 一键配网 */
    void smartConfig()
    {
      WiFi.mode(WIFI_STA);
      Serial.println("\r\nWait for Smartconfig");
      WiFi.beginSmartConfig();
      while (1)
      {
        Serial.print(".");
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
        if (WiFi.smartConfigDone())
        {
          Serial.println("SmartConfig Success");
          Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
          Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
          WiFi.setAutoConnect(true);  // 设置自动连接
          break;
        }
        delay(2000); // 这个地方一定要加延时,否则极易崩溃重启
      }
    }
    
    /* 延时N秒 */
    void delayNs(uint8_t m) {
      for (uint8_t index = 0; index < m; index ++) {
        delay(1000);
        ESP.wdtFeed();
      }
    }
    
    
    /* 延时重启 */
    void delayRestart(float t) {
      Serial.print("Restart after ");
      Serial.print(t);
      Serial.println("s");
      delayTimer.attach(t, []() {
        Serial.println("\r\nRestart now!");
        ESP.restart();
      });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    1. 选择NodeMCU1.0,端口选对应的,其他默认,最后点击上传;
      在这里插入图片描述

    2. 上传成功,点击串口监视器
      在这里插入图片描述

    3. Arduino串口打印显示,onenet平台显示设备在线,点击详情,选择数据流展示可见温湿度数据
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      记录这两个变量名称,Humi是湿度,Temp是温度,后面两者有交互

    Humi
    Temp
    
    • 1
    • 2

    3.3 onenet平台交互显示开发

    1. 选择数据模板,添加humi数据流模板
      在这里插入图片描述
      添加Temp数据流模板
      在这里插入图片描述

    2. 选择触发器管理,添加触发器
      在这里插入图片描述

    3. 选择应用管理,添加应用
      在这里插入图片描述

    4. 然后双击lab,进行应用控制设计
      在这里插入图片描述
      在这里插入图片描述
      进行以上操作后点击右上角保存和发布,然后选择应用管理刷新,就可以看见温湿度的动态变化🎉🎉🎉
      在这里插入图片描述
      我自己在尝试其他的拓展,显示效果如下

    在这里插入图片描述

    4. 总结

    • 本文是一个难度中等的物联网项目,实现ESP8266一键配网功能、MQTT协议连接ONENET、DHT11温湿度数据的获取、数据上发ONENET平台、ESP8266板载LED亮灭的控制、温度限幅触发器提示
    • 在以后的博文中我们将学会用ESP8266做常用的物联网开发,从而实现对外部世界进行感知,充分认识这个有机与无机的环境,科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力

    参考文献

    1. 下载驱动:包含BC20USB驱动,CH341驱动,FT232驱动,ST-LINK官方驱动,万能驱动
    2. 串口助手见:超级好用的SSCOM3.2串口助手
    3. 视频参考:14.BC20开发板LWM2M协议传输ADC传感器数据到ONENET移动云
  • 相关阅读:
    RTSP 和 RTMP原理 & 通过ffmpeg实现将本地摄像头推流到RTSP服务器
    《为你护航-网络空间安全科普读本》读书笔记
    前端(二十三)——轮询和长轮询
    低代码会使初级码农失业吗?
    【Swift 60秒】42 - Default parameters
    【Kafka】Golang中使用Kafka基于发布订阅模式实现消息队列
    某果的一个小参数分析
    针对U盘文件的盗与防攻略
    PX4模块设计之四十一:I2C/SPI Bus Instance基础知识
    Redis6.0使用了多线程还能保证线程安全么?-Redis6.0 多线程精讲
  • 原文地址:https://blog.csdn.net/vor234/article/details/122995727