ESP32 + MQTT 连接到中移动物联网云平台 OneNET

功能说明:ESP32 通过 MQTT 连接到中国移动物联网云平台 OneNET

应用展示 - https://open.iot.10086.cn/appview/p/1c77653399eb0cdde908b7e1faf1c1aa

子模块

ESP32 MQTT 组件库

功能列表

  • [x] 连接鉴权
  • [x] 心跳包
  • [x] 数据上报(QoS0, QoS1, QoS2)
  • [ ] 平台命令处理(QoS0)
  • [ ] 创建 Topic
  • [ ] 订阅
  • [ ] 取消订阅
  • [ ] 推送设备 Topic
  • [ ] 离线 Topic
  • [ ] 数据点订阅
  • [ ] 动态接入设备
  • [ ] 批量接入设备

快速体验

如果你已对oneNET有一定的了解,且能够使用 ESP-IDF 编译 hello-world,则可以按照下面的步骤快速体验。

  • 登录oneNET,依次创建产品,添加设备,设置鉴权信息。记录下产品ID、设备ID和鉴权信息。
  • 创建一个数据流,并记录下该数据流的名称。
  • 修改本仓库源代码目录下的config.h文件,主要包括: 
    • WIFI_SSID - esp32需要连接到的AP的ssid。
    • WIFI_PASS - esp32需要连接到的AP的密码。
    • ONENET_DEVICE_ID - 云平台所创建设备的设备ID。
    • ONENET_PROJECT_ID - 云平台所创建的产品的产品ID。
    • ONENET_AUTH_INFO - 自己设置的鉴权信息。
    • ONENET_DATA_STREAM - 自己所创建的数据流的名称。
  • 编译工程: 
    • 指定 ESP-IDF 所在路径:export IDF_PATH=/你的/ESP/IDF/所在的/路径
    • 编译&烧写:make & make flash

详细步骤

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>

#include "soc/rtc_cntl_reg.h"

#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"


#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"

#include "config.h"
#include "debug.h"

#include "mqtt.h"
#include "os.h"
#include "onenet.h"

static bool onenet_initialised = false;
static TaskHandle_t xOneNetTask = NULL;

void onenet_task(void *param)
{
   mqtt_client* client = (mqtt_client *)param;
   uint32_t val;

   while(1) {
        /**
         * Replace this *val* with real captured value by your sensor,
         * Here, we just use a rand number which ranges form 15 to 35. 
         */
        val = os_random() % 20 + 15;

        char buf[128];
        memset(buf, 0, sizeof(buf));
        sprintf(&buf[3], "{\"%s\":%d}", ONENET_DATA_STREAM, val);
        uint16_t len = strlen(&buf[3]);
        buf[0] = data_type_simple_json_without_time;
        buf[1] = len >> 8;
        buf[2] = len & 0xFF;
        mqtt_publish(client, "$dp", buf, len + 3, 0, 0);

		for (int i = 0 ; i < len + 3; i ++){
			printf("0x%02x ", buf[i]);
		}
		printf(", len:%d\n", len+3);
    
        vTaskDelay((unsigned long long)ONENET_PUB_INTERVAL* 1000 / portTICK_RATE_MS);
   }
}


void onenet_start(mqtt_client *client)
{
    if(!onenet_initialised) {
        xTaskCreate(&onenet_task, "onenet_task", 2048, client, CONFIG_MQTT_PRIORITY + 1, &xOneNetTask);
        onenet_initialised = true;
    }
}

void onenet_stop(mqtt_client *client)
{
    if(onenet_initialised) {
        if(xOneNetTask) {
            vTaskDelete(xOneNetTask);
        }
        onenet_initialised = false;
    }
}

void connected_cb(void *self, void *params)
{
	INFO("[USER] connected_cb\n");
    mqtt_client *client = (mqtt_client *)self;
    //
    mqtt_subscribe(client, "/test", 0);   //订阅 /test 这个topic
    mqtt_publish(client, "/test", "howdy!", 6, 0, 0);//向 /test 这个topic进行发布

// onenet_start(client);}void disconnected_cb(void *self, void *params){ INFO("[USER] disconnected_cb\n"); mqtt_client *client = (mqtt_client *)self; onenet_stop(client);}void reconnect_cb(void *self, void *params){INFO("[USER] reconnect_cb\n"); mqtt_client *client = (mqtt_client *)self; onenet_start(client);}void subscribe_cb(void *self, void *params){INFO("[USER] subscribe_cb\n"); INFO("[APP] Subscribe ok, test publish msg\n"); mqtt_client *client = (mqtt_client *)self; // mqtt_publish(client, "/test", "abcde", 5, 0, 0); //}void publish_cb(void *self, void *params){INFO("[USER] publish_cb\n");}void data_cb(void *self, void *params){INFO("[USER] data_cb\n"); (void)self; mqtt_event_data_t *event_data = (mqtt_event_data_t *)params; if (event_data->data_offset == 0) { char *topic = malloc(event_data->topic_length + 1); memcpy(topic, event_data->topic, event_data->topic_length); topic[event_data->topic_length] = 0; INFO("[APP] Publish topic: %s\n", topic); free(topic); } // char *data = malloc(event_data->data_length + 1); // memcpy(data, event_data->data, event_data->data_length); // data[event_data->data_length] = 0; INFO("[APP] Publish data[%d/%d bytes] is %s\n", event_data->data_length + event_data->data_offset, event_data->data_total_length,event_data->data); //在这里进行订阅的topic 在这里进行数据接收 // data); // free(data);}mqtt_settings settings = { .host = ONENET_HOST, .port = ONENET_PORT, .client_id = ONENET_DEVICE_ID, .username = ONENET_PROJECT_ID, .password = ONENET_AUTH_INFO, .clean_session = 0, .keepalive = 120, .lwt_topic = "/lwt", .lwt_msg = "offline", .lwt_qos = 0, .lwt_retain = 0, .connected_cb = connected_cb, .disconnected_cb = disconnected_cb, .reconnect_cb = reconnect_cb, .subscribe_cb = subscribe_cb, .publish_cb = publish_cb, .data_cb = data_cb};static esp_err_t wifi_event_handler(void *ctx, system_event_t *event){ switch(event->event_id) { case SYSTEM_EVENT_STA_START: ESP_ERROR_CHECK(esp_wifi_connect()); break; case SYSTEM_EVENT_STA_GOT_IP: mqtt_start(&settings); // Notice that, all callback will called in mqtt_task // All function publish, subscribe break; case SYSTEM_EVENT_STA_DISCONNECTED: /* This is a workaround as ESP32 WiFi libs don't currently auto-reassociate. */ mqtt_stop(); ESP_ERROR_CHECK(esp_wifi_connect()); break; default: break; } return ESP_OK;}void wifi_conn_init(void){ INFO("[APP] Start, connect to Wifi network: %s ..\n", WIFI_SSID); tcpip_adapter_init(); ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) ); wifi_init_config_t icfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK( esp_wifi_init(&icfg) ); ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); wifi_config_t wifi_config = { .sta = { .ssid = WIFI_SSID, .password = WIFI_PASS }, }; ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); ESP_ERROR_CHECK( esp_wifi_start());}void app_main(){ INFO("[APP] Startup..\n"); INFO("[APP] Free memory: %d bytes\n", esp_get_free_heap_size()); INFO("[APP] Build time: %s\n", BUID_TIME);#ifdef CPU_FREQ_160MHZ INFO("[APP] Setup CPU run as 160MHz\n"); SET_PERI_REG_BITS(RTC_CLK_CONF, RTC_CNTL_SOC_CLK_SEL, 0x1, RTC_CNTL_SOC_CLK_SEL_S); WRITE_PERI_REG(CPU_PER_CONF_REG, 0x01); INFO("[APP] Setup CPU run as 160MHz - Done\n");#endif nvs_flash_init(); wifi_conn_init();}

说明

当前仓库中代码所上传的数据是假数据 —— 一个 15~35 之间的随机数,在实际应用中可添加传感器,并将其采集到的数据上传至云平台。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值