文章内容:以“wifi版温湿度蓝牙网关”这一具体项目为载体,对《ESP32从0到1》专辑前面所有内容的整合练习。
本篇设定为VIP可见,未开通VIP的可移至如下链接,每个组件功能之前均有单独发布,且涉及到的源码也已上传,可自行下载。
项目定义
硬件:
USB 5V供电;
硬件开关按钮;
外部flash数据存储;
空气温湿度测量并显示;
蓝牙主机功能(最多接3个从机)
wifi通信(快速配网);
LED状态显示;
软件:
支持ESPTouch快速配网;
上电wifi自动联网;
定时测量空气温湿度;
支持配置蓝牙从机,实现指型号蓝牙从机连接,并将收到的数据打包以MQTT形式上报至MQTT服务器
支持离线数据保存,联网数据补充上报功能;
支持时钟自校正功能;
外观:
外形尺寸:长方体形状,尺寸尽量控制在 80mm*50mm*20mm以内;
用嘉立创EDA 3D功能配合PCB做简易外壳;
方案选择
主芯片方案选型,查找资料其ESP32各系列主要区别:
资料来源:https://www.cnblogs.com/FBsharl/p/18234798
ESP32各系列比对 | |
ESP32 | 搭载Xtensa® 双核 32位 LX6 微处理器,支持高达 240 MHz 的时钟频率,片内520 KB SRAM,还可外扩PSRAM。支持 802.11b/g/n,802.11n 数据速率高达 150 Mbps,支持蓝牙V4.2 BR/EDR 和蓝牙 LE 标准,支持RMII有线以太网、摄像头、SDIO、I2S、IR、UART、I2C、SPI、CAN、ADC、DAC、触摸、PWM 等多种外设。几经岁月沧桑,ESP32依旧是乐鑫WIFI芯片中,能量产使用的性能翘楚。大哥的位置坐了好几年,S3也要来接它的班了,不过凭借以前积累的丰富代码资源,其未来依旧长青。 |
ESP32-S2 | 砍掉了蓝牙,导致其很难应用在连接手机和蓝牙的场合。且SRAM较小,很多时候要扩展PSRAM使用。(哭了,S2砍内核也就砍了,单核240MHz也不差,偏偏还带着SRAM也来一刀。美名其曰降低成本替换ESP8266,结果紧接着发布了C3。这下替换ESP8266的任务全都靠C3了,S2出道即退圈。蓝牙、以太网、CAN统统被砍,导致S2的定位及其尴尬,全靠USB和多出的IO撑门面。) |
ESP32-C3 | 价格美丽,性能尚可,搭载 RISC-V 32 位单核处理器,时钟频率高达 160 MHz,支持 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE)。虽然其内部的SRAM空间比ESP32小,但实际的用户可用堆栈容量较ESP32相差无几,详见:ESP32 与 ESP32-C3 可用存储空间对比。IO较少,不能扩展PSRAM。另外比较新,SDK待完善。 |
ESP32-S3 | 并没有带来太多的惊喜,或者说S3才应该是S2本来的样子,而不是现在的四不像S2。ESP32-S3 搭载 Xtensa® 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM。加入了用于加速神经网络计算和信号处理等工作的向量指令,性能对比ESP32有可观的提升。集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE),拥有 45 个可编程 GPIO,外设新增LCD接口、USB。因为太新了,现在在售的只有样板,SDK支持不全,价格不明,观望。 |
通过以上简述,能大概了解ESP32目前在售的产品线。现阶段,从学习资源上讲,推荐 ESP32入手。考虑量产成本,推荐 ESP32-C3 ,不过目前 ESP32-C3 的SDK没那么完善,更多的问题需要联系FAE。 | |
ESP32模组封装差异 | |
WROOM | 内置Flash,主要有板载天线和IPEX外置天线(U)两个版本 |
WROVER | 内置Flash、8MB-PSRAM,PCB有焊接IPEX和不焊接IPEX两个版本 |
与ESP32-WROOM的封装相比,WROVER兼容大部分引脚。不同之处在于WROVER将WROOM的底部引脚,从中分两列均匀放置到了两侧,而因为内置了PSRAM,所以PSRAM的IO位为NC |
本项目使用外设较少,主要功能就是wifi+蓝牙因此配置上不需要很高。
选型工具:https://products.espressif.com/#/product-selector?language=zh&names=
符合wifi+蓝牙+ipex天线+价格20元附近的模块有:
型号 | 价格(元) |
ESP32-C3-MINI-1U-N4 | 16 |
ESP32-C3-WROOM-02U-N4 | 17.5 |
ESP32-WROOM-32UE-N4 | 18.8 |
ESP32-MINI-1U-N4 | 18 |
ESP32-S3-WROOM-1U-N4 | 23 |
ESP32-S3-MINI-1U | 24 |
ESP32-C6-WROOM-1U-N4 | 22.5 |
ESP32-C6-MINI-1U-N4 | 21.5 |
ESP8684-WROOM-02UC-N4 | 16 |
考虑从学习资源丰富的角度,最终确定选择“ESP32-WROOM-32UE”,与本专辑一直用的开发板所用模组“ESP32-WROVER-E”主要区别是天线、封装以及管脚外设上,因此本专辑所有程序可直接使用。
模块图
线路图
BOM清单(测试用,电池及充电部分NC未安装)
外观
软件调试
1、实现数码管显示功能,验证样品板基本功能
内容:直接复制使用“《ESP32从0到1》之数码管显示(TM1640)”程序,根据新线路图修改程序,实现两个3位数码管的数据显示。为后面显示空气温湿度功能做准备。
https://download.csdn.net/download/u013534357/89874169《ESP32从0到1》之数码管显示(TM1640)_tm1640程序-CSDN博客
● 根据线路图修改管脚定义。
//GPIO管脚号
#define DIO 5
#define CLK 17
● 当前设计只有两个3位数码管,根据TM1640的"显示数据、地址、芯片管脚之间的对应关系"可确定3位段码管显存地址起始分别0xC0H和0xC3H,对应修改程序。
//数码管显存地址//显示模块一共2个数码管,2个小数码管3位地址0xc0和0xc3
#define _3DigLED1Addr 0xC0
#define _3DigLED2Addr 0xC3
#define _3DigLED1DataLen 3
#define _3DigLED2DataLen 3
#define maxDigLen 3//最大数码管位数
#define _3DigLED1DataPoint 1
#define _3DigLED2DataPoint 1
//按顺序存储3位显示管1,3位显示管2
uint8_t ledgroupaddr[]={_3DigLED1Addr,_3DigLED2Addr};
uint8_t ledgrouplen[]={_3DigLED1DataLen,_3DigLED2DataLen};
//小数点位置
uint8_t ledgrouppoint[]={_3DigLED1DataPoint,_3DigLED2DataPoint};//都在第二位上带小数点
● ClearAllShow清屏函数需要对应修改循环次数,当前两个3位的数码管,循环次数改为6。修改ShowMearData函数,去掉之前关于4位数码管部分程序。
● app_main函数中,修改测试函数
void app_main(void)
{
InitLED();//初始化LED
ShowMearData(0,(12.3*10));
ShowMearData(1,(45.6*10));
while(1)
{
printf("hello\n");
// Add your main loop handling code here.
}
}
● 运行结果
2、创建BLE-Wifi-Gateway工程
内容:直接复制使用“《ESP32从0到1》之MQTT与阿里iot通信”的tcp工程,修改工程名称为“BLE-Wifi-Gateway”。实现LED状态显示功能:联网成功LED常亮,发送数据时闪烁。备注:为了方便调试,最终MQTT数据发送至自有MQTT服务器,数据包内容为测量时间、测量数据。
《ESP32从0到1》之MQTT与阿里iot通信(上)_esp32 mqtt-CSDN博客
《ESP32从0到1》之MQTT与阿里iot通信(中)_esp32 mqtt例程-CSDN博客
● 添加LED相关宏定义,主函数中增加GPIO口初始化程序;
/************************LED指示灯相关定义***************** */
#define ledlight 27
#define ledlight_ON gpio_set_level(ledlight,1)
#define ledlight_OFF gpio_set_level(ledlight,0)
/********************************************************* */
//初始化LED管脚
gpio_reset_pin(ledlight);
gpio_set_direction(ledlight, GPIO_MODE_OUTPUT);//配置为输出模式
gpio_set_pull_mode(ledlight, GPIO_PULLUP_ONLY);//配置上拉
//默认为低电平
gpio_set_level(ledlight,1);
● wifi连接成功事件中增加亮灯程序(wifi_event_handler);
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { //表示联网成功
ledlight_ON;
if(wifi_nvs_flash_flg!=1)//未保存过ssid和password
{
xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
//保存正确联网的ssid和password
writeWifiConfig(ssid,sizeof(ssid),password,sizeof(password));
}
else
{
ESP_LOGI(TAG, "own IP_EVENT_STA_GOT_IP");
}
mqtt_app_start();
● MQTT数据发送部分增加灯闪程序。如果直接在esp_mqtt_client_publish函数前后操作灯的开关,因执行时间较短,无法肉眼看到灯的明显变化。调整程序如下,实现1s间隔的亮灭操作;
uint8_t ledinvert=0;
// 当循环执行计时器到期事件时执行的处理程序。
//此处理程序跟踪计时器过期的次数。当达到设定的到期次数时,处理程序会停止计时器并发送计时器停止事件。
static void timer_expiry_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
{
static int count = 0;
count++;
if(ledinvert==1)//用于切换发送时LED灯的亮灭
{
ledinvert=0;
ledlight_ON;
}
if (count >= TIMER_EXPIRIES_COUNT_10s) {
count=0;
ledlight_OFF; //发送数据时灭灯,发送完成后亮灯,以实现发送数据时灯闪的功能
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);
ledinvert=1;
}
ESP_LOGI(TAG, "TIMER_EVENTS:TIMER_EVENT_EXPIRY: timer_expiry_handler, executed %d out of %d times", count, TIMER_EXPIRIES_COUNT_10s);
}
3、移植蓝牙主机程序
内容:基于“《ESP32从0到1》之蓝牙一对多主机”移植程序,实现与指定型号的蓝牙从机模块通信,并提取数据上报至阿里iot平台。
《ESP32从0到1》之:蓝牙一对多主机(上)_esp32gatt-CSDN博客
《ESP32从0到1》之:蓝牙一对多主机(下)_esp32蓝牙-CSDN博客
● 在项目文件夹下新建"components"文件夹,"gattc_multi_connect"子文件夹。子文件夹中新建2个文件"CMakeLists.txt"和"gattc_multi_connect.h",将“《ESP32从0到1》之蓝牙一对多主机”程序中的"gattc_multi_connect.c"文件复制到子文件夹中,如下图所示。
● 单击打开新建的"CMakeLists.txt"文件,填充内容:
idf_component_register(SRCS "gattc_multi_connect.c"
INCLUDE_DIRS "."
REQUIRES bt)
● 修改gattc_multi_connect.c,将该c文件里的app_main改成BLECentralInit(),去掉关于nvsflash相关的初始化部分程序。
● 打开"gattc_multi_connect.h"头文件,填充内容如下:
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void BLECentralInit(void);
#ifdef __cplusplus
}
#endif
● 在"gattc_multi_connect.c"及"app_main.c"中包含"gattc_multi_connect.h"头文件,主函数中添加"BLECentralInit()"
● 编译烧录运行,打开测试用蓝牙从机模块,可连接成功,并定时收到上报的数据
● 补充说明:测试程序会发现扫描蓝牙的操作只持续了几十秒,几十秒之后不再 进行蓝牙从机的扫描。程序中start_scan函数设定了扫描时间,可在此进行修改。
//启动扫描函数
static void start_scan(void)
{
stop_scan_done = false;//初始化变量
Isconnecting = false;//初始化变量
uint32_t duration = 30;//持续扫描时间30s
esp_ble_gap_start_scanning(duration);//此过程使设备持续扫描正在广播的设备
}
4、以MQTT格式上报蓝牙从机上报的数据
内容:之前为了测试程序是每10s上报一次MQTT数据(上报的也是测试数据), 修改程序,将收到的从机上报数据打包上报。
● 先去掉“timer_expiry_handler”事件处理中的程序,留一个定时框架(后面用得着)
static void timer_expiry_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
{
static int count = 0;
count++;
if (count >= TIMER_EXPIRIES_COUNT_10s) {
count=0;
}
ESP_LOGI(TAG, "TIMER_EVENTS:TIMER_EVENT_EXPIRY: timer_expiry_handler, executed %d out of %d times", count, TIMER_EXPIRIES_COUNT_10s);
}
● 将收到的数据打包进行MQTT上报
程序中支持3个从机连接,因此有3个对应的事件处理函数gattc_profile_(a/b/c)_event_handler,在ESP_GATTC_NOTIFY_EVT事件中,进行数据打包。
case ESP_GATTC_NOTIFY_EVT://收到notification或者indication时触发该事件
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify len:%d,value: ", p_data->notify.value_len);
esp_log_buffer_hex(GATTC_TAG, p_data->notify.remote_bda, 6);//打印mac地址
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);//收到的内容stringhex打印出来
if(MQTTConnected==1)//定义的公共变量,MQTT连接成功时置1
{
//连接字符串,直接将数据转换成hex字符串
char revhex[p_data->notify.value_len*2];
for (int i = 0; i < p_data->notify.value_len; i ++) {
sprintf(revhex + 2 * i, "%02x ", p_data->notify.value[i]);
}
msg_id = esp_mqtt_client_publish(client,"/topic/qos1",revhex,0,1,0);
ESP_LOGI(GATTC_TAG, "sent publish successful, msg_id=%d", msg_id);
}
break;
● 整合成Json格式进行上报(有专门的json组件可供调用,但因为程序中只进行了数据打包,并不需要解析,因此直接用sprintf就可以实现json数据打包)
case ESP_GATTC_NOTIFY_EVT://收到notification或者indication时触发该事件
ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify len:%d,value: ", p_data->notify.value_len);
esp_log_buffer_hex(GATTC_TAG, p_data->notify.remote_bda, 6);//打印mac地址
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);//收到的内容stringhex打印出来
//发布主题
if(MQTTConnected==1)//定义的公共变量,MQTT连接成功时置1
{
//连接字符串,直接将数据转换成hex字符串
char revhex[p_data->notify.value_len*2];
char revmac[6*3];//用:间隔
char Jsonpayload[p_data->notify.value_len*2+41+1];//{"MAC":"XX:XX:XX:XX:XX:XX","Meardata": "0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c"}
for (int i = 0; i < 6; i ++) {
if(i==5)
{
sprintf(revmac + 3 * i, "%02x", p_data->notify.remote_bda[i]);
}
else
{
sprintf(revmac + 3 * i, "%02x:", p_data->notify.remote_bda[i]);
}
}
for (int i = 0; i < p_data->notify.value_len; i ++) {
sprintf(revhex + 2 * i, "%02x", p_data->notify.value[i]);
}
sprintf(Jsonpayload,"{\"MAC\": \"%s\",\"Meardata\": \"%s\"}",revmac,revhex);
msg_id = esp_mqtt_client_publish(client,"/topic/qos1",Jsonpayload,0,1,0);
ESP_LOGI(GATTC_TAG, "sent publish successful, msg_id=%d", msg_id);
}
break;
5、移植外部flash程序
内容:基于“《ESP32从0到1》之SPI Flash数据保存”移植部分程序,当MQTT连接成功时发布数据,若MQTT未连接则数据暂存至外部flash中。待MQTT连接成功后进行数据补发。
● 直接将hd_flash程序components文件夹下的子文件夹复制到当前项目的文件夹components下。
● "CMakeLists.txt"文件内容如下:
idf_component_register(SRCS "spi_flash.c"
INCLUDE_DIRS "."
REQUIRES driver)
● 根据线路图确认管脚配置
● 新增flash初始化函数
esp_err_t UserInitSPIFlash(flash_handle_t* flash_handle)
{
esp_err_t ret;
#ifndef CONFIG_EXAMPLE_USE_SPI1_PINS
ESP_LOGI(TAG, "Initializing bus SPI%d...", flash_HOST + 1);
spi_bus_config_t buscfg = {
.miso_io_num = PIN_NUM_MISO,
.mosi_io_num = PIN_NUM_MOSI,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,//没有硬件上的WP pin
.quadhd_io_num = -1,//没有硬件上的hold pin
.max_transfer_sz = 4096,//最大传输32字节
.flags = SPICOMMON_BUSFLAG_MASTER,
};
//Initialize the SPI bus
ret = spi_bus_initialize(flash_HOST, &buscfg, SPI_DMA_CH_AUTO);
ESP_ERROR_CHECK(ret);
#else
ESP_LOGI(TAG, "Attach to main flash bus...");
#endif
flash_config_t flash_config = {
.cs_io = PIN_NUM_CS,
.host = flash_HOST,
.miso_io = PIN_NUM_MISO,
};
#ifdef CONFIG_EXAMPLE_INTR_USED
flash_config.intr_used = true;
gpio_install_isr_service(0);
#endif
ESP_LOGI(TAG, "Initializing device...");
ret = spi_flash_init(&flash_config, flash_handle);
ESP_ERROR_CHECK(ret);
return ret;
}
● 程序新建一个公共变量用于记录保存多少组数据没有发送至MQTT服务器(即历史数据),MQTT连接成功后启动计时器,每秒判断一次并发送一组历史数据至MQTT服务器。收到蓝牙从机数据时若MQTT没有连接成功则保存至flash。
6、移植I2C程序,实现与AHT20通信并数码显示
内容:基于“《ESP32从0到1》之IIC与AHT20”以及"《ESP32从0到1》之数码管显示(TM1640)"移植部分程序,定时获取AHT20温湿度数据,并将数据显示在数码管上,保留小数位1点。
● 仿照步骤3将AHT20作为外部组件移植到components文件夹下
● 将AHT20.c的“app_main”改成"void ReadAHT20Data(float* temp,float* humi)"
7、移植数码显示程序
内容:实现AHT20定时读取数据,定时显示在数码管上
● 仿照步骤5将soft_2wire_master作为外部组件移植到components文件夹下,步骤1中已经修改了.c/.h文档。主函数中包含调用即可
8、定时获取网络时间
内容:上报数据包中增加日期时间,为确保时间的准确,定时获取网络时间并校正。
● 在components文件夹中添加sntp子文件夹。右击sntp添加sntp.c、sntp.h和CMakeLists.txt文件。如下图所示:
● 可通过menuconfig设置sntp服务器最大值为3,表示支持3个服务器轮流连接获取网络时间。
● 基于sample 的sntp示例工程,移植相关程序到sntp.c
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif_sntp.h"
#include "esp_sntp.h"
#include "sntpsync.h"
static const char *TAG = "sntpsync";
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 48
#endif
void time_sync_notification_cb(struct timeval *tv)
{
ESP_LOGI(TAG, "Notification of a time synchronization event");
}
static void print_servers(void)
{
ESP_LOGI(TAG, "List of configured NTP servers:");
for (uint8_t i = 0; i < SNTP_MAX_SERVERS; ++i){
if (esp_sntp_getservername(i)){
ESP_LOGI(TAG, "server %d: %s", i, esp_sntp_getservername(i));
} else {
// we have either IPv4 or IPv6 address, let's print it
char buff[INET6_ADDRSTRLEN];
ip_addr_t const *ip = esp_sntp_getserver(i);
if (ipaddr_ntoa_r(ip, buff, INET6_ADDRSTRLEN) != NULL)
ESP_LOGI(TAG, "server %d: %s", i, buff);
}
}
}
void obtain_time(void)
{
ESP_LOGI(TAG, "Initializing and starting SNTP");
#if CONFIG_LWIP_SNTP_MAX_SERVERS > 1
/* This demonstrates configuring more than one server
*/
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG_MULTIPLE(CONFIG_LWIP_SNTP_MAX_SERVERS,
ESP_SNTP_SERVER_LIST("ntp1.aliyun.com" , "pool.ntp.org" ,"210.72.145.44") );
#else
/*
* This is the basic default config with one server and starting the service
*/
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org" );
#endif
config.sync_cb = time_sync_notification_cb; // Note: This is only needed if we want
esp_netif_sntp_init(&config);
print_servers();
// wait for time to be set
time_t now = 0;
struct tm timeinfo = { 0 };
int retry = 0;
const int retry_count = 15;
while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) == ESP_ERR_TIMEOUT && ++retry < retry_count) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
}
time(&now);
localtime_r(&now, &timeinfo);
ESP_LOGI(TAG, "set china timezone..");
// set timezone to China Standard Time
setenv("TZ", "CST-8", 1);
tzset();
strftime(strftime_buf, sizeof(strftime_buf), "%F %T", &timeinfo);
ESP_LOGI(TAG, "The current date/time in Shanghai is: %s", strftime_buf);
esp_netif_sntp_deinit();
}
● wifi连接成功后就调用一次obtain_time,后定时每小时调用一次obtain_time获取网络时间并校正。
● 运行如下所示:
● 修改程序,数据上报部分增加时间的上报。
if(MQTTConnected==1)
{
//获取当前的时间
time_t now = 0;
struct tm timeinfo = { 0 };
char revTime[20];
time(&now);
localtime_r(&now, &timeinfo);
setenv("TZ", "CST-8", 1);
tzset();
strftime(revTime, sizeof(revTime), "%F %T", &timeinfo);
ESP_LOGI(GATTC_TAG, "revTime:%s", revTime);
//连接字符串,直接将数据转换成hex字符串
char revhex[p_data->notify.value_len*2];
char revmac[6*3];//用:间隔
char Jsonpayload[200];//[p_data->notify.value_len*2+41+1+30];//{"MAC":"XX:XX:XX:XX:XX:XX","Meardata": "0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c"}
for (int i = 0; i < 6; i ++) {
if(i==5)
{
snprintf(revmac + 3 * i,18, "%02x", p_data->notify.remote_bda[i]);
}
else
{
snprintf(revmac + 3 * i,18, "%02x:", p_data->notify.remote_bda[i]);
}
}
ESP_LOGI(GATTC_TAG, "revmac:%s", revmac);
for (int i = 0; i < p_data->notify.value_len; i ++) {
snprintf(revhex + 2 * i,(p_data->notify).value_len * 2, "%02x", p_data->notify.value[i]);
}
ESP_LOGI(GATTC_TAG, "revhex:%s", revhex);
snprintf(Jsonpayload,200,"{\"MAC\":\"%s\",\"Meardata\": \"%s\",\"Time\":\"%s\"}",revmac,revhex,revTime);
msg_id = esp_mqtt_client_publish(client,"/topic/qos1",Jsonpayload,0,1,0);
ESP_LOGI(GATTC_TAG, "sent publish successful, msg_id=%d", msg_id);
}
结语
至此,项目定义的软件功能均已实现,因该项目涉及到实际公司正在开发的产品,更多的优化细节就不再更新,友友们可以自行优化。后续有机会会在新的试验性项目中进行并发布。
当前程序主要实现初始的调试功能,后续需要进一步优化的内容如下:
1)3个蓝牙从机是指定的同一个型号产品,所有参数均是相同的,事务处理程序可以合并;
2)程序中很多逻辑功能实现是通过公共变量进行的,实际上可以优化成事件处理。
3)MQTT连接成功、MQTT断开、Wifi连接成功、Wifi断开相应的逻辑均需要优化。
4)发送实时数据和发送历史数据至MQTT服务器,发送程序可以优化合并成一个函数。
5)MQTT数据上报时增加了时间的上报,但是历史数据保存时并没有保存时间,这块功能需要按照实际需求进行优化.时间上报可直接上报时间戳。当前为了调试查看方便转换成了string常见日期时间格式。
6)wifi和MQTT可以独立成两个组件
7)bug优化
程序已上传至微信公众号IT搬砖客,可免费下载。
🌹欢迎关注、订阅、收藏🌹
文章中有不清晰或者有疑问、错误的地方,请务必留言提醒、讨论。非常感谢!!!