This is an old revision of the document!
The idea for this project came as I wanted to add some backlight to my computer and desk so that it would be more cozy especially during the night. I wanted to be able to have more mods and have a finer control on the LEDs, so I chose a NeoPixels LED Strip, where I can control each LED of the Strip individually.
For the communication protocol between the ESP32 controller and my phone, I decided to use the Bluetooth LowEnergy protocol. I will use my phone as a remote control to send commands to the ESP32 controller and control the LED strip.
I used an OLED display as a way to better visualize the current status of the system, like if there is a device connected, if the lights are turned on or of, and what mode is currently selected.
// BLE settings #define SERVICE_UUID "LED12345-1234-1234-1234-123456789LED" #define CHARACTERISTIC_UUID "87654321-4321-4321-4321-LED987654321" BLECharacteristic *pCharacteristic; bool deviceConnected = false; std::string receivedValue; // BLE server callback class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; // BLE characteristic callback class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { receivedValue = pCharacteristic->getValue(); if (receivedValue.length() > 0) { Serial.print("Received Value: "); Serial.println(receivedValue.c_str()); } } }; void setup() { Serial.begin(115200); // Initialize the NeoPixel library strip.begin(); // Set all pixels to 'off' strip.show(); // Initialize BLE BLEDevice::init("ESP32_LED_Control"); BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); pCharacteristic->setValue("Hello, World!"); pService->start(); BLEAdvertising *pAdvertising = pServer->getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->setScanResponse(true); pAdvertising->setMinPreferred(0x06); pAdvertising->setMinPreferred(0x12); BLEDevice::startAdvertising(); Serial.println("Waiting for a client connection to notify..."); }
void loop() { // Check if a device was connected if (deviceConnected) { if (!receivedValue.empty()) { handleCommand(receivedValue); receivedValue = ""; } } } // Function that handles the commands got from the Phone via BLE void handleCommand(const std::string& command) { if (command == "off") { lightsOn = false; strip.clear(); strip.show(); } else { lightsOn = true; mode = command; } }
Initially, I wanted to use both WiFi and BLE to control the LED Strip, but I had to limit myself to just one of them, so I chose BLE. The issue was that the WiFi library was just too big in size, taking over 59% of the text memory on my development board, so I dropped it.
By dropping the WiFi features, I had to drop the automatic time triggering as I could not set the time. To set the time to the Local Time, i would have to use a NTP server, but without the WiFi library, I could not connect to one. One other option was to pass the time as a parameter when the code is flashed on the board, but this is not optimal. Other option is to pass it as a command through my phone, but this just destroys the purpose of it being automatic.
Lastly, I found to my surprise that the ESP32 development board I have bought has not a LTR308 module on it, so I was unable to set an automatic detection of light in the room and trigger the light when needed.
First of all, buy a better development board, one that has at leas a LTR308 module on it. After that, I will implement the automatic light detection function and have the lights start automatically when it becomes dark in the room.