构思:
蓝牙无线插座的硬件设备有:ESP32-WROOM-32、OLED(Organic Light-Emitting Diode)
显示模块、继电器、电源转换器、插头部件、插座部件。具体结构如下图所示。
硬件电路的基本工作流程如下:接通电源,模块220V的AC(Alternating current)电流转换成5V的DC(Direct Current)电流,整流电路将5V转为3.3V,ESP32可以获得稳定的电流并正常工作。用户可以用手机打开蓝牙并启动蓝牙APP,手机与插座配对蓝牙,继电器模块发送开启指令后,控制插座开关OLED屏幕开始运行,显示插座运行时间,并通过蓝牙向手机发送数据APP端。
标题
Arduino代码
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> #include <Wire.h> // 引入驱动OLED0.91所需的库 #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // 设置OLED单位:像素 #define SCREEN_HEIGHT 32 // 设置OLED高度,单位:像素 // 虽然教程没有使用
自定义重置引脚,但是Adafruit_SSD1306库文件库文件 #define OLED_RESET 4 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); BLEServer *pServer = NULL; BLECharacteristic * pTxCharacteristic; bool deviceConnected = false; bool oldDeviceConnected = false; bool deviceswitch = false; uint8_t txValue = 0; uint8_t runtime = 0; // See the following for generating UUIDs: // https://ww.uuidgenerator.net/ #define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue(); if (rxValue.length() > 0) { Serial.println("*********"); Serial.print("Received Value: "); for (int i = 0; i < rxValue.length(); i++) Serial.print(rxValue[i]); if(rxValue[0]=='a') { digitalWrite(2,HIGH);//open switch deviceswitch=true; runtime = millis() / 1000; } if(rxValue[0]=='b') { digitalWrite(2,LOW);//open switch deviceswitch=false; } Serial.println(); Serial.println("*********"); } } }; void setup() { Serial.begin(115200); pinMode(2,OUTPUT);//设置输出2脚 digitalWrite(2,LOW);//默认低电平 Wire.begin(/*SDA*/22,/*SCL*/21); // 初始化OLED并设置其IIC地址为 0x3C display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Create the BLE Device BLEDevice::init("UART Service"); // Create the BLE Server pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); // Create the BLE Service BLEService *pService = pServer->createService(SERVICE_UUID); // Create a BLE Characteristic pTxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY ); pTxCharacteristic->addDescriptor(new BLE2902()); BLECharacteristic * pRxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE ); pRxCharacteristic->setCallbacks(new MyCallbacks()); // Start the service pService->start(); // Start advertising pServer->getAdvertising()->start(); Serial.println("Waiting a client connection to notify..."); } void loop() { if (deviceConnected) { pTxCharacteristic->setValue(&txValue, 1); pTxCharacteristic->notify(); txValue++; delay(10); // bluetooth stack will go into congestion, if too many packets are sent } // disconnecting if (!deviceConnected && oldDeviceConnected) { delay(500); // give the bluetooth stack the chance to get things ready pServer->startAdvertising(); // restart advertising Serial.println("start advertising"); oldDeviceConnected = deviceConnected; } // connecting if (deviceConnected && !oldDeviceConnected) { // do stuff here on connecting oldDeviceConnected = deviceConnected; } if(deviceswitch==true) { words_display(); display.display(); //Serial.println("start advertising"); } } void words_display() { uint8_t runtime0 = (millis() / 1000)-runtime; // 清除屏幕 display.clearDisplay(); // 设置字体颜色,白色可见 display.setTextColor(WHITE); //设置字体大小 display.setTextSize(1.5); //设置光标位置 display.setCursor(0, 0); display.print("BLE SWITCH"); display.setCursor(0, 10); display.print("Run time: "); //打印自开发板重置以来的秒数: if(runtime0>3600) { display.print(runtime0/3600); display.print(" h"); } if(runtime0>60) { display.print(runtime0/60); display.print(" min"); } else { display.print(runtime0); display.print(" s"); } display.setCursor(0, 20); //Serial.println(runtime); //ESP.restart(); //ESP.reset(); }
最后说明一下,保存的代码有两个文件夹,如果上述不能使用请下载压缩包, 有论述性文章可供参考。