本帖最后由 御坂10032号 于 2025-10-22 20:24 编辑
简介
在写上一篇ESP32C5连接WIFI 5G的时候发现正好群里一个老师发了一个帖子是在Arduino上实现BLE键盘的,于是我想起来ESP-IDF上也有一个Example是可以实现低功耗蓝牙的HID设备。 因此我将在这篇文章中带着大家快速的根据上述的example 修改出一个键盘设备来实现键盘↓的功能。
BLE HID 设备 是一种使用 低功耗蓝牙(Bluetooth Low Energy, BLE) 通信的 人机交互设备(Human Interface Device),
常用于向手机、电脑、平板等主机发送输入数据,例如:键盘、鼠标、遥控器、游戏手柄等。 (来源互联网)
结果
不浪费大家流量,这个IDF的支持还是有限。编译和烧录正常。但是烧录之后蓝牙设备不启动。
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图1](https://mc.dfrobot.com.cn/data/attachment/forum/202510/17/230714atto909yzayieers.png)
正文【 ESP32-C5 MQTT 数据上报】
1- 首先按照DF,WIKI 的教程进行Arduino C5开发板的安装,切后切换版本到3.3.0 Alpha版本
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图2](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/192935sva11s2zji3sy03j.png)
2- 烧录完教程中的代码即设置GPIO15来使板载LED达到常亮成功即可验证环境正常
3- 打开WIFI6的demo进行连接测试,并且修改wifi账号密码为本地5G wifi密码
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图3](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/193146hzjlwwpw55aqu5wo.png)
修改密码
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图4](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/193219v5lmll10llrf5z06.png)
烧录代码
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图5](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/193246gsw0at0xesusjz1k.png)
当前的程序行为是连接路由器,作为STA设备,然后进行NTC校时并且每秒向控制台打印当前的时间。同时作为AP设备允许其他设备连接。但是如果使用的是Arduino的ide的话,我们无法看到串口的输出。
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图6](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/193419ij6dzo6p6rnt6onb.png)
猜测是因为系统启动需要时间,连接串口的时候日志正好打印好了。但是其中的NTC打印却也没有正常的输出。进行检查, 发现是因为CDC没有打开从而导致了串口数据从TX和RX输出了。所以我们需要开启CDC使其从USB输出。
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图7](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/194105f6vfs56vlf56msvg.png)
重新进行烧录,此时便可以看到开发板已经获取到了IP地址,并且获取了UTC的时间。
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图8](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/194207p9c0k0ccoko7hosm.png)
根据OPEN WRT的后台也可以看到,此时开发板的网络接入也正是5G频段。
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图9](https://mc.dfrobot.com.cn/data/attachment/forum/202510/18/194312nlcb8bf6gbhoxd8g.png)
然后将上述代码进行编辑,增加MQTT连接的部分,同时使用本地树莓派上的MQTT服务进行测试。
- #include <WiFi.h>
- #include <WiFiClient.h>
- #include <MQTT.h> // 256dpi/arduino-mqtt 库
- #include <NetworkUDP.h>
-
- #define STA_SSID "ImmortalWrt-5G"
- #define STA_PASS "mazha1997"
-
- #define AP_SSID "esp32-v6"
-
- // ====== MQTT 配置 ======
- #define MQTT_HOST "192.168.1.153" // 你可以改成自己的 MQTT 服务器地址
- #define MQTT_PORT 1884
- #define MQTT_USER "root" // 如果有用户名密码可以填上
- #define MQTT_PASS "123456"
- #define MQTT_CLIENT_ID "esp32-client"
-
- // ====== 全局变量 ======
- static volatile bool wifi_connected = false;
- NetworkUDP ntpClient;
- WiFiClient net;
- MQTTClient mqtt(256); // 建议设置缓存区大小,例如256字节
-
- // ====== NTP 同步函数 ======
- void wifiConnectedLoop() {
- const int NTP_PACKET_SIZE = 48;
- byte ntpPacketBuffer[NTP_PACKET_SIZE];
-
- IPAddress address;
- WiFi.hostByName("time.nist.gov", address);
- memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE);
- ntpPacketBuffer[0] = 0b11100011; // LI, Version, Mode
- ntpPacketBuffer[1] = 0;
- ntpPacketBuffer[2] = 6;
- ntpPacketBuffer[3] = 0xEC;
- ntpPacketBuffer[12] = 49;
- ntpPacketBuffer[13] = 0x4E;
- ntpPacketBuffer[14] = 49;
- ntpPacketBuffer[15] = 52;
- ntpClient.beginPacket(address, 123);
- ntpClient.write(ntpPacketBuffer, NTP_PACKET_SIZE);
- ntpClient.endPacket();
-
- delay(1000);
-
- int packetLength = ntpClient.parsePacket();
- if (packetLength >= NTP_PACKET_SIZE) {
- ntpClient.read(ntpPacketBuffer, NTP_PACKET_SIZE);
- ntpClient.clear();
- uint32_t secsSince1900 =
- (uint32_t)ntpPacketBuffer[40] << 24 |
- (uint32_t)ntpPacketBuffer[41] << 16 |
- (uint32_t)ntpPacketBuffer[42] << 8 |
- ntpPacketBuffer[43];
- uint32_t epoch = secsSince1900 - 2208988800UL;
- uint8_t h = (epoch % 86400L) / 3600;
- uint8_t m = (epoch % 3600) / 60;
- uint8_t s = (epoch % 60);
- Serial.printf("UTC: %02u:%02u:%02u (GMT)\n", h, m, s);
- }
- }
-
- // ====== MQTT 回调函数 ======
- void mqttMessageReceived(String &topic, String &payload) {
- Serial.print("MQTT message received: ");
- Serial.print(topic);
- Serial.print(" => ");
- Serial.println(payload);
- }
-
- // ====== MQTT 初始化连接 ======
- void mqttConnect() {
- Serial.print("Connecting to MQTT... ");
- while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS)) {
- Serial.print(".");
- delay(1000);
- }
- Serial.println("\nMQTT connected!");
- mqtt.subscribe("esp32/test");
- mqtt.publish("esp32/status", "ESP32 connected successfully!");
- }
-
- // ====== WiFi 事件处理 ======
- void wifiOnConnect() {
- Serial.println("STA Connected");
- Serial.print("STA IPv4: ");
- Serial.println(WiFi.localIP());
-
- ntpClient.begin(2390);
-
- // 初始化 MQTT
- mqtt.begin(MQTT_HOST, MQTT_PORT, net);
- mqtt.onMessage(mqttMessageReceived);
- mqttConnect();
- }
-
- void wifiOnDisconnect() {
- Serial.println("STA Disconnected");
- delay(1000);
- WiFi.begin(STA_SSID, STA_PASS);
- }
-
- void WiFiEvent(WiFiEvent_t event) {
- switch (event) {
- case ARDUINO_EVENT_WIFI_AP_START:
- WiFi.softAPsetHostname(AP_SSID);
- break;
- case ARDUINO_EVENT_WIFI_STA_START:
- WiFi.setHostname(AP_SSID);
- break;
- case ARDUINO_EVENT_WIFI_STA_GOT_IP:
- wifi_connected = true;
- wifiOnConnect();
- break;
- case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
- wifi_connected = false;
- wifiOnDisconnect();
- break;
- default:
- break;
- }
- }
-
- // ====== 初始化 ======
- void setup() {
- Serial.begin(115200);
- WiFi.disconnect(true);
- WiFi.onEvent(WiFiEvent);
- WiFi.mode(WIFI_MODE_APSTA);
-
- WiFi.softAPenableIPv6();
- WiFi.softAP(AP_SSID);
-
- WiFi.enableIPv6();
- WiFi.begin(STA_SSID, STA_PASS);
- }
-
- // ====== 主循环 ======
- void loop() {
- if (wifi_connected) {
- mqtt.loop(); // MQTT 保持连接和接收消息
- if (!mqtt.connected()) {
- mqttConnect();
- }
-
- static unsigned long lastMsg = 0;
- if (millis() - lastMsg > 10000) {
- lastMsg = millis();
- mqtt.publish("esp32/test", "Hello from ESP32!");
- wifiConnectedLoop(); // 每10秒打印时间
- }
- }
-
- while (Serial.available()) {
- Serial.write(Serial.read());
- }
- }
复制代码
然后我们可以成功的在MQTTX中查看到上传的消息。
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图10](https://mc.dfrobot.com.cn/data/attachment/forum/202510/22/195928il5k95ulru65xk75.png)
整合BH1750
接下来我们把BH1750也整合进去,实现光照数据的上报。
- #include <WiFi.h>
- #include <WiFiClient.h>
- #include <MQTT.h> // 256dpi/arduino-mqtt 库
- #include <NetworkUDP.h>
- #include <Wire.h>
- #include <BH1750.h> // BH1750 光照传感器库
-
- #define STA_SSID "ImmortalWrt-5G"
- #define STA_PASS "mazha1997"
-
- #define AP_SSID "esp32-v6"
-
- // ====== MQTT 配置 ======
- #define MQTT_HOST "192.168.1.153"
- #define MQTT_PORT 1884
- #define MQTT_USER "root"
- #define MQTT_PASS "123456"
- #define MQTT_CLIENT_ID "esp32-client"
-
- // ====== 全局变量 ======
- static volatile bool wifi_connected = false;
- NetworkUDP ntpClient;
- WiFiClient net;
- MQTTClient mqtt(256);
- BH1750 lightMeter; // BH1750 实例
-
- // ====== NTP 同步函数 ======
- void wifiConnectedLoop() {
- const int NTP_PACKET_SIZE = 48;
- byte ntpPacketBuffer[NTP_PACKET_SIZE];
-
- IPAddress address;
- WiFi.hostByName("time.nist.gov", address);
- memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE);
- ntpPacketBuffer[0] = 0b11100011; // LI, Version, Mode
- ntpPacketBuffer[1] = 0;
- ntpPacketBuffer[2] = 6;
- ntpPacketBuffer[3] = 0xEC;
- ntpPacketBuffer[12] = 49;
- ntpPacketBuffer[13] = 0x4E;
- ntpPacketBuffer[14] = 49;
- ntpPacketBuffer[15] = 52;
- ntpClient.beginPacket(address, 123);
- ntpClient.write(ntpPacketBuffer, NTP_PACKET_SIZE);
- ntpClient.endPacket();
-
- delay(1000);
-
- int packetLength = ntpClient.parsePacket();
- if (packetLength >= NTP_PACKET_SIZE) {
- ntpClient.read(ntpPacketBuffer, NTP_PACKET_SIZE);
- ntpClient.clear();
- uint32_t secsSince1900 =
- (uint32_t)ntpPacketBuffer[40] << 24 |
- (uint32_t)ntpPacketBuffer[41] << 16 |
- (uint32_t)ntpPacketBuffer[42] << 8 |
- ntpPacketBuffer[43];
- uint32_t epoch = secsSince1900 - 2208988800UL;
- uint8_t h = (epoch % 86400L) / 3600;
- uint8_t m = (epoch % 3600) / 60;
- uint8_t s = (epoch % 60);
- Serial.printf("UTC: %02u:%02u:%02u (GMT)\n", h, m, s);
- }
- }
-
- // ====== MQTT 回调函数 ======
- void mqttMessageReceived(String &topic, String &payload) {
- Serial.print("MQTT message received: ");
- Serial.print(topic);
- Serial.print(" => ");
- Serial.println(payload);
- }
-
- // ====== MQTT 初始化连接 ======
- void mqttConnect() {
- Serial.print("Connecting to MQTT... ");
- while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS)) {
- Serial.print(".");
- delay(1000);
- }
- Serial.println("\nMQTT connected!");
- mqtt.subscribe("esp32/test");
- mqtt.publish("esp32/status", "ESP32 connected successfully!");
- }
-
- // ====== WiFi 事件处理 ======
- void wifiOnConnect() {
- Serial.println("STA Connected");
- Serial.print("STA IPv4: ");
- Serial.println(WiFi.localIP());
-
- ntpClient.begin(2390);
-
- // 初始化 MQTT
- mqtt.begin(MQTT_HOST, MQTT_PORT, net);
- mqtt.onMessage(mqttMessageReceived);
- mqttConnect();
- }
-
- void wifiOnDisconnect() {
- Serial.println("STA Disconnected");
- delay(1000);
- WiFi.begin(STA_SSID, STA_PASS);
- }
-
- void WiFiEvent(WiFiEvent_t event) {
- switch (event) {
- case ARDUINO_EVENT_WIFI_AP_START:
- WiFi.softAPsetHostname(AP_SSID);
- break;
- case ARDUINO_EVENT_WIFI_STA_START:
- WiFi.setHostname(AP_SSID);
- break;
- case ARDUINO_EVENT_WIFI_STA_GOT_IP:
- wifi_connected = true;
- wifiOnConnect();
- break;
- case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
- wifi_connected = false;
- wifiOnDisconnect();
- break;
- default:
- break;
- }
- }
-
- // ====== 初始化 ======
- void setup() {
- Serial.begin(115200);
- Serial.println("ESP32 Booting...");
-
- // ===== 初始化 I2C 和 BH1750 =====
- Wire.begin(9, 10); // SDA=9, SCL=10
- if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
- Serial.println("BH1750 initialized successfully.");
- } else {
- Serial.println("BH1750 not detected! Check wiring.");
- }
-
- // ===== 初始化 Wi-Fi =====
- WiFi.disconnect(true);
- WiFi.onEvent(WiFiEvent);
- WiFi.mode(WIFI_MODE_APSTA);
-
- WiFi.softAPenableIPv6();
- WiFi.softAP(AP_SSID);
-
- WiFi.enableIPv6();
- WiFi.begin(STA_SSID, STA_PASS);
- }
-
- // ====== 主循环 ======
- void loop() {
- if (wifi_connected) {
- mqtt.loop(); // MQTT 保持连接
- if (!mqtt.connected()) {
- mqttConnect();
- }
-
- static unsigned long lastMsg = 0;
- if (millis() - lastMsg > 10000) {
- lastMsg = millis();
-
- // ===== 读取 BH1750 光照强度 =====
- float lux = lightMeter.readLightLevel();
- Serial.printf("Light intensity: %.2f lux\n", lux);
-
- // ===== 组装 JSON 并发布到 MQTT =====
- String payload = String("{"lux":") + String(lux, 2) + "}";
- mqtt.publish("esp32/bh1750", payload);
- Serial.println("Published: " + payload);
-
- // ===== 同步 NTP 时间 =====
- wifiConnectedLoop();
- }
- }
-
- while (Serial.available()) {
- Serial.write(Serial.read());
- }
- }
复制代码
此时可以看到控制台已经成功的发送了MQTT的消息
![FireBeetle 2 ESP32-C5 MQTT 数据上报 [5GHZ] 二图11](https://mc.dfrobot.com.cn/data/attachment/forum/202510/22/202404e3tee6fo161kmwyw.png)
|