meiyao

  • 2024-12-16
  • 加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 IMU功能演示与方向讲解-ARDUINO NANO RP2040 CONNECT

  • 加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 Blink RGB与UART功能演示-ARDUINO NANO RP2040 CONNECT

  • 2024-12-15
  • 加入了学习《【Follow me第二季第3期】》,观看 【Follow me第二季第3期】进阶任务:示例程序中新增命令打印信息

  • 2024-12-13
  • 加入了学习《【Follow me第二季第3期】任务汇总》,观看 【Follow me第二季第3期】任务汇总

  • 2024-12-12
  • 加入了学习《Follow me 第二季第3期成果视频》,观看 成果展示

  • 2024-12-10
  • 加入了学习《【Follow me第二季第1期】+ CPE基于VS-CODE PIO的都功能挂饰开发》,观看 【Follow me第二季第1期】+ CPE基于VS-CODE PIO的都功能挂饰开发

  • 回复了主题帖: 今天下午两点直播STM32全球线上峰会,STM32N6重磅发布,快来直播间【抽开发板】啦!

     

  • 2024-12-07
  • 加入了学习《FollowMe 第二季:3 - EK_RA6M5 开发板入门》,观看 EK-RA6M5 开发板入门

  • 2024-12-05
  • 评论了课程: 【2024 DigiKey 应用说】第三期:大模型时代的智能汽车

    感谢分享大模型车端部署技术、生成式AI对汽车电子设计的交互革命、沉浸式交互可能性及自动驾驶核心技术视频,我对这个又有了深层次的理解与认识。

  • 2024-11-06
  • 上传了资料: 2024 DigiKey 创意大赛

  • 2024-11-05
  • 发表了主题帖: 【2024 DigiKey 创意大赛】+总结

    基于ESP32-S3和rp2040双核心的智能温湿度显示系统 作者:meiyao 一、作品简介   本项目是利用自己设计一款功能强大的PCB扩展板,与现有的Espressif(乐鑫)ESP32-S3-LCD-EV-Board触摸屏显示评估板相连接,实现温湿度数据显示、数据存储等实用功能。使用软件部分将基于ESP32-S3和rp2040双核心进行通信开发,其中ESP32-S3作为主核心负责LVGL用户交互界面的运行和显示,而rp2040作为副核心则负责温湿度数据的采集、处理以及与主核心的两者之间通信,并实时的显示在屏上,而且也在PC端进行数据打印,使用LVGL界面显示时间,目前采集的数据等功能。   二、系统框图   硬件连接示意图:   硬件示意图上面是分两个板,一个是Espressif(乐鑫)ESP32-S3-LCD-EV-Board触摸屏显示评估板,一个是自己设计的PICO转接板。   Espressif(乐鑫)ESP32-S3-LCD-EV-Board触摸屏显示评估板相连接,实现温湿度数据显示、数据存储等实用功能。采用rp2040副核心,Bosch的BME280传感器,为用户提供便捷的数据传输和实时环境监测功能。 下面请看软件流程图:       工作流程图描述 将PCB扩展板与ESP32-S3-LCD-EV-Board触摸屏显示评估板相连接。 连接rp2040副核心板,确保通信接口(UART)正确连接。 软件初始化 在ESP32-S3主核心上安装并配置LVGL(Light and Versatile Graphics Library)以支持用户交互界面。 在rp2040副核心上编写并安装温湿度数据采集和处理程序。 配置主核心和副核心之间的通信协议(UART通信)。 温湿度数据采集 副核心(rp2040)启动温湿度传感器,开始数据采集。 副核心处理采集到的温湿度数据,可能包括数据滤波、校准等处理步骤。 数据通信 副核心将处理后的温湿度数据通过预定义的通信协议发送给主核心(ESP32-S3)。 数据显示 主核心使用LVGL在触摸屏上显示温湿度数据。 显示界面可能包括当前温湿度值、时间等。 数据打印(PC端) 主核心通过串口通信或其他方式将温湿度数据发送到PC端。 实时监控与反馈 系统持续监控温湿度数据的变化。 如果数据超出预设范围,系统可以通过用户界面提供警告或报警信息。 结束     三、各部分功能说明   硬件部分 ESP32-S3-LCD-EV-Board是一款功能强大的触摸屏显示评估板,使用的是ESP32-S3芯片设计。具备双核CPU和强大的AI算力,为屏幕方案带来灵敏的触控体验、流畅的GUI响应,以及高性能的离、在线人机语音交互功能。支持IIC、SPI、UART、8080等多种接口类型,能够驱动多种分辨率和接口的LCD显示屏,满足用户对不同触摸屏应用产品的开发需求。配备了一块480×480分辨率的触摸屏,能够清晰地显示图像和文本信息,方便用户进行交互操作。   PICO与BMP280: BMP280传感器通常通过I²C接口与副板PICO进行连接,这个是自己设计的板了,已经集成在下图紫色的板上。 在连接时,需要确保BMP280的VCC、GND、SCL(时钟线)、SDA(数据线)等引脚与副板PICO的相应引脚正确对接。为什么要提出来,因为这个东西蛮小,而且很容易弄错方向,但不好处理的是不好焊接。 PICO是最小系统核心板,使用排针进行板载对接。         PICO与ESP32 S3通信上PC端输出的数据: 屏幕上实际输出画面:   四、作品源码 界面设计: 利用LVGL(Light and Versatile Graphics Library)库,设计直观、易用的用户交互界面,界面应包含温湿度数据显示区域、数据刷新按钮。 数据更新与显示: 编写程序,使ESP32-S3主核心能够实时接收来自rp2040副核心的温湿度数据。 利用LVGL库中的图表或标签等控件,将接收到的数据动态显示在界面上。 实现数据刷新功能,用户点击刷新按钮时,界面将更新显示最新的温湿度数据。 LVGL用户交互界面实现: static lv_disp_t *display_init(ESP_PanelLcd *lcd) { ESP_PANEL_CHECK_FALSE_RET(lcd != nullptr, nullptr, "Invalid LCD device"); ESP_PANEL_CHECK_FALSE_RET(lcd->getHandle() != nullptr, nullptr, "LCD device is not initialized"); static lv_disp_draw_buf_t disp_buf; static lv_disp_drv_t disp_drv; // Alloc draw buffers used by LVGL void *buf[LVGL_PORT_BUFFER_NUM_MAX] = { nullptr }; int buffer_size = 0; ESP_LOGD(TAG, "Malloc memory for LVGL buffer"); #if !LVGL_PORT_AVOID_TEAR // Avoid tearing function is disabled buffer_size = LVGL_PORT_BUFFER_SIZE; for (int i = 0; (i < LVGL_PORT_BUFFER_NUM) && (i < LVGL_PORT_BUFFER_NUM_MAX); i++) { buf[i] = heap_caps_malloc(buffer_size * sizeof(lv_color_t), LVGL_PORT_BUFFER_MALLOC_CAPS); assert(buf[i]); ESP_LOGD(TAG, "Buffer[%d] address: %p, size: %d", i, buf[i], buffer_size * sizeof(lv_color_t)); } 温湿度数据采集与处理 传感器初始化与配置: 在rp2040副核心上编写代码,初始化BME280传感器,并配置其采集模式和采样率等参数。 数据采集与传输: 编写数据采集循环,使rp2040能够定期从BME280传感器读取温湿度数据。 实现数据通信协议,将采集到的数据通过UART、SPI等通信接口发送给ESP32-S3主核心。   温湿度数据采集与处理 Serial.begin(115200); while(!Serial); // time to get serial running Serial.println(F("BME280 test")); unsigned status; status = bme.begin(); if (!status) { Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!"); Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16); Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n"); Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n"); Serial.print(" ID of 0x60 represents a BME 280.\n"); Serial.print(" ID of 0x61 represents a BME 680.\n"); while (1) delay(10); if (isnan(temperature) || isnan(humidity)) { // 如果读取失败,则通过串口输出错误信息 Serial.println("Failed to read from BME280 sensor!"); } else { // 如果温度和湿度数据读取成功,则执行以下操作 // 创建一个静态JSON文档对象,分配200字节的内存空间 // 用于存储JSON格式的数据 StaticJsonDocument<200> doc; // 向JSON文档中添加温度数据 doc["temperature"] = temperature; // 向JSON文档中添加湿度数据 doc["humidity"] = humidity; // 假设pressure和altitude变量已经通过某种方式获取(例如从BME280传感器) // 向JSON文档中添加气压数据 doc["pressure"] = pressure; // 向JSON文档中添加海拔数据(注意:BME280传感器本身不提供海拔数据, // 这里可能是通过其他方式计算或获取的) doc["altitude"] = altitude; // 创建一个字符串对象,用于存储序列化后的JSON数据 String jsonString; // 使用serializeJson函数将JSON文档序列化为字符串 // 并存储在jsonString变量中 serializeJson(doc, jsonString); // 通过串口输出序列化后的JSON字符串(通常用于调试) Serial.println(jsonString); // 通过Serial1串口输出序列化后的JSON字符串 // 这可能用于将数据发送到其他设备或系统 Serial1.println(jsonString); } 显示地理位置代码: String cityCode = "66666"; // 查看你的 城市代码 String userKey = "66666"; // 要去注册一个高德地图的开发用户 esp-bsp 库,使用 VSCode 打开 esp-bsp 文件夹, bsp/esp32_s3_eye/esp32_s3_eye.c 文件, bsp_display_lcd_init()函数,下代码所示: static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) { assert(cfg != NULL); esp_lcd_panel_io_handle_t io_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL; const bsp_display_config_t bsp_disp_cfg = { .max_transfer_sz = BSP_LCD_DRAW_BUFF_SIZE * sizeof(uint16_t), }; BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new(&bsp_disp_cfg, &panel_handle, &io_handle)); #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) esp_lcd_panel_disp_off(panel_handle, false); #else esp_lcd_panel_disp_on_off(panel_handle, true); #endif /* Add LCD screen */ ESP_LOGD(TAG, "Add LCD screen"); const lvgl_port_display_cfg_t disp_cfg = { .io_handle = io_handle, .panel_handle = panel_handle, .buffer_size = cfg->buffer_size, .double_buffer = cfg->double_buffer, .hres = BSP_LCD_H_RES, .vres = BSP_LCD_V_RES, .monochrome = false, /* Rotation values must be same as used in esp_lcd for initial settings of the screen */ .rotation = { .swap_xy = false, .mirror_x = false, .mirror_y = false, }, .flags = { .buff_dma = cfg->flags.buff_dma, .buff_spiram = cfg->flags.buff_spiram, #if LVGL_VERSION_MAJOR >= 9 .swap_bytes = (BSP_LCD_BIGENDIAN ? true : false), #endif } }; return lvgl_port_add_disp(&disp_cfg); } // 显示屏初始化函数 lv_disp_t* initialize_display(const bsp_display_cfg_t* cfg) { // 使用esp-bsp库初始化LCD显示屏的代码 // ... // 返回LVGL显示屏句柄 } // 温湿度数据采集与处理函数 void read_and_process_sensor_data() { // 初始化串口和BME280传感器 // ... // 读取温度和湿度数据 // ... // 处理数据(例如,创建JSON文档并输出) // ... } // 主函数或其他调用点 void setup() { // 初始化显示屏 lv_disp_t* disp = initialize_display(/* 配置参数 */); // 读取并处理传感器数据 read_and_process_sensor_data(); // 其他初始化代码... }     五、作品功能演示视频 视频: [localvideo]5fa65f99896cae6117497e83aa643c75[/localvideo] [localvideo]652e1cb2367ebe39bafaef6c09ca39e7[/localvideo] 文档: 原码: https://download.eeworld.com.cn/detail/meiyao/634898 【2024 DigiKey 创意大赛】+功能 https://bbs.eeworld.com.cn/thread-1298153-1-1.html 【2024 DigiKey 创意大赛】+硬件准备 https://bbs.eeworld.com.cn/thread-1298135-1-1.html   总结: 一个基于ESP32-S3和rp2040双核心的智能温湿度显示系统。硬件部分通过连接BME280传感器实现数据采集,软件部分则利用LVGL库设计用户交互界面,并实时显示温湿度数据。ESP32-S3作为主核心负责界面运行与数据显示,而rp2040则负责数据采集与传输。项目关键工作包括界面设计、数据更新与显示、LVGL用户交互界面实现以及温湿度数据采集与处理。通过此系统,用户可直观获取当前环境的温湿度信息。        

  • 2024-11-03
  • 发表了主题帖: 【2024 DigiKey 创意大赛】+功能

    本帖最后由 meiyao 于 2024-11-5 23:20 编辑 项目概述和主要工作内容,以下是对项目的详细分析: 针对您提出的项目,以下是对软件规划部分的详细阐述,包括LVGL用户交互界面的实现等关键内容:   一、硬件连接示意图:     二、软件架构概述 软件部分将基于ESP32-S3和rp2040双核心进行开发,其中ESP32-S3作为主核心负责LVGL用户交互界面的运行和显示,而rp2040作为副核心则负责温湿度数据的采集、处理以及与主核心的通信。   界面设计: 利用LVGL(Light and Versatile Graphics Library)库,设计直观、易用的用户交互界面,界面应包含温湿度数据显示区域、数据刷新按钮。 数据更新与显示: 编写程序,使ESP32-S3主核心能够实时接收来自rp2040副核心的温湿度数据。 利用LVGL库中的图表或标签等控件,将接收到的数据动态显示在界面上。 实现数据刷新功能,用户点击刷新按钮时,界面将更新显示最新的温湿度数据。   LVGL用户交互界面实现: static lv_disp_t *display_init(ESP_PanelLcd *lcd) { ESP_PANEL_CHECK_FALSE_RET(lcd != nullptr, nullptr, "Invalid LCD device"); ESP_PANEL_CHECK_FALSE_RET(lcd->getHandle() != nullptr, nullptr, "LCD device is not initialized"); static lv_disp_draw_buf_t disp_buf; static lv_disp_drv_t disp_drv; // Alloc draw buffers used by LVGL void *buf[LVGL_PORT_BUFFER_NUM_MAX] = { nullptr }; int buffer_size = 0; ESP_LOGD(TAG, "Malloc memory for LVGL buffer"); #if !LVGL_PORT_AVOID_TEAR // Avoid tearing function is disabled buffer_size = LVGL_PORT_BUFFER_SIZE; for (int i = 0; (i < LVGL_PORT_BUFFER_NUM) && (i < LVGL_PORT_BUFFER_NUM_MAX); i++) { buf[i] = heap_caps_malloc(buffer_size * sizeof(lv_color_t), LVGL_PORT_BUFFER_MALLOC_CAPS); assert(buf[i]); ESP_LOGD(TAG, "Buffer[%d] address: %p, size: %d", i, buf[i], buffer_size * sizeof(lv_color_t)); }     三、温湿度数据采集与处理 传感器初始化与配置: 在rp2040副核心上编写代码,初始化BME280传感器,并配置其采集模式和采样率等参数。 数据采集与传输: 编写数据采集循环,使rp2040能够定期从BME280传感器读取温湿度数据。 实现数据通信协议,将采集到的数据通过UART、SPI等通信接口发送给ESP32-S3主核心。 Serial.begin(115200); while(!Serial); // time to get serial running Serial.println(F("BME280 test")); unsigned status; status = bme.begin(); if (!status) { Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!"); Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16); Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n"); Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n"); Serial.print(" ID of 0x60 represents a BME 280.\n"); Serial.print(" ID of 0x61 represents a BME 680.\n"); while (1) delay(10); if (isnan(temperature) || isnan(humidity)) { // 如果读取失败,则通过串口输出错误信息 Serial.println("Failed to read from BME280 sensor!"); } else { // 如果温度和湿度数据读取成功,则执行以下操作 // 创建一个静态JSON文档对象,分配200字节的内存空间 // 用于存储JSON格式的数据 StaticJsonDocument<200> doc; // 向JSON文档中添加温度数据 doc["temperature"] = temperature; // 向JSON文档中添加湿度数据 doc["humidity"] = humidity; // 假设pressure和altitude变量已经通过某种方式获取(例如从BME280传感器) // 向JSON文档中添加气压数据 doc["pressure"] = pressure; // 向JSON文档中添加海拔数据(注意:BME280传感器本身不提供海拔数据, // 这里可能是通过其他方式计算或获取的) doc["altitude"] = altitude; // 创建一个字符串对象,用于存储序列化后的JSON数据 String jsonString; // 使用serializeJson函数将JSON文档序列化为字符串 // 并存储在jsonString变量中 serializeJson(doc, jsonString); // 通过串口输出序列化后的JSON字符串(通常用于调试) Serial.println(jsonString); // 通过Serial1串口输出序列化后的JSON字符串 // 这可能用于将数据发送到其他设备或系统 Serial1.println(jsonString); } 实际输出 结果:     显示地理位置代码: String cityCode = "66666&"; // 查看你的 城市代码 String userKey = "66666666666"; // 要去注册一个高德地图的开发用户 文字代码: /* 佛 */ 20,20,18,0,3,0, //dsc : unicode = 0x4f5b 0x00,0x00,0x00,0x00,0xcc,0x7f,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xdc,0x87,0x00,0x00,0x00,0x00,0x00, //....@*...%%..@%..... 0x00,0x00,0x00,0x33,0xff,0x5d,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //...+@*...%%..@%..... 0x00,0x00,0x00,0x8f,0xf2,0x53,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x48,0x00, //...%@*@@@@@@@@@@@@*. 0x00,0x00,0x0c,0xf0,0x91,0x17,0x54,0x54,0x54,0xcf,0xcf,0x54,0x54,0xed,0xb2,0x54,0x6e,0xff,0x48,0x00, //..+@%+***@@**@%**@*. 0x00,0x00,0x6e,0xff,0x28,0x00,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xe4,0x8c,0x00,0x28,0xff,0x48,0x00, //..*@+....%%..@%.+@*. 0x00,0x0c,0xe8,0xff,0x10,0x00,0x00,0x00,0x00,0xb8,0xb8,0x00,0x00,0xe4,0x8c,0x00,0x28,0xff,0x48,0x00, //.+@@+....%%..@%.+@*. 0x00,0x82,0xff,0xff,0x10,0x21,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x48,0x00, //.%@@++@@@@@@@@@@@@*. 0x2e,0xfa,0xd5,0xff,0x10,0x44,0xff,0x79,0x54,0xd4,0xcd,0x54,0x54,0xed,0xb2,0x54,0x6e,0xff,0x48,0x00, //+@@@+*@**@@**@%**@*. 0xa1,0xd5,0x5b,0xff,0x10,0x67,0xff,0x1c,0x00,0xc6,0xab,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //%@*@+*@+.@%..@%..... 0x50,0x35,0x54,0xff,0x10,0x8a,0xf9,0x02,0x00,0xd9,0x9a,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //*+*@+%@+.@%..@%..... 0x00,0x00,0x54,0xff,0x10,0x9c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2a, //..*@+%@@@@@@@@@@@@@+ 0x00,0x00,0x54,0xff,0x10,0x33,0x54,0x54,0x6f,0xff,0x8c,0x54,0x54,0xed,0xb2,0x54,0x54,0x96,0xff,0x20, //..*@++***@%**@%**%@+ 0x00,0x00,0x54,0xff,0x10,0x00,0x00,0x00,0x5e,0xff,0x24,0x00,0x00,0xe4,0x8c,0x00,0x00,0x6e,0xff,0x12, //..*@+...*@+..@%..*@+ 0x00,0x00,0x54,0xff,0x10,0x00,0x00,0x00,0xc5,0xda,0x00,0x00,0x00,0xe4,0x8c,0x0f,0x07,0xae,0xf5,0x02, //..*@+...@@...@%++%@+ 0x00,0x00,0x54,0xff,0x10,0x00,0x00,0x54,0xff,0x67,0x00,0x00,0x00,0xe4,0x8c,0xdf,0xff,0xff,0xa3,0x00, //..*@+..*@*...@%@@@%. 0x00,0x00,0x54,0xff,0x10,0x00,0x28,0xf1,0xc9,0x05,0x00,0x00,0x00,0xe4,0x8c,0x51,0x73,0x57,0x05,0x00, //..*@+.+@@+...@%***+. 0x00,0x00,0x54,0xff,0x10,0x30,0xe9,0xe8,0x20,0x00,0x00,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //..*@++@@+....@%..... 0x00,0x00,0x54,0xff,0x10,0x37,0xc6,0x23,0x00,0x00,0x00,0x00,0x00,0xe4,0x8c,0x00,0x00,0x00,0x00,0x00, //..*@++@+.....@%..... /* 山 */ 19,17,18,2,3,0, //dsc : unicode = 0x5c71 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.......@@........ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.......@@........ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.......@@........ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xa8,0x00,0x00,0x00,0x00,0x00,0xdc,0xd8,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //@%.....@@.....%@+ 0xff,0xd2,0x7c,0x7c,0x7c,0x7c,0x7c,0xed,0xeb,0x7c,0x7c,0x7c,0x7c,0x7c,0xce,0xff,0x0c, //@@*****@@*****@@+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0c, //@@@@@@@@@@@@@@@@+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xff,0x0c, //..............%@+ /* 市 */ 20,20,20,0,2,0, //dsc : unicode = 0x5e02 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0xd1,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //........*@+......... 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0xfe,0xbe,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //........+@%+........ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9b,0xc8,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........%@+........ 0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80, //*@@@@@@@@@@@@@@@@@@% 0x32,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0xe3,0xe3,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x3e, //+********@@********+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@......... 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@......... 0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00, //..@@@@@@@@@@@@@@@@.. 0x00,0x00,0xc0,0xdf,0x74,0x74,0x74,0x74,0x74,0xe1,0xe1,0x74,0x74,0x74,0x74,0x74,0xcf,0xe0,0x00,0x00, //..@@*****@@*****@@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xa8,0xe0,0x00,0x00, //..@@.....@@.....%@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0xab,0xdf,0x00,0x00, //..@@.....@@.....%@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x1a,0xe1,0xca,0x00,0x00, //..@@.....@@....+@@.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x6c,0xff,0xff,0xff,0xff,0x75,0x00,0x00, //..@@.....@@.*@@@@*.. 0x00,0x00,0xc0,0xc4,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x28,0x8b,0x83,0x7c,0x4c,0x00,0x00,0x00, //..@@.....@@.+%%**... 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@......... 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //.........@@......... 显示结果:     LVGL 初始化液晶屏和 LVGL 接口的函数,直接调用 esp_lvgl语句实现的,函数就是在 esp32_s3_szp.c 文件中实现的及函数的定义。      esp-bsp 库,使用 VSCode 打开 esp-bsp 文件夹, bsp/esp32_s3_eye/esp32_s3_eye.c 文件, bsp_display_lcd_init()函数,下代码所示: static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) { assert(cfg != NULL); esp_lcd_panel_io_handle_t io_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL; const bsp_display_config_t bsp_disp_cfg = { .max_transfer_sz = BSP_LCD_DRAW_BUFF_SIZE * sizeof(uint16_t), }; BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new(&bsp_disp_cfg, &panel_handle, &io_handle)); #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) esp_lcd_panel_disp_off(panel_handle, false); #else esp_lcd_panel_disp_on_off(panel_handle, true); #endif /* Add LCD screen */ ESP_LOGD(TAG, "Add LCD screen"); const lvgl_port_display_cfg_t disp_cfg = { .io_handle = io_handle, .panel_handle = panel_handle, .buffer_size = cfg->buffer_size, .double_buffer = cfg->double_buffer, .hres = BSP_LCD_H_RES, .vres = BSP_LCD_V_RES, .monochrome = false, /* Rotation values must be same as used in esp_lcd for initial settings of the screen */ .rotation = { .swap_xy = false, .mirror_x = false, .mirror_y = false, }, .flags = { .buff_dma = cfg->flags.buff_dma, .buff_spiram = cfg->flags.buff_spiram, #if LVGL_VERSION_MAJOR >= 9 .swap_bytes = (BSP_LCD_BIGENDIAN ? true : false), #endif } }; return lvgl_port_add_disp(&disp_cfg); } 四、实际效果: [localvideo]19f3271426efcb902bba5bfaeb89e893[/localvideo]       总结: 一个基于ESP32-S3和rp2040双核心的智能温湿度显示系统。硬件部分通过连接BME280传感器实现数据采集,软件部分则利用LVGL库设计用户交互界面,并实时显示温湿度数据。ESP32-S3作为主核心负责界面运行与数据显示,而rp2040则负责数据采集与传输。项目关键工作包括界面设计、数据更新与显示、LVGL用户交互界面实现以及温湿度数据采集与处理。通过此系统,用户可直观获取当前环境的温湿度信息。      

  • 发表了主题帖: 【2024 DigiKey 创意大赛】+硬件准备

    本帖最后由 meiyao 于 2024-11-3 20:10 编辑 收到这个任务的时候时间上有点晚哈,今天把我的任务工作过程分享出来,主要分享一下硬件的主要功能点:   一、硬件分析 1、使用的是Espressif(乐鑫)的ESP32-S3-LCD-EV-BOARD作为主评估板,板集成了ESP32-S3芯片和LCD显示屏,为项目开发提供了强大的处理和显示能力。 2、设计一款与ESP32-S3-LCD-EV-BOARD扩展接口对接的PCB扩展板,实现数据显示等功能。 要求扩展板在设计上需要与主评估板完美对接,同时满足新增功能的需求。 3、采用Bosch的BME280传感器,该传感器能够实时监测环境的温湿度数据,具有高精度和稳定性,非常适合用于环境监测类项目。 4、采用rp2040作为副核心,与主核心ESP32-S3相互通信,实现通信功能 。 5、采用LVGL作为用户交互界面,实现温湿度传感器数据的实时显示。使用LVGL嵌入式系统,实现动画图形界面元素。   二、硬件准备 ESP32-S3-LCD-EV-BOARD评估板: 核心芯片:ESP32-S3,集成Wi-Fi和Bluetooth LE功能,开发板搭载了ESP32-S3系统级芯片(SoC),芯片集成了强大的Wi-Fi和蓝牙功能,并支持Bluetooth 5和Bluetooth mesh,同时兼容BLE(低功耗蓝牙)。 显示屏:集成LCD显示屏,支持触摸操作,开发板提供了LCD总成接口,支持连接各种类型的LCD屏幕,用于显示图像和文本信息。 接口:提供丰富的扩展接口,方便与扩展板对接,除了LCD接口外,开发板还提供了多种GPIO接口和外设支持,USB OTG、SPI、I2C、UART等,方便开发者连接各种传感器、执行器等外部设备。 电源管理:开发板内置了电源管理模块,用于为各个部件提供稳定的电源供应,并确保在低功耗模式下能够正常工作。   BME280温湿度传感器: 温度检测范围:-40℃~+85℃,分辨率0.1℃,误差±0.5℃。 湿度检测范围:0~100%RH,分辨率0.1%RH,误差±2%RH。 接口:支持SPI和I2C通信协议,方便与扩展板连接。   rp2040副核心: 核心芯片:RP2040,提供强大的处理能力和低功耗特性。 接口:提供多种通信接口(UART、SPI、I2C等),方便与主核心和扩展板连接。   电阻、电容、电感等被动元件。 连接线、排针、排母等连接器件。 电源管理芯片,确保系统稳定运行。     三、硬件原理与PCB: ESP32-S3-LCD-EV-BOARD与PICO连接硬件原理:     PCB设计如下图:   PCB上的走线遵循了电气规范和信号完整性要求,确保信号的稳定传输。       PCB空板:     焊接完成的成品正面:     焊接完成的成品背面:     连接成品:     四、总结 本次任务基于Espressif的ESP32-S3-LCD-EV-BOARD评估板,设计了一款PCB扩展板,并集成了Bosch的BME280传感器和rp2040副核心。 通过LVGL实现用户交互界面,实时显示温湿度数据。硬件准备充分,包括评估板、传感器、副核心及被动元件等。 PCB设计遵循电气规范和信号完整性要求,确保信号稳定传输。成品焊接完成,连接良好。    

  • 2024-10-30
  • 发表了主题帖: Follow me 第二季第2期+任务汇总

    本帖最后由 meiyao 于 2024-10-31 21:37 编辑 下面是我Follow me 第二季第2期各个功能的贴子,具体的细节可以进行查看。 Follow me 第二季第2期任务入门任务+Blink / 串口打印Hello EEWorld! https://bbs.eeworld.com.cn/thread-1294799-1-1.html Follow me 第二季第2期任务基础任务点阵/DAC/ADC采集 https://bbs.eeworld.com.cn/thread-1294800-1-1.html https://bbs.eeworld.com.cn/thread-1295342-1-1.html Follow me 第二季第2期进阶任务MQTT平台HA任务 https://bbs.eeworld.com.cn/thread-1295082-1-1.html Follow me 第二季第2期+ 扩展任务一利用LTR-329 环境光传感器,上传光照度到HA并显示 https://bbs.eeworld.com.cn/thread-1295431-1-1.html Follow me 第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示 https://bbs.eeworld.com.cn/thread-1295434-1-1.html   视频: [localvideo]fa157f1c900550afff4ee4e473f65689[/localvideo] [localvideo]36e188073c5598033c40e07049ddec06[/localvideo]     Follow me 第二季第2期任务入门任务+Blink / 串口打印Hello EEWorld! LED闪烁代码: void setup() { // 初始化数字引脚LED_BUILTIN为输出状态 pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); // 打开LED灯 delay(1000); // 等待一秒 digitalWrite(LED_BUILTIN, LOW); // 关闭LED灯 delay(1000); // 等待一秒 }   工作流程: 开始(Start) 流程图的起点。 初始化 调用setup()函数。 设置LED_BUILTIN引脚为输出模式(pinMode(LED_BUILTIN, OUTPUT))。 主循环(Loop) 调用loop()函数,这是一个无限循环。 打开LED 在loop()中,首先调用digitalWrite(LED_BUILTIN, HIGH)将LED灯打开。 等待一秒 调用delay(1000),等待1000毫秒(即1秒)。 关闭LED 调用digitalWrite(LED_BUILTIN, LOW)将LED灯关闭。 再次等待一秒 再次调用delay(1000),等待1000毫秒(即1秒)。 回到主循环 流程回到loop()的开始,重复步骤4到7。 结束(End) 理论上,由于这是一个无限循环,流程不会真正结束,但在流程图中可以用一个圆形结束符号表示流程图的视觉结束点。     串口打印Hello EEWorld! void setup() { // 初始化数字引脚LED_BUILTIN为输出状态 pinMode(LED_BUILTIN, OUTPUT); // 初始化串口通信,设置波特率为9600 Serial.begin(9600); } void loop() { digitalWrite(LED_BUILTIN, HIGH); // 打开LED灯 delay(1000); digitalWrite(LED_BUILTIN, LOW); // 关闭LED灯 delay(1000); // 串口打印Hello EEWorld! Serial.println("Hello EEWorld!"); } 输出结果:     Follow me 第二季第2期任务基础任务DAC/ADC采集     驱动12x8点阵LED Arduino UNO R4 WiFi开发板上点阵LED的行列控制引脚正确连接到开发板的数字I/O接口。 在Arduino IDE中编写代码,使用digitalWrite或shiftOut等函数控制点阵LED的行列,实现显示功能。 通过循环或数组来控制LED的亮灭,形成图案或文字。   下面代码中,显示‘MY’。 #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; byte frame[8][12] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0 }, { 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0 }, { 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; void setup() { Serial.begin(115200); matrix.begin(); matrix.renderBitmap(frame, 8, 12); } void loop() { }   输出结果:     用DAC生成正弦波: Arduino UNO R4 WiFi开发板上的DAC接口需要被正确配置。根据开发板的文档,设置DAC的分辨率、输出范围等参数。 生成正弦波:编写代码,使用数学函数(如sin)生成正弦波的数据点。将数据点通过DAC输出到模拟引脚。     #include "analogWave.h" analogWave wave(DAC); // 使用DAC引脚实例化模拟曲线对象wave float freq = 0.5; // 设置曲线初始频率 void setup() { Serial.begin(115200); // 串口波特率 wave.sine(freq); // 使用模拟曲线对象wave按照初始频率生成正弦波 wave.amplitude(0.5); } void loop() { printf("%d\n",analogRead(A4)); // 读取正弦值 delay(100); } #include "analogWave.h":这行代码包含了一个名为analogWave的头文件,这个头文件中可能定义了用于生成模拟波形的类和相关函数。 analogWave wave(DAC);:使用DAC引脚实例化一个名为wave的analogWave对象。这意味着这个对象将使用指定的DAC引脚来输出模拟波形。 float freq = 0.5;:设置一个初始频率为0.5的浮点数变量freq。这个频率可能用于控制生成的正弦波的周期。 void setup() {... }: Serial.begin(115200);:初始化串口通信,设置波特率为 115200。 wave.sine(freq);:使用wave对象调用sine函数,传入初始频率freq,以生成正弦波。 wave.amplitude(0.5);:设置生成的正弦波的幅度为 0.5。 void loop() {... }: printf("%d\n",analogRead(A4));:读取A4引脚的模拟值,并通过串口打印出来。 delay(100);:延迟 100 毫秒,以控制程序的执行速度。 主要功能是使用一个名为analogWave的类来生成正弦波,并通过DAC引脚输出。代码在主循环中不断读取A4引脚的模拟值并通过串口打印出来。         用OPAMP放大DAC信号   生成一个正弦波,并可以通过读取模拟输入引脚 A5 的值来动态调整正弦波的频率,然后将更新后的频率信息打印到串口监视器上。   #include "analogWave.h" // Include the library for analog waveform generation #include <OPAMP.h> analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin int freq = 10; // in hertz, change accordingly int reading = 0; void setup() { OPAMP.begin(OPAMP_SPEED_HIGHSPEED); Serial.begin(115200); // Initialize serial communication at a baud rate of 115200 analogWriteResolution(14); wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); reading = analogRead(A4); Serial.print(reading); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(50); // Delay for one second before repeating } 使用的工具与器件有: 电阻10K--1个 电阻30K--1个 手持示波器--一台。   电阻连接示意图:       用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线 代码的主要功能是通过读取模拟输入引脚 A5 的值来动态调整正弦波的频率,并将该频率信息打印到串口监视器上。代码使用 analogWave 类在指定的 DAC 引脚上生成正弦波,并通过读取 A4 引脚的模拟值进行一些可能的后续处理(这里只是将其打印出来)。 #include "analogWave.h" // Include the library for analog waveform generation #include <OPAMP.h> analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin int freq = 10; // in hertz, change accordingly int reading = 0; void setup() { OPAMP.begin(OPAMP_SPEED_HIGHSPEED); Serial.begin(115200); // Initialize serial communication at a baud rate of 115200 analogWriteResolution(14); wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); reading = analogRead(A4); Serial.print(reading); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(50); // Delay for one second before repeating } 程序工作流程: 开始 标记为“开始”的圆形节点。 初始化 包含库:analogWave.h 和 <OPAMP.h> 创建实例:analogWave wave(DAC); 设置变量:int freq = 10; 和 int reading = 0; 设置OPAMP:OPAMP.begin(OPAMP_SPEED_HIGHSPEED); 初始化串口:Serial.begin(115200); 设置DAC分辨率:analogWriteResolution(14); 生成初始波形:wave.sine(freq); 标记为“处理框”或“步骤”的矩形节点,包含上述初始化步骤。 主循环 标记为“循环开始”的圆形节点(通常有一个小箭头指向它,表示循环)。 读取A5引脚 读取模拟值:freq = map(analogRead(A5), 0, 1024, 0, 10000); 标记为“处理框”的矩形节点,显示读取和映射操作。 打印频率 输出到串口:Serial.println("Frequency is now " + String(freq) + " hz"); 标记为“输出”的菱形节点,显示串口输出。 读取A4引脚 读取模拟值:reading = analogRead(A4); 输出到串口:Serial.print(reading); 标记为“处理框”的矩形节点,显示读取和输出操作。 设置波形频率 更新波形频率:wave.freq(freq); 标记为“处理框”的矩形节点,显示频率更新操作。 延迟 延时:delay(50); 标记为“延迟”的菱形节点,显示延迟时间。 循环结束 回到“主循环”的圆形节点,形成闭环。 结束 标记为“结束”的圆形节点。 输出效果图:     Follow me 第二季第2期进阶任务MQTT平台HA任务     MQTT服务器:EMQX或Mosquitto,可以选择安装一个MQTT服务器,或者在云服务上使用一个现有的MQTT服务。 配置MQTT服务器:根据MQTT服务器的文档,配置必要的参数,。记录MQTT服务器的地址、端口和认证信息(用户名和密码)。 // 引入必要的库 #include <ArduinoMqttClient.h> // 注意:这个库可能不是标准的Arduino库,需要确认其来源和兼容性 #include <WiFiS3.h> // 这个库可能也不是标准的,通常我们使用<WiFi.h> #include <WiFiClient.h> // 用于创建WiFi客户端对象,与MQTT服务器通信 // WiFi网络的SSID和密码 char ssid[] = "CMCC-qM7y"; char pass[] = "15074219167"; // WiFi连接状态 int status = WL_IDLE_STATUS; // MQTT代理的IP地址和端口号 const char broker[] = "192.168.1.113"; int port = 1883; // 要发布的MQTT主题 const char topic[] = "/aht10/test"; // 创建WiFi客户端和MQTT客户端对象 WiFiClient wifiClient; MqttClient mqttClient(wifiClient); // 注意:MqttClient类的构造函数可能需要根据实际库进行调整 void setup() { // 初始化串口通信,用于调试 Serial.begin(9600); // 等待串口连接(仅对某些开发板必要) while (!Serial) { // 空循环,等待串口准备就绪 } // 检查WiFi模块是否存在 if (WiFi.status() == WL_NO_MODULE) { Serial.println("WiFi模块通信失败!"); // 如果WiFi模块不存在,则停止执行 while (true); } // 检查WiFi固件版本(这个步骤可能不是必需的) String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { // 注意:WIFI_FIRMWARE_LATEST_VERSION可能需要定义或根据实际情况调整 Serial.println("请升级固件!"); } // 尝试连接到WiFi网络 while (status != WL_CONNECTED) { Serial.print("正在尝试连接到WPA SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, pass); // 开始连接到指定的SSID和密码 delay(10000); // 等待10秒以尝试连接 } // 打印当前连接的网络信息 Serial.print("您已连接到网络"); printCurrentNet(); printWifiData(); // 尝试连接到MQTT代理 if (!mqttClient.connect(broker, port)) { Serial.print("MQTT连接失败!错误代码 = "); Serial.println(mqttClient.connectError()); // 打印连接错误的详细信息 // 如果连接失败,则停止执行 while (1); } Serial.println("您已连接到MQTT"); } // 打印当前网络的信息 void printCurrentNet() { // 打印连接的SSID Serial.print("SSID: "); Serial.println(WiFi.SSID()); // 打印路由器的MAC地址 byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // 打印接收到的信号强度 long rssi = WiFi.RSSI(); Serial.print("信号强度 (RSSI):"); Serial.println(rssi); // 打印加密类型 byte encryption = WiFi.encryptionType(); Serial.print("加密类型:"); Serial.println(encryption, HEX); // 以十六进制格式打印 Serial.println(); } // 打印MAC地址的函数 void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); // 在MAC地址的每个字节之间打印冒号 } // 如果MAC地址的某个字节小于16,则在前面打印0 if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); // 以十六进制格式打印MAC地址的每个字节 } Serial.println(); } // 打印WiFi数据(IP地址和MAC地址) void printWifiData() { // 打印开发板的IP地址 IPAddress ip = WiFi.localIP(); Serial.print("IP 地址: "); Serial.println(ip); // 打印开发板的MAC地址 byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC 地址: "); printMacAddress(mac); } // 主循环 void loop() { // 开始一个新的MQTT消息 mqttClient.beginMessage(topic); // 向消息中添加内容 mqttClient.print("Hello EEworld and Digikey!"); // 结束并发送消息 mqttClient.endMessage(); // 等待500毫秒,然后重复发送 delay(500); } 工作流程: 初始化阶段(setup()函数) 串口初始化: Serial.begin(9600); 初始化串口通信,波特率设为9600,用于调试信息输出。 WiFi模块检查: 通过WiFi.status()检查WiFi模块是否存在。如果不存在,则输出错误信息并停止执行。 WiFi固件版本检查(可选): 获取WiFi固件版本,并与最新版本进行比较(注意:WIFI_FIRMWARE_LATEST_VERSION可能需要自定义或根据实际情况调整)。如果版本过旧,则提示用户升级固件。 连接到WiFi网络: 使用WiFi.begin(ssid, pass);尝试连接到指定的SSID和密码。如果连接失败,则每10秒重试一次,直到成功为止。 打印网络信息: 一旦连接到WiFi网络,使用printCurrentNet()和printWifiData()函数打印当前网络的信息,包括SSID、BSSID(路由器的MAC地址)、信号强度(RSSI)、加密类型,以及开发板的IP地址和MAC地址。 连接到MQTT代理: 使用mqttClient.connect(broker, port);尝试连接到MQTT代理。如果连接失败,则输出错误信息并停止执行。 主循环阶段(loop()函数) 发布MQTT消息: 在主循环中,首先使用mqttClient.beginMessage(topic);开始一个新的MQTT消息,其中topic是消息要发布到的主题。 然后,使用mqttClient.print("Hello EEworld and Digikey!");向消息中添加内容。 最后,使用mqttClient.endMessage();结束并发送消息。 延迟: 使用delay(500);等待500毫秒,然后重复上述过程。这意味着每500毫秒,代码将向MQTT代理发布一条包含"Hello EEworld and Digikey!"的消息。   输出结果:       Follow me 第二季第2期+ 扩展任务一利用LTR-329 环境光传感器,上传光照度到HA并显示   通过外部LTR-329环境光传感器,将光照度数据上传到HA并在HA面板上显示,所需搭配器件Arduino UNO R4 WiFi、5591(LTR-329光传感器扩展板)、PRT-14426(Qwiic缆线-50mm)。 连接LTR-329光传感器: 使用5591(LTR-329光传感器扩展板)将LTR-329光传感器与Arduino UNO R4 WiFi连接起来,连接的是J2接口。 连接Qwiic缆线: 使用PRT-14426(Qwiic缆线-50mm)将扩展板与Arduino UNO R4 WiFi的Qwiic连接器连接起来。 Qwiic连接器的设计使得连接更加简便和可靠,即插即用。     // 引入必要的库 #include "Adafruit_LTR329_LTR303.h" #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> // 创建LTR-329传感器的实例 Adafruit_LTR329 ltr = Adafruit_LTR329(); // WiFi网络的SSID和密码 char ssid[] = "CMCC-c6tG"; char pass[] = "mei13728232960"; int status = WL_IDLE_STATUS; // WiFi连接状态 // MQTT代理的地址和端口 const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "lux"; // MQTT主题 // 创建WiFi和MQTT客户端实例 WiFiClient wifiClient; MqttClient mqttClient(wifiClient); // 用于存储JSON数据的变量 JSONVar dataObj; void setup() { // 初始化串口通信 Serial.begin(115200); Serial.println("Adafruit LTR-329 advanced test"); // 检查WiFi固件版本 String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } // 尝试连接到WiFi网络 while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, pass); delay(10000); // 等待10秒 } // 打印连接到的网络信息 Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); // 尝试连接到MQTT代理 if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); // 连接失败则停止执行 } Serial.println("You are connected to MQTT"); // 检查WiFi模块通信 if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); while (true); // 停止执行 } // 初始化LTR-329传感器 if ( ! ltr.begin(&Wire1) ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); // 未找到传感器则停止执行 } Serial.println("Found LTR sensor!"); // 设置传感器的增益、积分时间和测量速率 ltr.setGain(LTR3XX_GAIN_2); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } } // 打印当前连接的网络信息 void printCurrentNet() { Serial.print("SSID: "); Serial.println(WiFi.SSID()); byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } // 打印MAC地址 void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } // 打印WiFi数据 void printWifiData() { IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } // 主循环 void loop() { bool valid; uint16_t visible_plus_ir, infrared; if (ltr.newDataAvailable()) { // 检查是否有新数据 valid = ltr.readBothChannels(visible_plus_ir, infrared); // 读取可见光和红外数据 if (valid) { // 如果数据有效 dataObj["brightness"] = visible_plus_ir; // 设置JSON对象中的亮度值 dataObj["psData"] = infrared; // 设置JSON对象中的红外数据 String jsonString = JSON.stringify(dataObj); // 将JSON对象转换为字符串 mqttClient.beginMessage(command_topic); // 开始发送MQTT消息 mqttClient.print(jsonString); // 发送JSON字符串 mqttClient.endMessage(); // 结束消息发送 } } delay(500); // 等待500毫秒 } 工作流程: 初始化阶段(setup()函数) 串口初始化: Serial.begin(115200); 设置串口通信波特率为115200,用于调试信息的输出。 WiFi固件版本检查(可选步骤): 获取并检查WiFi模块的固件版本,若版本过旧,则提示用户进行升级。但请注意,WIFI_FIRMWARE_LATEST_VERSION可能需自定义或根据具体情况调整,且此步骤在实际应用中可能并非必需。 WiFi网络连接: 尝试连接到指定的SSID和密码的WiFi网络。若连接失败,则每10秒重试一次,直至成功连接。 网络信息打印: 连接成功后,利用printCurrentNet()和printWifiData()函数打印当前网络信息,涵盖SSID、BSSID(路由器MAC地址)、信号强度(RSSI)、加密类型,以及开发板的IP地址和MAC地址。 MQTT代理连接: 尝试连接到MQTT代理,若连接失败,则输出错误信息并停止执行。 WiFi模块通信检查: 此步骤实际上应在尝试连接WiFi网络之前进行,但在此代码中被置于之后。它检查WiFi模块是否存在且通信正常。若模块不存在或通信失败,则停止执行。然而,更合理的做法是在尝试连接网络前进行此检查,以避免不必要的等待。 LTR-329传感器初始化: 初始化LTR-329光照传感器,并检查其是否成功连接。若未找到传感器,则停止执行。 传感器设置: 配置传感器的增益、积分时间和测量速率,并通过串口打印出当前设置。 主循环阶段(loop()函数) 数据读取与验证: 利用ltr.newDataAvailable()检查传感器是否有新数据可读。若有,则通过ltr.readBothChannels()读取可见光和红外数据,并验证数据的有效性。 数据处理与发送: 若数据有效,则创建一个JSON对象dataObj,并分别将可见光数据和红外数据赋值给其brightness和psData字段。 利用JSON.stringify(dataObj)将JSON对象转换为字符串。 通过MQTT客户端发送此JSON字符串到指定的MQTT主题lux。 延迟: 每次循环结束后,程序会等待500毫秒,然后重复上述过程。     Follow me 第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示 通过外部SHT40温湿度传感器,将温湿度数据上传到Home Assistant(HA)并在HA面板上显示。 连接SHT40温湿度传感器 使用4885(SHT40温湿度传感器扩展板)将SHT40温湿度传感器与Arduino UNO R4 WiFi连接起来。 SHT40传感器通常具有VCC、GND、SCK(时钟线)和SDA(数据线)四个引脚,正确对应连接到扩展板和Arduino J2上。 代码: #include "Adafruit_SHT4x.h" // 引入Adafruit SHT4x库 #include <ArduinoMqttClient.h> // 引入Arduino MQTT客户端库 #include <WiFiS3.h> // 引入WiFi库(适用于ESP32) #include <WiFiClient.h> // 引入WiFi客户端库 #include <Arduino_JSON.h> // 引入Arduino JSON库 Adafruit_SHT4x sht4; // 创建SHT4x对象 char ssid[] = "CMCC-c6tG"; // WiFi网络的SSID char pass[] = "mei13728232960"; // WiFi网络的密码 int status = WL_IDLE_STATUS; // WiFi连接状态 const char broker[] = "192.168.1.113"; // MQTT代理的IP地址 int port = 1883; // MQTT代理的端口号 const char command_topic[] = "office/sensor1"; // MQTT主题 WiFiClient wifiClient; // 创建WiFi客户端对象 MqttClient mqttClient(wifiClient); // 创建MQTT客户端对象 JSONVar dataObj; // 创建JSON对象用于存储数据 void setup() { Serial.begin(115200); // 初始化串口通信 // 设置SHT4x的精度为高精度 sht4.setPrecision(SHT4X_HIGH_PRECISION); // 打印当前设置的精度 switch (sht4.getPrecision()) { case SHT4X_HIGH_PRECISION: Serial.println(F("SHT40 set to High precision")); break; case SHT4X_MED_PRECISION: Serial.println(F("SHT40 set to Medium precision")); break; case SHT4X_LOW_PRECISION: Serial.println(F("SHT40 set to Low precision")); break; } // 关闭SHT4x的加热器 sht4.setHeater(SHT4X_NO_HEATER); // 打印当前加热器的状态 switch (sht4.getHeater()) { case SHT4X_NO_HEATER: Serial.println(F("SHT40 Heater turned OFF")); break; // 其他加热器状态... } // 初始化SHT4x传感器 if (!sht4.begin(&Wire1)) { Serial.println(F("SHT40 sensor not found!")); while (1); // 如果传感器未找到,则停止程序 } else { Serial.print(F("SHT40 detected!\t")); Serial.print(F("Serial number:\t")); Serial.println(sht4.readSerial(), HEX); // 打印传感器的序列号 } Serial.println(F("----------------------------------")); // 检查WiFi固件版本 String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } // 连接到WiFi网络 while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, pass); delay(10000); // 等待10秒尝试连接 } Serial.print("You're connected to the network"); printCurrentNet(); // 打印当前网络的信息 printWifiData(); // 打印WiFi数据 // 连接到MQTT代理 if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); // 如果连接失败,则停止程序 } Serial.println("You are connected to MQTT"); // 检查WiFi模块是否通信正常 if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); while (true); // 如果通信失败,则停止程序 } } // 打印当前网络的信息 void printCurrentNet() { Serial.print("SSID: "); Serial.println(WiFi.SSID()); byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } // 打印MAC地址 void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } // 打印WiFi数据 void printWifiData() { IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { sensors_event_t humidity, temp; // 创建用于存储温度和湿度数据的结构体 sht4.getEvent(&humidity, &temp); // 从传感器获取最新的温度和湿度数据 float t = temp.temperature; // 获取温度值 Serial.println("Temp *C = " + String(t)); // 打印温度值 float h = humidity.relative_humidity; // 获取湿度值 Serial.println("Hum. % = " + String(h)); // 打印湿度值 // 将温度和湿度数据添加到JSON对象中 dataObj["temperature"] = t; dataObj["humidity"] = h; // 将JSON对象转换为字符串 String jsonString = JSON.stringify(dataObj); // 通过MQTT发送数据 mqttClient.beginMessage(command_topic); mqttClient.print(jsonString); mqttClient.endMessage(); delay(500); // 等待500毫秒后再次读取数据 }   初始化设置: 使用#include指令引入必要的库,包括Adafruit_SHT4x库(用于与SHT4x传感器通信)、ArduinoMqttClient库(用于MQTT通信)、WiFiS3和WiFiClient库(用于WiFi连接)、Arduino_JSON库(用于处理JSON数据)。 创建SHT4x对象sht4,用于与传感器通信。 定义WiFi网络的SSID和密码、MQTT代理的IP地址和端口号、MQTT主题等常量。 创建WiFi客户端对象wifiClient和MQTT客户端对象mqttClient。 创建一个JSON对象dataObj,用于存储将要发送的温湿度数据。 启动和配置: 在setup()函数中,首先初始化串口通信,设置波特率为115200。 配置SHT4x传感器,包括设置高精度模式、关闭加热器,并检查传感器是否正确连接。 检查WiFi固件版本,确保其为最新版本。 尝试连接到WiFi网络,如果连接失败,则每隔10秒重试一次,直到成功连接。 一旦连接到WiFi网络,打印当前网络的信息(SSID、BSSID、信号强度、加密类型)和WiFi数据(IP地址、MAC地址)。 尝试连接到MQTT代理,如果连接失败,则停止程序。 检查WiFi模块是否通信正常,如果不正常,则停止程序。 数据读取和发送: 在loop()函数中,程序进入一个无限循环,不断执行以下步骤: 从SHT4x传感器获取最新的温度和湿度数据。 打印温度和湿度值到串口监视器。 将温度和湿度数据添加到JSON对象dataObj中。 将JSON对象转换为字符串。 通过MQTT客户端mqttClient,将JSON字符串发送到指定的MQTT主题(command_topic)。 等待500毫秒,然后重复上述步骤。   实际输出结果:       概括与总结: Follow me 第二季第2期各个功能的帖子汇总,主要包括了入门任务、基础任务、进阶任务以及两个扩展任务的详细内容: 入门任务:Blink / 串口打印Hello EEWorld 搭建环境:需要安装Arduino IDE并更新到最新版本,添加Arduino UNO R4 WiFi的开发板支持包。 修改Blink示例代码:通过修改代码实现LED灯以1秒为周期闪烁,同时在串口监视器中打印"Hello EEWorld!"信息。 串口监视器设置:上传代码后,在Arduino IDE中选择正确的波特率(115200),打开串口监视器查看打印信息。 基础任务:点阵/DAC/ADC采集 驱动12x8点阵LED:查看点阵的连接方式与具体功能,将点阵LED的行列控制引脚正确连接到开发板的数字I/O接口,实现滚动显示文本。 DAC生成正弦波:配置DAC接口,设置分辨率、输出范围等参数,使用数学函数生成正弦波的数据点,通过DAC输出到模拟引脚。 OPAMP放大DAC信号:将OPAMP的输入端连接到DAC的输出引脚,配置增益以满足信号放大的需求,使用示波器测量放大效果。 ADC采集数据:设置ADC的采样率、分辨率等参数,将模拟信号连接到ADC的输入引脚,使用analogRead函数读取ADC的值,并打印到串口或其他接口。 进阶任务:MQTT平台HA任务 准备阶段:选择并配置MQTT服务器(如EMQX或Mosquitto),记录服务器的地址、端口和认证信息。 配置Arduino代码:在代码中配置WiFi连接,连接到MQTT服务器,设置MQTT客户端的参数。 发送MQTT消息:在主循环中,使用MQTT客户端发送消息到指定的主题,消息内容可以自定义。 测试与调试:上传Arduino代码,通过串口监视器查看输出信息,确保WiFi和MQTT连接正常。 扩展任务一:利用LTR-329环境光传感器,上传光照度到HA并显示 硬件连接:使用LTR-329环境光传感器扩展板和Qwiic缆线将传感器连接到Arduino UNO R4 WiFi。 读取光照数据:使用Adafruit_LTR329_LTR303库与LTR-329光传感器进行交互,读取光照数据。 发送数据到MQTT:将读取到的光照数据转换为JSON格式,通过MQTT协议发送到MQTT代理。 集成到Home Assistant:在Home Assistant中配置接收MQTT消息的设备,将光照数据显示在HA面板上。 扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示 硬件连接:使用SHT40温湿度传感器扩展板将传感器连接到Arduino UNO R4 WiFi,正确对应连接引脚。 读取温湿度数据:安装Adafruit_SHT4x库,使用库中的函数与SHT40传感器通信,读取温度和湿度数据。 发送数据到MQTT:将读取到的温湿度数据添加到JSON对象中,通过MQTT客户端发送到指定的主题。 在Home Assistant中显示:在Home Assistant中配置设备,接收MQTT消息并显示温湿度数据。     所用器件与开发板:   总结 从入门到进阶的Arduino编程和硬件连接技能,包括LED闪烁、串口通信、模拟信号采集与处理、MQTT协议应用以及传感器数据上传等。 通过完成这些任务,可以深入了解Arduino UNO R4 WiFi开发板的功能和应用场景,提高编程和硬件连接能力。 这些任务也为进一步学习和应用Arduino技术打下了坚实的基础。

  • 加入了学习《【Follow me第二季第1期】全部任务演示》,观看 全部任务演示2.0

  • 2024-10-12
  • 发表了主题帖: 2024 Digikey 感知万物,乐享生活”作创意大赛+开箱贴

      收到东西已经有半个月了,今天才来开箱贴,以下是对这款开发板的详细描述及与2024 Digikey“感知万物,乐享生活”创意大赛相关的开箱贴内容。   我使用的是ESP32-S3-LCD-EV-BOARD是一款由Espressif(乐鑫)制造的物料,它基于ESP32-S3-WROOM-1模组,并配备了FT5x06触摸屏驱动和GC9503CV LCD显示屏,是一个功能强大的屏幕交互开发板。   详细描述 ESP32-S3-LCD-EV-BOARD开发板具有以下特点和功能:   核心模组:搭载ESP32-S3-WROOM-1模组,该模组内置ESP32-S3系列芯片,提供Wi-Fi和低功耗蓝牙(Bluetooth 5/Bluetooth mesh)功能,适用于物联网(IoT)应用。 显示屏:配备GC9503CV LCD触摸屏,支持480x480分辨率,提供清晰的显示效果和触摸交互功能。 触摸屏驱动:采用FT5x06触摸屏驱动,确保触摸操作的准确性和响应速度。 接口丰富:提供GPIO、SPI、LCD接口、Camera接口、UART等多种外设接口,方便与其他硬件模块连接和扩展。 神经网络运算能力:模组具有强大的神经网络运算能力和信号处理能力,适用于AIoT领域的多种应用场景。   我仔细检查了开发板上的其他组件。ESP32-S3-WROOM-1模组位于开发板的核心位置,旁边是各种外设接口和扩展芯片。这些接口和芯片为我提供了丰富的扩展选项,让我可以轻松地连接其他硬件模块,实现更多的功能。 在开箱过程中,我还发现开发板附带了详细的文档和例程。这些文档和例程对我来说非常有帮助,它们可以帮助我更快地熟悉开发板的使用方法和编程技巧。 这款ESP32-S3-LCD-EV-BOARD开发板非常满意。它不仅外观精美、功能强大,而且扩展性强、易于使用。我相信在接下来的项目中,这款开发板一定会成为我的得力助手。”   上电开机照片:         盒子内部:   快递盒:     侧面:   压力传感器:     ESP32板袋:   总结:   经过半个月的等待,我终于迎来了ESP32-S3-LCD-EV-BOARD开发板。这款由Espressif(乐鑫)制造的开发板,以其强大的功能和精美的外观深深吸引了我。 开箱过程中,我仔细检查了开发板的各个组件,对其丰富的接口和扩展性表示赞赏。特别是ESP32-S3-WROOM-1模组、GC9503CV LCD触摸屏和FT5x06触摸屏驱动的组合,为我提供了清晰的显示效果和流畅的触摸操作体验。 开发板附带的详细文档和例程也对我帮助很大,让我能够更快地熟悉和掌握开发板的使用方法。 对这款ESP32-S3-LCD-EV-BOARD开发板非常满意。它不仅功能强大、易于使用,而且扩展性强,能够满足我在物联网项目中的各种需求。我相信,在未来的开发中,这款开发板一定会成为我的得力助手,助力我实现更多的创意和想法。                                      

  • 回复了主题帖: MPS MIE系列 第一期:痛点讨论|你理想中的电源模块是怎样的? 活动颁奖啦

    已扫码确认个人获奖信息,感谢MPS&EE论坛举办的活动!!!

  • 2024-10-08
  • 回复了主题帖: 邀您云逛展《TE Connectivity 线上工博会》报名有好礼!

      已参加 

  • 回复了主题帖: 颁奖:ADI & WT•世健 MCU 痛点探索季,第一站:征集活动

    已提交,收到

  • 2024-10-07
  • 发表了主题帖: Follow me 第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示

    通过外部SHT40温湿度传感器,将温湿度数据上传到Home Assistant(HA)并在HA面板上显示。   一、准备工作 连接SHT40温湿度传感器 使用4885(SHT40温湿度传感器扩展板)将SHT40温湿度传感器与Arduino UNO R4 WiFi连接起来。 SHT40传感器通常具有VCC、GND、SCK(时钟线)和SDA(数据线)四个引脚,正确对应连接到扩展板和Arduino J2上。   在Arduino IDE中,通过库管理器搜索并安装Adafruit_SHT4x库。这个库提供了与SHT40传感器通信所需的函数和接口。 编写Arduino程序 初始化WiFi连接,并配置MQTT客户端以连接到HA的MQTT服务器。 使用Adafruit_SHT4x库读取温湿度数据。 将读取到的温湿度数据序列化为JSON格式,并通过MQTT协议发送到HA。         二、代码: #include "Adafruit_SHT4x.h" // 引入Adafruit SHT4x库 #include <ArduinoMqttClient.h> // 引入Arduino MQTT客户端库 #include <WiFiS3.h> // 引入WiFi库(适用于ESP32) #include <WiFiClient.h> // 引入WiFi客户端库 #include <Arduino_JSON.h> // 引入Arduino JSON库 Adafruit_SHT4x sht4; // 创建SHT4x对象 char ssid[] = "CMCC-c6tG"; // WiFi网络的SSID char pass[] = "mei13728232960"; // WiFi网络的密码 int status = WL_IDLE_STATUS; // WiFi连接状态 const char broker[] = "192.168.1.113"; // MQTT代理的IP地址 int port = 1883; // MQTT代理的端口号 const char command_topic[] = "office/sensor1"; // MQTT主题 WiFiClient wifiClient; // 创建WiFi客户端对象 MqttClient mqttClient(wifiClient); // 创建MQTT客户端对象 JSONVar dataObj; // 创建JSON对象用于存储数据 void setup() { Serial.begin(115200); // 初始化串口通信 // 设置SHT4x的精度为高精度 sht4.setPrecision(SHT4X_HIGH_PRECISION); // 打印当前设置的精度 switch (sht4.getPrecision()) { case SHT4X_HIGH_PRECISION: Serial.println(F("SHT40 set to High precision")); break; case SHT4X_MED_PRECISION: Serial.println(F("SHT40 set to Medium precision")); break; case SHT4X_LOW_PRECISION: Serial.println(F("SHT40 set to Low precision")); break; } // 关闭SHT4x的加热器 sht4.setHeater(SHT4X_NO_HEATER); // 打印当前加热器的状态 switch (sht4.getHeater()) { case SHT4X_NO_HEATER: Serial.println(F("SHT40 Heater turned OFF")); break; // 其他加热器状态... } // 初始化SHT4x传感器 if (!sht4.begin(&Wire1)) { Serial.println(F("SHT40 sensor not found!")); while (1); // 如果传感器未找到,则停止程序 } else { Serial.print(F("SHT40 detected!\t")); Serial.print(F("Serial number:\t")); Serial.println(sht4.readSerial(), HEX); // 打印传感器的序列号 } Serial.println(F("----------------------------------")); // 检查WiFi固件版本 String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } // 连接到WiFi网络 while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, pass); delay(10000); // 等待10秒尝试连接 } Serial.print("You're connected to the network"); printCurrentNet(); // 打印当前网络的信息 printWifiData(); // 打印WiFi数据 // 连接到MQTT代理 if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); // 如果连接失败,则停止程序 } Serial.println("You are connected to MQTT"); // 检查WiFi模块是否通信正常 if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); while (true); // 如果通信失败,则停止程序 } } // 打印当前网络的信息 void printCurrentNet() { Serial.print("SSID: "); Serial.println(WiFi.SSID()); byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } // 打印MAC地址 void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } // 打印WiFi数据 void printWifiData() { IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { sensors_event_t humidity, temp; // 创建用于存储温度和湿度数据的结构体 sht4.getEvent(&humidity, &temp); // 从传感器获取最新的温度和湿度数据 float t = temp.temperature; // 获取温度值 Serial.println("Temp *C = " + String(t)); // 打印温度值 float h = humidity.relative_humidity; // 获取湿度值 Serial.println("Hum. % = " + String(h)); // 打印湿度值 // 将温度和湿度数据添加到JSON对象中 dataObj["temperature"] = t; dataObj["humidity"] = h; // 将JSON对象转换为字符串 String jsonString = JSON.stringify(dataObj); // 通过MQTT发送数据 mqttClient.beginMessage(command_topic); mqttClient.print(jsonString); mqttClient.endMessage(); delay(500); // 等待500毫秒后再次读取数据 }     代码解释: 加入库文件 Adafruit_SHT4x.h:用于与 Adafruit SHT4x 温湿度传感器进行交互。 ArduinoMqttClient.h:用于实现 MQTT 通信。 WiFiS3.h和WiFiClient.h:用于连接 WiFi 网络。 Arduino_JSON.h:用于处理 JSON 数据。   定义变量和对象 Adafruit_SHT4x sht4:创建 SHT4x 温湿度传感器对象。 char ssid[]和char pass[]:存储 WiFi 网络的名称和密码。 int status:用于存储 WiFi 连接状态。 const char broker[]和int port:MQTT 服务器的地址和端口。 const char command_topic[]:MQTT 的主题。 WiFiClient wifiClient和MqttClient mqttClient(wifiClient):创建 WiFi 客户端和 MQTT 客户端对象。 JSONVar dataObj:用于存储要发送的 JSON 数据。   setup 函数 初始化串口通信,设置波特率为 115200。 设置 SHT4x 传感器的精度为高精度,并打印当前精度。 关闭 SHT4x 传感器的加热器,并打印当前加热器状态。 初始化 SHT4x 传感器,如果未找到传感器则进入死循环;如果找到传感器,则打印传感器是否被检测到以及传感器的序列号。 检查 WiFi 固件版本,如果不是最新版本则提示升级。 尝试连接到指定的 WiFi 网络,直到连接成功。 连接 MQTT 服务器,如果连接失败则打印错误信息并进入死循环。 检查 WiFi 模块状态,如果通信失败则进入死循环。   printCurrentNet 函数 打印当前连接的 WiFi 网络的 SSID。 打印当前连接的路由器的 MAC 地址。 打印接收到的信号强度(RSSI)。 打印加密类型。   printMacAddress 函数 遍历传入的 MAC 地址数组,将每个字节转换为十六进制格式并打印,中间用冒号分隔。   printWifiData 函数 打印开发板的 IP 地址。 打印开发板的 MAC 地址,调用printMacAddress函数实现。   loop 函数 创建用于存储温度和湿度数据的结构体sensors_event_t humidity, temp。 从传感器获取最新的温度和湿度数据。 获取温度和湿度值,并打印出来。 将温度和湿度数据添加到dataObj中,将其转换为 JSON 字符串,并通过 MQTT 客户端发送到指定主题。 延迟 500 毫秒后再次读取数据。     三、实现效果                

统计信息

已有229人来访过

  • 芯积分:1255
  • 好友:4
  • 主题:80
  • 回复:130

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言