1.OneNet创建设备
点击右上角的控制台

点击前往控制台

点击创建产品

这里有很多产品,我们选择空调

选择设备接入,产品名字自己随便写一个,其他的按照我的填写

点击设备管理

点击添加设备

所属产品选择刚刚创建好的产品,设备名称自己看着填写,设备描述和位置信息可以不用填写,点击确定创建完设备

2.ESP32连接设备
我们创建一个空的esp-idf项目
在main.c里添加wifi代码
#include <stdio.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#define TAG "main"
#define SSID ""
#define PASSWORD ""
static uint8_t s_retry_num = 0;
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < 5)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
}
}
void wifi_init(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
wifi_config_t wifi_cfg = {
.sta = {
.ssid = SSID,
.password = PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
}接下来是mqtt代码
static void mqtt_event_handler(void *arg, esp_event_base_t base, int32_t event_id, void *event_data)
{
esp_mqtt_event_handle_t event = event_data;
switch (event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED");
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED");
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "Received data on topic=%.*s", event->topic_len, event->topic);
ESP_LOGI(TAG, "Data payload=%.*s", event->data_len, event->data);
break;
default:
break;
}
}
void mqtt_start(void)
{
char token[256] = {0};
generate_onenet_token(token, sizeof(token), KEY, TOKEN_RES, TOKEN_TIME);
esp_mqtt_client_handle_t client;
const esp_mqtt_client_config_t cfg = {
.broker.address.uri = MQTT_URL,
.credentials.client_id = DEVICE_NAME,
.credentials.username = PRODUCTID,
.credentials.authentication.password = token,
.session.keepalive = 120,
};
client = esp_mqtt_client_init(&cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
}我们需要自己去获取一下设备名称和产品ID还有key

将这些填入代码
#define MQTT_URL "mqtt://mqtts.heclouds.com:1883"
#define DEVICE_NAME "device"
#define PRODUCTID "4RgM5b7fB5"
#define KEY "Y1psT1ZYVU9CTlhzNkhSU0t1TzJJRFZUaDhCM3VlNlI="
//这个是后面计算token需要使用到的 固定格式为products/产品ID/devices/设备名称
#define TOKEN_RES "products/4RgM5b7fB5/devices/device"接下来我们需要计算tokenhttps://iot.10086.cn/doc/aiot/fuse/detail/1487 这个是文档
可以用官方给的工具来计算token
下载链接:https://open.iot.10086.cn/college/video/onenet-portal/2024-04-19/17134946071850.exe

res:products/4RgM5b7fB5/devices/device
key:Y1psT1ZYVU9CTlhzNkhSU0t1TzJJRFZUaDhCM3VlNlI=
et是这个token的到期的时间戳,可以用这个网站进行获取 https://tool.lu/timestamp/

比如说我这里是2030年,转换出来的时间戳1910577382复制到et就行
信息填完后获取token

不过一般我们不用上面那种方式,都是在代码里计算token的,下面来讲解一下token的计算
static void url_encode(const char *src, char *dest, int dest_len)
{
while (*src && dest_len > 3)
{
if (*src == '+')
{
sprintf(dest, "%%2B");
dest += 3;
dest_len -= 3;
}
else if (*src == '/')
{
sprintf(dest, "%%2F");
dest += 3;
dest_len -= 3;
}
else if (*src == '=')
{
sprintf(dest, "%%3D");
dest += 3;
dest_len -= 3;
}
else
{
*dest++ = *src;
dest_len--;
}
src++;
}
*dest = '\0';
}
/**
* @brief 生成OneNET的Token (完美支持md5与sha256自动切换)
*/
void generate_onenet_token(char *out_token, size_t max_len, const char *access_key, const char *res, long et)
{
const char *version = "2018-10-31";
const char *method = "md5"; // 如果要换 sha256,只需要改这里即可
// 1. 解码 AccessKey (Base64)
unsigned char decoded_key[64] = {0};
size_t decoded_key_len = 0;
mbedtls_base64_decode(decoded_key, sizeof(decoded_key), &decoded_key_len, (const unsigned char *)access_key, strlen(access_key));
// 2. 拼接待签名字符串
char string_to_sign[256];
snprintf(string_to_sign, sizeof(string_to_sign), "%ld\n%s\n%s\n%s", et, method, res, version);
// 3. 🎯 修复:根据 method 动态选择算法类型和输出长度
unsigned char hmac_output[32] = {0};
size_t hmac_len = 0;
const mbedtls_md_info_t *md_info = NULL;
if (strcmp(method, "md5") == 0)
{
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
hmac_len = 16; // MD5 结果是 16 字节
}
else
{
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
hmac_len = 32; // SHA256 结果是 32 字节
}
mbedtls_md_context_t ctx;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, md_info, 1);
mbedtls_md_hmac_starts(&ctx, decoded_key, decoded_key_len);
mbedtls_md_hmac_update(&ctx, (const unsigned char *)string_to_sign, strlen(string_to_sign));
mbedtls_md_hmac_finish(&ctx, hmac_output);
mbedtls_md_free(&ctx);
// 4. 🎯 修复:将真正的 hmac_len 传入 Base64 编码
char base64_sign[64] = {0};
size_t base64_len = 0;
mbedtls_base64_encode((unsigned char *)base64_sign, sizeof(base64_sign), &base64_len, hmac_output, hmac_len);
// 5. 对关键字段进行 URL 编码
char encoded_res[128] = {0};
char encoded_sign[128] = {0};
url_encode(res, encoded_res, sizeof(encoded_res));
url_encode(base64_sign, encoded_sign, sizeof(encoded_sign));
// 6. 最终拼装
snprintf(out_token, max_len, "version=%s&res=%s&et=%ld&method=%s&sign=%s", version, encoded_res, et, method, encoded_sign);
}完整代码
烧录代码到esp32
#include <stdio.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "mqtt_client.h"
#include "mbedtls/md.h"
#include "mbedtls/base64.h"
#define TAG "main"
#define SSID "ChinaNet-cfu6"
#define PASSWORD "6vtndlma"
#define MQTT_URL "mqtt://mqtts.heclouds.com:1883"
#define DEVICE_NAME "device"
#define PRODUCTID "4RgM5b7fB5"
#define KEY "Y1psT1ZYVU9CTlhzNkhSU0t1TzJJRFZUaDhCM3VlNlI="
#define TOKEN_RES "products/4RgM5b7fB5/devices/device"
#define TOKEN_TIME 1910577382
void mqtt_start(void);
static uint8_t s_retry_num = 0;
static void url_encode(const char *src, char *dest, int dest_len)
{
while (*src && dest_len > 3)
{
if (*src == '+')
{
sprintf(dest, "%%2B");
dest += 3;
dest_len -= 3;
}
else if (*src == '/')
{
sprintf(dest, "%%2F");
dest += 3;
dest_len -= 3;
}
else if (*src == '=')
{
sprintf(dest, "%%3D");
dest += 3;
dest_len -= 3;
}
else
{
*dest++ = *src;
dest_len--;
}
src++;
}
*dest = '\0';
}
/**
* @brief 生成OneNET的Token (完美支持md5与sha256自动切换)
* @param out_token token的输出
* @param max_len token的最大长度
* @param access_key key
* @param res token_res
* @param et 时间戳
*/
void generate_onenet_token(char *out_token, size_t max_len, const char *access_key, const char *res, long et)
{
const char *version = "2018-10-31";
const char *method = "md5"; // 如果要换 sha256,只需要改这里即可
// 1. 解码 AccessKey (Base64)
unsigned char decoded_key[64] = {0};
size_t decoded_key_len = 0;
mbedtls_base64_decode(decoded_key, sizeof(decoded_key), &decoded_key_len, (const unsigned char *)access_key, strlen(access_key));
// 2. 拼接待签名字符串
char string_to_sign[256];
snprintf(string_to_sign, sizeof(string_to_sign), "%ld\n%s\n%s\n%s", et, method, res, version);
// 3. 🎯 修复:根据 method 动态选择算法类型和输出长度
unsigned char hmac_output[32] = {0};
size_t hmac_len = 0;
const mbedtls_md_info_t *md_info = NULL;
if (strcmp(method, "md5") == 0)
{
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
hmac_len = 16; // MD5 结果是 16 字节
}
else
{
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
hmac_len = 32; // SHA256 结果是 32 字节
}
mbedtls_md_context_t ctx;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, md_info, 1);
mbedtls_md_hmac_starts(&ctx, decoded_key, decoded_key_len);
mbedtls_md_hmac_update(&ctx, (const unsigned char *)string_to_sign, strlen(string_to_sign));
mbedtls_md_hmac_finish(&ctx, hmac_output);
mbedtls_md_free(&ctx);
// 4. 🎯 修复:将真正的 hmac_len 传入 Base64 编码
char base64_sign[64] = {0};
size_t base64_len = 0;
mbedtls_base64_encode((unsigned char *)base64_sign, sizeof(base64_sign), &base64_len, hmac_output, hmac_len);
// 5. 对关键字段进行 URL 编码
char encoded_res[128] = {0};
char encoded_sign[128] = {0};
url_encode(res, encoded_res, sizeof(encoded_res));
url_encode(base64_sign, encoded_sign, sizeof(encoded_sign));
// 6. 最终拼装
snprintf(out_token, max_len, "version=%s&res=%s&et=%ld&method=%s&sign=%s", version, encoded_res, et, method, encoded_sign);
}
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < 5)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
mqtt_start();
}
}
static void mqtt_event_handler(void *arg, esp_event_base_t base, int32_t event_id, void *event_data)
{
esp_mqtt_event_handle_t event = event_data;
switch (event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED");
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED");
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "Received data on topic=%.*s", event->topic_len, event->topic);
ESP_LOGI(TAG, "Data payload=%.*s", event->data_len, event->data);
break;
default:
break;
}
}
void wifi_init(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
wifi_config_t wifi_cfg = {
.sta = {
.ssid = SSID,
.password = PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
}
void mqtt_start(void)
{
char token[256] = {0};
generate_onenet_token(token, sizeof(token), KEY, TOKEN_RES, TOKEN_TIME);
esp_mqtt_client_handle_t client;
const esp_mqtt_client_config_t cfg = {
.broker.address.uri = MQTT_URL,
.credentials.client_id = DEVICE_NAME,
.credentials.username = PRODUCTID,
.credentials.authentication.password = token,
.session.keepalive = 120,
};
client = esp_mqtt_client_init(&cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
}
void app_main(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init();
}烧录成功并且成功连接上mqtt后打印
I (1942) main: MQTT_EVENT_CONNECTED
OneNet设备状态显示在线

3.设备通讯
成功连接上OneNe后,我们需要让esp32和物模型主题进行通讯
文档:https://iot.10086.cn/doc/aiot/fuse/detail/920

有很多通讯主题,我们主要来了解一下这几个
pid:PRODUCTID
device-name:DEVICE_NAME
接下来我们可以增加以下代码来进行通讯
//Topic主题
#define TOPIC_POST "$sys/4RgM5b7fB5/device/thing/property/post"
#define TOPIC_GET "$sys/4RgM5b7fB5/device/thing/property/get"
#define TOPIC_SET "$sys/4RgM5b7fB5/device/thing/property/set"
//写在mqtt_event_handler的MQTT_EVENT_CONNECTED事件里
//订阅主题
esp_mqtt_client_subscribe(event->client, TOPIC_GET, 1);
esp_mqtt_client_subscribe(event->client, TOPIC_SET, 1);
//上报当前温度属性
//数据报不能有错,否则云端不会去处理
static const char *data = "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"currentTemp\":{\"value\":30}}}";
esp_mqtt_client_publish(event->client, TOPIC_POST, data, strlen(data), 1, 0);向 OneNET 上报设备属性时,必须严格遵循以下 JSON 结构
{ "id": "123", "version": "1.0", "params": { "currentTemp": { "value": 30 } } }
属性标识符在设备管理里的设备详情里的属性里看,点击红色箭头指向的地方

标识符就是"params": { "currentTemp": { "value": 30 } } 这里的currentTemp

完整代码
#include <stdio.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "mqtt_client.h"
#include "mbedtls/md.h"
#include "mbedtls/base64.h"
#define TAG "main"
#define SSID "ChinaNet-cfu6"
#define PASSWORD "6vtndlma"
#define MQTT_URL "mqtt://mqtts.heclouds.com:1883"
#define DEVICE_NAME "device"
#define PRODUCTID "4RgM5b7fB5"
#define KEY "Y1psT1ZYVU9CTlhzNkhSU0t1TzJJRFZUaDhCM3VlNlI="
#define TOKEN_RES "products/4RgM5b7fB5/devices/device"
#define TOKEN_TIME 1910577382
#define TOPIC_POST "$sys/4RgM5b7fB5/device/thing/property/post"
#define TOPIC_GET "$sys/4RgM5b7fB5/device/thing/property/get"
#define TOPIC_SET "$sys/4RgM5b7fB5/device/thing/property/set"
void mqtt_start(void);
static uint8_t s_retry_num = 0;
static void url_encode(const char *src, char *dest, int dest_len)
{
while (*src && dest_len > 3)
{
if (*src == '+')
{
sprintf(dest, "%%2B");
dest += 3;
dest_len -= 3;
}
else if (*src == '/')
{
sprintf(dest, "%%2F");
dest += 3;
dest_len -= 3;
}
else if (*src == '=')
{
sprintf(dest, "%%3D");
dest += 3;
dest_len -= 3;
}
else
{
*dest++ = *src;
dest_len--;
}
src++;
}
*dest = '\0';
}
/**
* @brief 生成OneNET的Token (完美支持md5与sha256自动切换)
* @param out_token token的输出
* @param max_len token的最大长度
* @param access_key key
* @param res token_res
* @param et 时间戳
*/
void generate_onenet_token(char *out_token, size_t max_len, const char *access_key, const char *res, long et)
{
const char *version = "2018-10-31";
const char *method = "md5"; // 如果要换 sha256,只需要改这里即可
// 1. 解码 AccessKey (Base64)
unsigned char decoded_key[64] = {0};
size_t decoded_key_len = 0;
mbedtls_base64_decode(decoded_key, sizeof(decoded_key), &decoded_key_len, (const unsigned char *)access_key, strlen(access_key));
// 2. 拼接待签名字符串
char string_to_sign[256];
snprintf(string_to_sign, sizeof(string_to_sign), "%ld\n%s\n%s\n%s", et, method, res, version);
// 3. 🎯 修复:根据 method 动态选择算法类型和输出长度
unsigned char hmac_output[32] = {0};
size_t hmac_len = 0;
const mbedtls_md_info_t *md_info = NULL;
if (strcmp(method, "md5") == 0)
{
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
hmac_len = 16; // MD5 结果是 16 字节
}
else
{
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
hmac_len = 32; // SHA256 结果是 32 字节
}
mbedtls_md_context_t ctx;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, md_info, 1);
mbedtls_md_hmac_starts(&ctx, decoded_key, decoded_key_len);
mbedtls_md_hmac_update(&ctx, (const unsigned char *)string_to_sign, strlen(string_to_sign));
mbedtls_md_hmac_finish(&ctx, hmac_output);
mbedtls_md_free(&ctx);
// 4. 🎯 修复:将真正的 hmac_len 传入 Base64 编码
char base64_sign[64] = {0};
size_t base64_len = 0;
mbedtls_base64_encode((unsigned char *)base64_sign, sizeof(base64_sign), &base64_len, hmac_output, hmac_len);
// 5. 对关键字段进行 URL 编码
char encoded_res[128] = {0};
char encoded_sign[128] = {0};
url_encode(res, encoded_res, sizeof(encoded_res));
url_encode(base64_sign, encoded_sign, sizeof(encoded_sign));
// 6. 最终拼装
snprintf(out_token, max_len, "version=%s&res=%s&et=%ld&method=%s&sign=%s", version, encoded_res, et, method, encoded_sign);
}
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < 5)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
mqtt_start();
}
}
static void mqtt_event_handler(void *arg, esp_event_base_t base, int32_t event_id, void *event_data)
{
esp_mqtt_event_handle_t event = event_data;
switch (event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
esp_mqtt_client_subscribe(event->client, TOPIC_GET, 1);
esp_mqtt_client_subscribe(event->client, TOPIC_SET, 1);
static const char *data = "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"currentTemp\":{\"value\":30}}}";
esp_mqtt_client_publish(event->client, TOPIC_POST, data, strlen(data), 1, 0);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED");
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED");
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "Received data on topic=%.*s", event->topic_len, event->topic);
ESP_LOGI(TAG, "Data payload=%.*s", event->data_len, event->data);
break;
default:
break;
}
}
void wifi_init(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
wifi_config_t wifi_cfg = {
.sta = {
.ssid = SSID,
.password = PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
}
void mqtt_start(void)
{
char token[256] = {0};
generate_onenet_token(token, sizeof(token), KEY, TOKEN_RES, TOKEN_TIME);
esp_mqtt_client_handle_t client;
const esp_mqtt_client_config_t cfg = {
.broker.address.uri = MQTT_URL,
.credentials.client_id = DEVICE_NAME,
.credentials.username = PRODUCTID,
.credentials.authentication.password = token,
.session.keepalive = 120,
};
client = esp_mqtt_client_init(&cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
}
void app_main(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init();
}烧录到esp32后OneNet控制台显示温度

串口打印
I (1892) main: MQTT_EVENT_CONNECTED
I (1932) main: MQTT_EVENT_SUBSCRIBED
I (1972) main: MQTT_EVENT_SUBSCRIBED
I (1972) main: MQTT_EVENT_PUBLISHED
4.结尾
前面我们完成了 ESP32 到 OneNET 的数据上报。下一步,我们将加入手机 App 端,打通双向通信。这样即使不在设备身边,也能随时随地通过手机远程监控和控制 ESP32,完成一个完整的物联网远程控制闭环。
评论交流
欢迎留下你的想法