ESP32蓝牙开关DIY:从硬件选型到APP控制全流程(附OLED显示)

张开发
2026/4/16 20:49:52 15 分钟阅读

分享文章

ESP32蓝牙开关DIY:从硬件选型到APP控制全流程(附OLED显示)
ESP32蓝牙开关DIY从硬件选型到APP控制全流程附OLED显示周末在家捣鼓智能家居设备时突然想到为什么不自己动手做个蓝牙开关既能远程控制电器又能学习物联网技术一举两得。经过两周的折腾终于完成了这个基于ESP32的蓝牙开关项目期间踩了不少坑也积累了不少实战经验。下面就把这个项目的完整实现过程分享给大家从硬件选型到代码编写再到手机APP控制手把手教你打造属于自己的智能开关。1. 硬件选型与电路设计选择适合的硬件组件是项目成功的第一步。经过多次对比测试我最终确定了以下核心部件主控芯片ESP32-WROOM-32D模块双核240MHz处理器内置蓝牙4.2和WiFi丰富的外设接口性价比极高显示模块0.96寸OLED屏幕SSD1306驱动I2C接口128x64分辨率低功耗适合嵌入式应用继电器模块5V单路继电器最大负载10A/250V AC光耦隔离安全可靠电源模块AC-DC降压模块输入220V AC输出5V/3A DC配合AMS1117稳压至3.3V电路连接注意事项电源部分220V交流电接入务必做好绝缘处理建议使用带保险丝的电源模块ESP32的供电电压严格控制在3.3V信号连接ESP32 GPIO22 → OLED SDA ESP32 GPIO21 → OLED SCL ESP32 GPIO2 → 继电器IN安全提示高压电路部分建议使用现成的电源模块非专业人士请勿直接处理220V交流电2. 开发环境搭建与基础配置工欲善其事必先利其器。在开始编码前需要准备好开发环境安装Arduino IDE从官网下载最新版本安装ESP32开发板支持包# 在Arduino首选项中添加开发板管理器网址 https://dl.espressif.com/dl/package_esp32_index.json安装必要库文件BLEDeviceESP32蓝牙核心库Adafruit_SSD1306OLED驱动库Adafruit_GFX图形库开发板设置选择ESP32 Dev ModuleFlash Mode设为QIOFlash Size选择4MB(32Mb)常见问题排查问题现象可能原因解决方案上传失败端口被占用关闭串口监视器再试OLED不显示I2C地址错误尝试0x3C或0x3D蓝牙不可见供电不足检查3.3V电压是否稳定3. BLE服务实现与代码解析蓝牙低功耗(BLE)是项目的核心功能下面详细解析关键代码// BLE服务定义 #define SERVICE_UUID 6E400001-B5A3-F393-E0A9-E50E24DCCA9E #define CHAR_RX_UUID 6E400002-B5A3-F393-E0A9-E50E24DCCA9E #define CHAR_TX_UUID 6E400003-B5A3-F393-E0A9-E50E24DCCA9E // 初始化BLE设备 BLEDevice::init(SmartSwitch); BLEServer *pServer BLEDevice::createServer(); pServer-setCallbacks(new MyServerCallbacks()); // 创建BLE服务 BLEService *pService pServer-createService(SERVICE_UUID); // 创建特征值 BLECharacteristic *pRxChar pService-createCharacteristic( CHAR_RX_UUID, BLECharacteristic::PROPERTY_WRITE ); pRxChar-setCallbacks(new MyCallbacks());代码关键点说明UUID生成使用在线UUID生成器创建唯一标识服务UUID和特征UUID需要匹配回调函数实现void MyCallbacks::onWrite(BLECharacteristic *pChar) { std::string value pChar-getValue(); if(value ON) digitalWrite(RELAY_PIN, HIGH); else if(value OFF) digitalWrite(RELAY_PIN, LOW); }连接状态管理设备连接/断开时更新状态标志断开后自动重新广播4. OLED显示功能实现OLED屏可以直观展示设备状态增强用户体验// 初始化OLED display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); // 显示状态信息 void updateDisplay(bool state, unsigned long uptime) { display.clearDisplay(); display.setCursor(0,0); display.print(BLE Switch); display.setCursor(0,16); display.print(state ? Status: ON : Status: OFF); display.setCursor(0,32); display.print(Uptime: ); display.print(uptime/60); display.print(m); display.display(); }显示优化技巧使用display.display()仅在内容变化时刷新避免频繁全屏刷新延长OLED寿命添加简单的动画效果提升观感5. 手机APP控制方案完成硬件和固件后还需要手机端控制方案使用现成APPnRF Connect调试用BLE Scanner基础控制支持自定义指令发送自主开发APPAndroid可以使用MIT App InventoriOS推荐使用Swift开发关键功能设备扫描与连接指令发送ON/OFF状态显示微信小程序方案通过蓝牙API实现控制无需安装使用方便APP控制指令格式指令功能返回值ON打开继电器当前状态OFF关闭继电器当前状态STAT获取状态ON/OFF6. 项目优化与扩展思路基础功能实现后可以考虑以下优化方向功耗优化启用ESP32的深度睡眠模式降低蓝牙广播频率动态调整CPU频率功能扩展添加WiFi双模控制集成定时任务功能增加温度传感器监测安全增强添加配对密码实现指令加密固件OTA升级进阶改进建议使用PCB代替杜邦线连接提高可靠性设计3D打印外壳提升美观度开发多设备组网功能7. 常见问题与解决方案在项目实施过程中我遇到了不少问题以下是典型问题及解决方法蓝牙连接不稳定检查天线设计确保没有被金属屏蔽调整广播间隔为100-200ms降低发射功率减少干扰继电器误动作// 添加软件去抖 void setRelay(bool state) { static unsigned long lastTime 0; if(millis() - lastTime 500) { digitalWrite(RELAY_PIN, state); lastTime millis(); } }OLED显示残影定期执行全屏刷新降低对比度检查电源稳定性调试技巧使用串口打印调试信息时建议采用JSON格式便于解析和分析{ status: connected, relay: off, uptime: 125 }8. 项目总结与心得这个项目从构思到完成大约用了两周时间期间最大的收获不是最终成品而是解决问题的过程。印象最深的是蓝牙连接不稳定的问题花了三天时间才发现是电源模块的纹波太大导致的。还有一次OLED突然不显示了最后发现是I2C上拉电阻没焊好。几个实用建议给想尝试的朋友购买元件时多买几个备用特别是便宜的模块善用开源社区很多问题都能找到答案复杂功能分阶段实现先确保基础功能正常最让我满意的是这个开关现在控制着我的书房台灯每天用手机就能开关OLED还能显示累计使用时间既实用又有成就感。下一步我打算给它加上WiFi功能实现远程控制到时候再和大家分享经验。

更多文章