ESP32-C3 应用 篇(实例一、通过MQTT协议连接ONENET上报传感器数据,云平台下发灯光调色)

简介: ESP32-C3学到现在,我们已经掌握了从基本外设到网络服务端的相关知识,这篇文章就是做一个简单的应用,使用开发板连接ONENET云平台,使用MQTT协议,上报温湿度和光照数据,平台下发命令控制全彩灯颜色切换。
ESP32-C3学到现在,我们已经掌握了从基本外设到网络服务端的相关知识,
这篇文章就是做一个简单的应用,使用开发板连接ONENET云平台,
使用MQTT协议,上报温湿度和光照数据,平台下发命令控制全彩灯颜色切换。

前言

接下来的 ESP32-C3 功能测试都是基于自己设计的开发板:

自己画一块ESP32-C3 的开发板(第一次使用立创EDA)(PCB到手)

开发环境是乐鑫官方的 ESP-IDF, 基于VScode插件搭建好的:

ESP32-C3 VScode开发环境搭建(基于乐鑫官方ESP-IDF——Windows和Ubuntu双环境)

本文作为一个具体的应用实现,把前面博文所学的知识做了个结合,具体实现的功能如下:

1. 光照度采集
ESP32-C3入门教程 基础篇(一、ADC采样)

2. 温湿度采集
ESP32-C3入门教程 基础篇(四、I2C总线 — 与SHT21温湿度传感器通讯)

3.按键操作
ESP32-C3入门教程 基础篇(二、GPIO中断、按键驱动测试)

4.全彩RGB LED控制
ESP32-C3入门教程 基础篇(五、RMT应用 — SK6812全彩RGB LED灯驱动测试)

5.周期上报数据
ESP32-C3入门教程 基础篇(六、TIMG 硬件定时器 与 软件定时器)

6.WiFi配网
ESP32-C3入门教程 网络 篇(一、 Wi-Fi 使用入门 — 初始化及STA、AP模式)
ESP32-C3入门教程 网络 篇(二、 Wi-Fi 配网 — Smart_config方式 和 BlueIF方式)

7.MQTT连接云平台
ESP32-C3入门教程 网络 篇(三、 MQTT 协议基础介绍及测试)

我们还没有讲解 ESP-IDF 的工程结构,本文虽然是综合应用实例,目的在于实现一个完成的小项目实例,对于工程代码文件结构,规范性没有处理,示例是以简单的形式呈现,特此申明! 勿杠!

当初计划是使用阿里云,但是我想到自己的手机阿里云还是新用户,新用户会有采购优惠,不能浪费了= =, 所以为了优惠这里抛弃了阿里云,采用OneNet。

一、整体框架设计

首先明白,本实例的核心部分就是 MQTT 的通信,所以整体的框架是基于 MQTT 的Demo 进行修改,
在以此为基本框架的基础上增加我们需要的组件,功能,函数。

1.1 配网添加(Smart_config )

删除 MQTT Demo中关于配网的操作,使用 Smart_config 配网方式,直接拷贝 Smart_config Demo中的函数:
在这里插入图片描述
Smart_Config的初始化函数,回调函数,任务函数都直接复制Smart_config Demo中的即可,但是得注意 其中的任务smartconfig_example_task 配网结束后需要删除,节约空间,如下图:
在这里插入图片描述

1.2 周期上报数据(Timer)

周期上报数据使用硬件定时器方式,使能一个 自动重装载的定时器,在定时器中断函数中改变状态位,提醒需要上报数据,需要的代码比定时器 demo 中的简单,只需要需要的功能,如下:
在这里插入图片描述

1.3 光照度采集(ADC)

光照度采集使用的事ADC采样,只需要简单的在 主函数中使能了ADC,直接采用单次采样的方式,加上一下数据处理,结合上面的定时器,就能实现一个周期上报功能:
在这里插入图片描述

测试效果:
在这里插入图片描述

1.4 温湿度采集(I2C)

温湿度的采集,还是根据 ESP32-C3入门教程 基础篇(四、I2C总线 — 与SHT21温湿度传感器通讯)中的内容,添加对应的 sht21.c 和 sht21.h 文件,然后在周期任务处调用测试:
在这里插入图片描述
测试效果:
在这里插入图片描述

1.5 按键(GPIO)

按键操作目的在于,当产品需要配网的时候,手动删除以前的配网信息,按键的操作在
ESP32-C3入门教程 基础篇(二、GPIO中断、按键驱动测试) 有过说明,同时在 ESP32-C3入门教程 网络 篇(二、 Wi-Fi 配网 — Smart_config方式 和 BlueIF方式)也有过说明,这里主要的用法和Wi-Fi配网教学篇中的一样,按键会主动删除曾经有过的配网信息,导致产品重新进入配网:
在这里插入图片描述
测试效果:
在这里插入图片描述
重启以后重新配网能够回归正常。

完成程序的框架设计搭建,接下来就要进场云平台的产品创建。

二、ONENET平台设置

在 OneNET平台,进入控制台,找到对应的MQTT 物联网套件:
在这里插入图片描述

2.1 添加产品 和设备

在这里插入图片描述

产品添加成功,此时可以点击如下图片立即添加设备:
在这里插入图片描述

如果当时没有立即添加,可以在产品概况的(左边栏目),设备列表里面找到关于设备的相关信息,进行添加设备:
在这里插入图片描述

添加完成后,可以看到设备离线,然后一些基本信息:
在这里插入图片描述

2.2 为设备添加数据流

找到设备
在这里插入图片描述

2.3 云平台协议参数说明

前面完成了云平台的设置,我们可以通过PC客户端先对云平台进行一个测试,在这之前,需要先了解一下ONENET MQTT协议规范的基本介绍,通过如下网站可以查找到所有需要的ONENET MQTT介绍:

OneNET MQTT 协议规范文档说明
在这里插入图片描述

2.3.1 ONENET MQTT服务器地址

mqtts.heclouds.com      1883

OneNET MQTT 服务器地址

在这里插入图片描述

2.3.2 clientld、username、password

在这里插入图片描述
更加详细的介绍如下图:
在这里插入图片描述

2.3.3 password 获取方法

连接除了clientld、username,还需要password 。 ONENET的 password 需要使用费 token 算法 获取:

ONENET token 算法说明
ONENET token工具下载
在这里插入图片描述
1、products/产品ID/devices/设备名称
在这里插入图片描述
2、时间戳

通过这个的工具获取: 在线 时间戳转换工具

在这里插入图片描述
填入工具之中:
在这里插入图片描述
3、key
在这里插入图片描述
4、生成密码
在这里插入图片描述

通过 MQTT.fx 配置连接云平台,按照如下配置进行设置:

在这里插入图片描述

配置完成以后,点击connect,在ONENET上可以看到设备在线状态:
在这里插入图片描述

2.4 订阅Topic

ONENET平台 与设备 Topic 的约定,不能随意的定义自己的Topic,有对应的规定:
在这里插入图片描述
有如下一些Topic:
在这里插入图片描述
比如,我们订阅一个上报结果,类似如图所示:
在这里插入图片描述

2.5 发送数据至云平台

我们上面完成了数据上报结果订阅,那么有关于任何数据点上报的结果,我们都能收到消息,我们使用工具来尝试一下给平台发送数据:
在这里插入图片描述
在 MQTT.fx 中,数据格式使用 Json 格式发送:
在这里插入图片描述

点击发布,我们可以通过订阅的消息看到消息已经发送,在云平台也能看到数据上报成功:
在这里插入图片描述

2.6 云平台下发命令

接收平台下发的命令,就是订阅设备所有命令相关消息:
在这里插入图片描述

在云平台点击下发命令,如下图,然后写入cmd,在MQTT.fx 中我们订阅过消息,所以能够收到命令:
在这里插入图片描述
测试完成,到时候我们将会使用这个命令来控制板子上的RGB灯。

三、整体调整测试

3.1 结合平台的基本调整

在前面其实有提到过 topic 的说明,设备发布消息到非法topic ,平台会断开设备连接:
在这里插入图片描述

所以在整体修改的过程中需要注意,不要有其他的无用的测试Topic 。

在前面修改完成的整体程序框架中,根据平台的测试结果,修改一些必要的地方:

一些基本的定义:
在这里插入图片描述MQTT配置部分代码:
在这里插入图片描述
周期上报的逻辑:
在这里插入图片描述

3.2 .url 和 .host

在此期间测试有一个问题:
在这里插入图片描述
实际上这里有个概念没有搞清楚:
在这里插入图片描述

此处的内容可参考博文:网址(url),域名,ip地址,dns,hosts之间的关系

3.3 周期上报效果

最终测试结果,周期上报板子上传感器数值,在云平台可以看到周期上报的结果:

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

3.4 下行命令处理(RMT应用)

下行命令处理,我们这里是基于订阅了云平台的 CMD 命令,但是对于这个下行的命令,目前看到也并没有一个标准的格式指定。这里目的是为了演示,所以我们怎么简单怎么来。
我们自己把下行需要处理的命令格式定位: mycmd:XXXXX。
比如:mycmd:ledred mycmd:ledblue。
这样,我们通过接受到的消息经常简单的数据处理以后,做出对应的动作。
(具体的执行可参考源码)
在这里插入图片描述

测试结果, 切换成蓝灯:

在这里插入图片描述

测试结果,切换成红灯:
在这里插入图片描述

附录(源码)

这里上一下app_main.c文件源码,其实只要看过我的教学博文,下面这个文件的代码都是有分析说明的,包括本文上面也对每个部分的功能有单独说明。整个应用工程的代码,我上传到了资源:

本博文工程源码

app_main.c

/* MQTT (over TCP) Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
/*
smartconfig
*/
#include "esp_smartconfig.h"   
#include "freertos/event_groups.h"
// #include "esp_wpa2.h"
/*
定时器
*/
#include "driver/timer.h" 
/*
ADC
*/
#include "driver/adc.h"
#include "driver/gpio.h" 
/*
I2C
*/  
#include "sht21.h"
/*
button
*/
#include "my_button.h"
/*
RMT
*/
#include "driver/rmt.h"
#include "led_strip.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 "esp_log.h"
#include "mqtt_client.h"

#define TIMER_SCALE           (TIMER_BASE_CLK / 16)  // convert counter value to seconds


#define ONENET_MqttServer "mqtts.heclouds.com"

#define ONENET_clientld   "esp32-device1"  //name
#define ONENET_UserName   "493136"     //ID
#define ONENET_Password   "version=2018-10-31&res=products%2F493136%2Fdevices%2Fesp32-device1&et=1741490120&method=md5&sign=wscxn0OWnKxbxQ7mae3CLQ%3D%3D"

//设备上传数据的post主题
#define ONENET_TOPIC_PROP_POST "$sys/" ONENET_UserName "/" ONENET_clientld "/dp/post/json"

#define ONENET_TOPIC_DP_Publish  "$sys/493136/esp32-device1/dp/post/json"
#define ONENET_TOPIC_DP_Sub      "$sys/493136/esp32-device1/dp/post/json/+"
#define ONENET_TOPIC_CMD_Sub     "$sys/493136/esp32-device1/cmd/#"

//这是post上传数据使用的模板
#define ONENET_POST_BODY_FORMAT "{\"id\":123,\"dp\":%s}"

static EventGroupHandle_t s_wifi_event_group;

static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "MQTT";
static const char *TAG2 = "smartconfig";

// static EventGroupHandle_t s_cmd_event_group;
static const int RED_BIT = BIT3;
static const int BLUE_BIT = BIT4;

bool send_cycle = false;

typedef struct {
    int timer_group;
    int timer_idx;
    int alarm_interval;
    bool auto_reload;
} example_timer_info_t;

#define RMT_TX_NUM 8 //WS2812 control pin
#define RMT_TX_CHANNEL RMT_CHANNEL_0
#define EXAMPLE_CHASE_SPEED_MS (10)
#define LED_STRIP_NUM 1
#define COLOR_RED 9
#define COLOR_GREE 8
#define COLOR_BULE 10
#define COLOR_PURPLE 11
#define COLOR_ORANGE 12

#define Lamp_Open 13
#define lamp_close 14
#define lamp_speed_Up 15
#define lamp_speed_down 16

#define ligth_down 18
#define ligth_up 19
struct WS2812_COLOR
{
    uint8_t lamp;
    uint8_t ligth_rank;
    uint8_t lamp_speed;
    uint32_t red;
    uint32_t green;
    uint32_t blue;
};

static led_strip_t *strip;

struct WS2812_COLOR WS2812_RGB;

/**
 * @brief A sample structure to pass events from the timer ISR to task
 *
 */
typedef struct {
    example_timer_info_t info;
    uint64_t timer_counter_value;
} example_timer_event_t;



static void smartconfig_example_task(void * parm);
static void led_cmd_task(void * parm);

void RGB16for10(struct WS2812_COLOR *RGB, uint32_t reb_16)
{
    uint32_t rgb_16 = reb_16;
    RGB->blue = rgb_16 & 0Xff;

    rgb_16 = rgb_16 >> 8;
    RGB->green = rgb_16 & 0xff;

    rgb_16 = rgb_16 >> 8;

    RGB->red = rgb_16 & 0xff;
}

void set_rgb(uint32_t rgb_24bit, uint8_t ligth_rank)
{
    RGB16for10(&WS2812_RGB, rgb_24bit);
    ligth_rank = 21 - ligth_rank;
    for (int i = 0; i < LED_STRIP_NUM; i++)
    {
        strip->set_pixel(strip, i, WS2812_RGB.red / ligth_rank, WS2812_RGB.green / ligth_rank, WS2812_RGB.blue / ligth_rank);
    }

    strip->refresh(strip, 10);
}

void init_led()
{
    rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_NUM, RMT_TX_CHANNEL);
    // set counter clock to 40MHz
    config.clk_div = 2;
    ESP_ERROR_CHECK(rmt_config(&config));
    ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));

    // install ws2812 driver
    led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(1, (led_strip_dev_t)config.channel);
    strip = led_strip_new_rmt_ws2812(&strip_config);
    if (!strip)
    {
        ESP_LOGE(TAG, "install WS2812 driver failed");
    }
    // Clear LED strip (turn off all LEDs)
    ESP_ERROR_CHECK(strip->clear(strip, 100));
    
}


static void log_error_if_nonzero(const char * message, int error_code)
{
    if (error_code != 0) {
        ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
    }
}

static int single_read(void *arg)
{
    int adc1_reading[1] = {0};
    adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_0);
    // vout = (adc1_reading[0] * 2500.00)/4095.00;
    // ESP_LOGI(TAG_CH[0], "%x vout mv is %f", adc1_reading[0],vout);
    return  adc1_reading[0];
}


static bool IRAM_ATTR system_timer_callback(void* arg)
{
    BaseType_t high_task_awoken = pdFALSE;
    send_cycle = true;
    return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR
}

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) {
        xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        esp_wifi_connect();
        xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
        ESP_LOGI(TAG2, "Scan done");
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
        ESP_LOGI(TAG2, "Found channel");
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
        ESP_LOGI(TAG2, "Got SSID and password");

        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
        wifi_config_t wifi_config;
        uint8_t ssid[33] = { 0 };
        uint8_t password[65] = { 0 };
        uint8_t rvd_data[33] = { 0 };

        bzero(&wifi_config, sizeof(wifi_config_t));
        memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
        memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
        wifi_config.sta.bssid_set = evt->bssid_set;
        if (wifi_config.sta.bssid_set == true) {
            memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
        }

        memcpy(ssid, evt->ssid, sizeof(evt->ssid));
        memcpy(password, evt->password, sizeof(evt->password));
        ESP_LOGI(TAG2, "SSID:%s", ssid);
        ESP_LOGI(TAG2, "PASSWORD:%s", password);
        if (evt->type == SC_TYPE_ESPTOUCH_V2) {
            ESP_ERROR_CHECK( esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)) );
            ESP_LOGI(TAG2, "RVD_DATA:");
            for (int i=0; i<33; i++) {
                printf("%02x ", rvd_data[i]);
            }
            printf("\n");
        }

        ESP_ERROR_CHECK( esp_wifi_disconnect() );
        ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
        printf("ready to connect!\r\n");
        esp_wifi_connect();
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
        xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
    }
}

static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    char cmdbuf[20];
    // your_context_t *context = event->context;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            // msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
            // ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, ONENET_TOPIC_DP_Sub, 0);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, ONENET_TOPIC_CMD_Sub, 1);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            // msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
            // ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            // esp_mqtt_client_start(client);
            break;

        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            // msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
            // ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
            
            sprintf(cmdbuf,"%.*s",event->data_len,event->data);
            if(strstr(cmdbuf, ":ledred")){
                xEventGroupSetBits(s_wifi_event_group, RED_BIT);
            }
            else if(strstr(cmdbuf, ":ledblue")){
                xEventGroupSetBits(s_wifi_event_group, BLUE_BIT);
            }
            break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
                log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
                log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
                log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
                ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));

            }
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
    return ESP_OK;
}

static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    mqtt_event_handler_cb(event_data);
}

static void mqtt_app_start(void)
{
    int msg_id;
    int adc_value;
    float adc_mv;
    /* ADC */
    adc1_config_width(ADC_WIDTH_BIT_DEFAULT);
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);
    /* */
    esp_mqtt_client_config_t mqtt_cfg = {
        // .uri = ONENET_MqttServer,
        .host = "mqtts.heclouds.com",
        // .uri = "mqtt://broker.emqx.io",
        .client_id = ONENET_clientld,
        .username = ONENET_UserName,
        .password = ONENET_Password,
        .port = 1883,
    };
#if CONFIG_BROKER_URL_FROM_STDIN
    char line[128];

    if (strcmp(mqtt_cfg.uri, "FROM_STDIN") == 0) {
        int count = 0;
        printf("Please enter url of mqtt broker\n");
        while (count < 128) {
            int c = fgetc(stdin);
            if (c == '\n') {
                line[count] = '\0';
                break;
            } else if (c > 0 && c < 127) {
                line[count] = c;
                ++count;
            }
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
        mqtt_cfg.uri = line;
        printf("Broker url: %s\n", line);
    } else {
        ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
        abort();
    }
#endif /* CONFIG_BROKER_URL_FROM_STDIN */

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
    esp_mqtt_client_start(client);

    // char *adc_head ="my adc value is:";
    // char *adc_tail ="mv";
    // char adc_publish[25] = {0};

    // int thread;
    float T,H;
    
    char jsonBuf[100];
    char databuf[80];

    while (1)
    {
        if(send_cycle){
            send_cycle = false;
            adc_value = single_read(NULL);
            adc_mv = (adc_value * 2500.00)/4095.00;
            
            SHT2X_THMeasure(I2C_MASTER_NUM);
            // if(thread == ESP_ERR_TIMEOUT){}
            // else{
                T =(getTemperature()/100.0);
                H =(getHumidity()/100.0);
                printf("this is my th test, %4.2f C\r\n%4.2f %%\r\n",T,H); 
            // }

            sprintf(databuf, "{ \"tem\":[{\"v\":%.2f}] ,\"hum\":[{\"v\":%.2f}] ,\"adc\":[{\"v\":%.2f}] }", T,H,adc_mv); 
            sprintf(jsonBuf, ONENET_POST_BODY_FORMAT, databuf);
            // sprintf(adc_publish,"%s %.2f %s",adc_head,adc_mv,adc_tail);
            msg_id = esp_mqtt_client_publish(client, ONENET_TOPIC_DP_Publish, jsonBuf , 0, 1, 0);
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
        }
        
        vTaskDelay(1);
    }
}


static void initialise_wifi(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    s_wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    /*
    just for test  ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
    esp_wifi_restore 使用需要在 esp_wifi_init 之后
    */
    // esp_wifi_restore();

    ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );

    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK( esp_wifi_start() );

    xTaskCreate(led_cmd_task, "led_cmd_task", 2048, NULL, 2, NULL);
}


/**
 * @brief Initialize selected timer of timer group
 *
 * @param group Timer Group number, index from 0
 * @param timer timer ID, index from 0
 * @param auto_reload whether auto-reload on alarm event
 * @param timer_interval_sec interval of alarm
 */
static void example_tg_timer_init(int group, int timer, bool auto_reload, int timer_interval_sec)
{
    /* Select and initialize basic parameters of the timer */
    timer_config_t config = {
        .divider = 16,
        .counter_dir = TIMER_COUNT_UP,
        .counter_en = TIMER_PAUSE,
        .alarm_en = TIMER_ALARM_EN,
        .auto_reload = auto_reload,
    }; // default clock source is APB
    timer_init(group, timer, &config);

    /* Timer's counter will initially start from value below.
       Also, if auto_reload is set, this value will be automatically reload on alarm */
    timer_set_counter_value(group, timer, 0);

    /* Configure the alarm value and the interrupt on alarm. */
    timer_set_alarm_value(group, timer, timer_interval_sec * (TIMER_BASE_CLK / 16));
    timer_enable_intr(group, timer);

    example_timer_info_t *timer_info = calloc(1, sizeof(example_timer_info_t));
    timer_info->timer_group = group;
    timer_info->timer_idx = timer;
    timer_info->auto_reload = auto_reload;
    timer_info->alarm_interval = timer_interval_sec;
    timer_isr_callback_add(group, timer, system_timer_callback, timer_info, 0);

    timer_start(group, timer);
}

static void smartconfig_example_task(void * parm)
{
    EventBits_t uxBits;

    wifi_config_t myconfig = {0};
    esp_wifi_get_config(ESP_IF_WIFI_STA,&myconfig);
    if(strlen((char *)myconfig.sta.ssid) > 0){      
        ESP_LOGI(TAG2, "already set SSID:%s,connect now!...",myconfig.sta.ssid);
        esp_wifi_connect();
    }else{
        ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH) );
        smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
        ESP_ERROR_CHECK( esp_smartconfig_start(&cfg) );
    }
 
    while (1) {
        uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
        if(uxBits & CONNECTED_BIT) {
            ESP_LOGI(TAG2, "WiFi Connected to ap");
            example_tg_timer_init(TIMER_GROUP_0, TIMER_0, true, 5);
            vTaskDelete(NULL);
        }
        if(uxBits & ESPTOUCH_DONE_BIT) {
            ESP_LOGI(TAG2, "smartconfig over");
            esp_smartconfig_stop();
            example_tg_timer_init(TIMER_GROUP_0, TIMER_0, true, 5);
            vTaskDelete(NULL);
        }
    }
}

static void led_cmd_task(void * parm)
{
    EventBits_t uxBits;
    while (1) {
        uxBits = xEventGroupWaitBits(s_wifi_event_group, RED_BIT | BLUE_BIT, true, false, portMAX_DELAY);
        if(uxBits & RED_BIT) {
            ESP_LOGI(TAG, "LED Turn RED"); 
            set_rgb(0x00FF00, WS2812_RGB.ligth_rank);         
        }
        if(uxBits & BLUE_BIT) {
            ESP_LOGI(TAG, "LED Turn BLUE");
            set_rgb(0X0000ff, WS2812_RGB.ligth_rank);
        }
        // set_rgb(0Xff0000, WS2812_RGB.ligth_rank);//绿色
        // set_rgb(0x00FF00, WS2812_RGB.ligth_rank); //红色
        // set_rgb(0X0000ff, WS2812_RGB.ligth_rank);//蓝色
        //set_rgb(0XF05308, WS2812_RGB.ligth_rank); //黄绿色
    }
}



void app_main(void)
{
    ESP_LOGI(TAG, "[APP] Startup..");
    ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
    ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());

    esp_log_level_set("*", ESP_LOG_INFO);
    esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);
    esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE);

    
    esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
    esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);

    

    ESP_ERROR_CHECK(nvs_flash_init());
    // ESP_ERROR_CHECK(esp_netif_init());
    // ESP_ERROR_CHECK(esp_event_loop_create_default());

    /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
     * Read "Establishing Wi-Fi or Ethernet Connection" section in
     * examples/protocols/README.md for more information about this function.
     */
    // ESP_ERROR_CHECK(example_connect());

    ESP_ERROR_CHECK(i2c_master_init());

    button_start();

    init_led();
       
    initialise_wifi();

    mqtt_app_start();
}
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
2月前
|
消息中间件 Java 测试技术
消息队列 MQ使用问题之数据流出规则是否支持平台的云RabbitMQ
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
3月前
|
消息中间件 存储 开发工具
消息队列 MQ产品使用合集之C++如何使用Paho MQTT库进行连接、发布和订阅消息
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2天前
|
消息中间件 监控 物联网
MQTT协议对接及RabbitMQ的使用记录
通过合理对接MQTT协议并利用RabbitMQ的强大功能,可以构建一个高效、可靠的消息通信系统。无论是物联网设备间的通信还是微服务架构下的服务间消息传递,MQTT和RabbitMQ的组合都提供了一个强有力的解决方案。在实际应用中,应根据具体需求和环境进行适当的配置和优化,以发挥出这两个技术的最大效能。
25 0
|
20天前
|
物联网 C# 智能硬件
智能家居新篇章:WPF与物联网的智慧碰撞——通过MQTT协议连接与控制智能设备,打造现代科技生活的完美体验
【8月更文挑战第31天】物联网(IoT)技术的发展使智能家居设备成为现代家庭的一部分。通过物联网,家用电器和传感器可以互联互通,实现远程控制和状态监测等功能。本文将探讨如何在Windows Presentation Foundation(WPF)应用中集成物联网技术,通过具体示例代码展示其实现过程。文章首先介绍了MQTT协议及其在智能家居中的应用,并详细描述了使用Wi-Fi连接方式的原因。随后,通过安装Paho MQTT客户端库并创建MQTT客户端实例,演示了如何编写一个简单的WPF应用程序来控制智能灯泡。
40 0
|
1月前
|
消息中间件 Arthas Java
RocketMQ—一次连接namesvr失败的案例分析
项目组在使用RocketMQ时遇到Consumer连接Name Server失败的问题,异常显示连接特定地址失败。通过Arthas工具逐步分析代码执行路径,定位到创建Channel返回空值导致异常。进一步跟踪发现,问题源于Netty组件在初始化`ByteBufAllocator`时出现错误。分析依赖后确认存在Netty版本冲突。解决方法为排除冲突的Netty包,仅保留兼容版本。
117 0
RocketMQ—一次连接namesvr失败的案例分析
|
30天前
|
物联网 网络性能优化 Python
"掌握MQTT协议,开启物联网通信新篇章——揭秘轻量级消息传输背后的力量!"
【8月更文挑战第21天】MQTT是一种轻量级的消息传输协议,以其低功耗、低带宽的特点在物联网和移动应用领域广泛应用。基于发布/订阅模型,MQTT支持三种服务质量级别,非常适合受限网络环境。本文详细阐述了MQTT的工作原理及特点,并提供了使用Python `paho-mqtt`库实现的发布与订阅示例代码,帮助读者快速掌握MQTT的应用技巧。
43 0
|
2月前
|
消息中间件 开发工具 RocketMQ
消息队列 MQ使用问题之一直连接master失败,是什么原因
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
消息中间件 Java 物联网
消息队列 MQ操作报错合集之建立连接时发生了超时错误,该如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
消息队列 MQ操作报错合集之建立连接时发生了超时错误,该如何解决
EMQ
|
2月前
|
传感器 人工智能 安全
EMQX 与 MQTT: AI 大模型时代的分布式数据中枢
在以数据为核心的 AI 时代,基于 MQTT 协议的消息服务器 EMQX 能帮助企业更好的利用人工智能和机器学习模型,是智能化系统中核心的数据基础软件。
EMQ
180 9
|
2月前
|
消息中间件 JavaScript Linux
消息队列 MQ操作报错合集之客户端在启动时遇到了连接错误,是什么原因
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。