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 之间的随机数,在实际应用中可添加传感器,并将其采集到的数据上传至云平台。

### 回答1: app+stm32+esp8266+mqtt协议可以实现将数据上传到onenet云平台。具体实现步骤如下: 1. 编写stm32程序,采集传感器数据并通过esp8266模块将数据发送到onenet云平台。 2. 在esp8266模块使用mqtt协议连接onenet云平台,并将采集到的数据发布到指定的主题。 3. 在onenet云平台上创建设备,并将设备与mqtt主题绑定。 4. 在onenet云平台上创建数据流,并将数据流与设备绑定。 5. 在onenet云平台上创建数据模板,并将数据模板与数据流绑定。 6. 在app使用onenet提供的api接口,获取设备数据并进行展示。 通过以上步骤,就可以实现将stm32采集到的数据上传到onenet云平台,并在app进行展示。 ### 回答2: STM32是意法半导体公司推出的一款32位微控制器芯片,具有低功耗、高性能、高可靠性等特点,广泛应用于物联网、工业自动化、智能家居等领域。ESP8266是一款集成WiFi模块的微控制器芯片,具有低成本、低功耗、易于上手等特点,也广泛应用于物联网、智能家居等领域。MQTT协议是一款轻量级的物联网通信协议,可以实现低功耗、高可靠性、高扩展性等特点,特别适用于物联网场景的设备间通信OneNet移动推出的物联网云平台,提供设备管理、数据存储和可视化展示等功能,支持多种通信协议,包括MQTT。基于STM32和ESP8266,我们可以通过MQTT协议将设备数据上传至OneNet云平台,实现对设备状态的监控和远程控制。 具体实现步骤包括: 1. 在STM32和ESP8266分别实现MQTT协议的相关功能,如连接服务器、发布订阅消息、接收数据等。 2. 接入OneNet云平台,创建设备和数据流,并获取设备ID和API Key。 3. 在STM32发送设备数据到ESP8266,ESP8266通过MQTT协议将数据上传到OneNet云平台,并记录上传数据的时间戳。 4. 在OneNet云平台可以实现对设备数据的监控、历史数据查询、报警设置等功能。同时,也可以通过API接口实现数据的远程控制。 总之,基于STM32和ESP8266的MQTT协议上云OneNet,是一种方便快捷、低成本高效的物联网应用方案。通过实现设备与互联网的连接,可以实现智能化控制、远程监控等功能,提高工作效率和生活品质。 ### 回答3: STM32和ESP8266都是常用的嵌入式单片机,而MQTT是一种轻量级的消息传输协议,通常被用于物联网设备间的通信。而OneNet是国内比较知名的物联网云平台,它提供开发者友好的接口以及强大的数据管理功能,方便开发者快速构建物联网应用。在使用STM32和ESP8266进行物联网开发上,MQTT协议和OneNet的结合能够为开发带来很多便利。 首先讲一下STM32和ESP8266的配合。在嵌入式系统,STM32通常作为主控制器,用于控制各种传感器以及执行设备控制操作。而ESP8266则可以作为一种无线模块,用于与网络进行通信。在物联网应用,ESP8266作为WiFi模块,可以将STM32采集到的数据或进行的控制操作通过WiFi连接发送到数据云平台上,用于实时数据监控或设备远程控制等。 而MQTT协议可以帮助我们快速实现消息传输和设备控制。MQTT协议相较于HTTP等传统网络协议来说,它的传输速度更快、开销更小,且支持低功耗的设备。比如在家庭物联网系统,我们可以将一些传感器(比如温度、湿度、烟雾检测等)通过STM32采集到,然后通过ESP8266模块发送到OneNet。这样就可以实现实时的数据监控和远程控制等功能了。 最后,OneNet平台是国内较为知名的物联网云平台,支持MQTT协议,提供了丰富的接口和SDK,可以帮助开发者快速构建物联网应用。在使用MQTT协议与OneNet平台结合时,我们只需要在设备端运用MQTT协议,将采集到的数据发送到OneNet平台上,然后在云平台上进行数据存储、处理和分析等操作,从而实现对设备的远程监控和控制。 总的来说,STM32和ESP8266的配合,MQTT协议的应用以及OneNet平台的支持,可以为物联网设备的快速开发和应用提供很大的帮助。未来,随着物联网的普及和发展,这一领域的应用前景将会更加广阔。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值