Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iothings:proiecte:2025sric:ledstrip [2025/04/10 08:35]
andrei.besliu created
iothings:proiecte:2025sric:ledstrip [2025/05/29 00:48] (current)
andrei.besliu [ESP32 Web-based LED strip]
Line 1: Line 1:
-Web-based LED strip.+====== ESP32 BLE-based LED strip ======
  
-Provide smart lighting to a home using an RGB LED strip and an ESP32. The ESP32 will act as a web server, ​accessible ​from devices such as a smartphone ​or desktop PC.+  * Author: Besliu Andrei-Cornel 
 +  * Email: andrei.besliu@stud.acs.pub.ro 
 +  * Master: SCPD 
 +  * Video Link: https://​youtu.be/​Q6bHqYo0OGY 
 +  * Source Code: {{:​iothings:​proiecte:​2025sric:​besliu_andrei_iot.zip}} 
 +====== Introduction ====== 
 + 
 +Provide smart lighting to a home using an RGB LED strip and an ESP32. The ESP32 will expose a BLE server that can receive commands from any BLE client. To prove functionality I implemented some simple features such as selecting from number of preset colors and adjusting brightness. 
 + 
 + 
 +====== Hardware ====== 
 +  * **ESP32-WROOM-32:​** 1 x ESP32 Sparrow development board  
 +  * **NeoPixel LED Strip:** 1 x 5m NeoPixel LED strip, 300 LED'​s. 
 +  * **Breadboard:​** 1x Breadboard for securing connections. 
 +  * **Connecting Cables** 
 +  * **USB-A to micro USB cable** 
 +====== Diagram ====== 
 + 
 +{{ :​iothings:​proiecte:​2025sric:​diagram_ledstrip.png }} 
 + 
 +====== Actual Hardware ====== 
 + 
 +{{ :​iothings:​proiecte:​2025sric:​actualHw_ledStrip.jpeg?​500 |}} 
 + 
 +The NeoPixel LED strip need +5V and GND to power the LED's and the addresing is done using a single data pin, which I have connected to GPIO 17. 
 +====== Software ====== 
 + 
 +   * Arduino IDE for development 
 +   * Adafruit_NeoPixel library for easy LED strip manipulation 
 +   * ArduinoBLE library for Bluetooth service. 
 + 
 +====== Code Snippets ====== 
 +Setting up BLE service with 2 Characteristics,​ one for setting the color and one for setting the brightness. The color receives a string 
 +with the desired color ("​red",​ "​blue",​ "​yellow",​ "​green",​ "​purple",​ "​orange",​ "​cyan"​) and the brightness is a single 8-bit value where 0 is off and 255 is the highest possible brightness. 
 + 
 +<code C++> 
 +// BLE server ​callback 
 +class MyServerCallbacks:​ public BLEServerCallbacks { 
 +  void onConnect(BLEServer* pServer) { 
 +    deviceConnected = true; 
 +  }; 
 + 
 +  void onDisconnect(BLEServer* pServer) { 
 +    deviceConnected = false; 
 +  } 
 +}; 
 + 
 +/* BLE Characteristics */ 
 +BLECharacteristic *colorCharacteristic;​ 
 +class ColorCallback:​ public BLECharacteristicCallbacks { 
 +  void onWrite(BLECharacteristic *colorCharacteristic) { 
 +    receivedColor = colorCharacteristic->​getValue();​ 
 +    if (receivedColor.length() > 0) { 
 +      Serial.print("​Received Color: "); 
 +      Serial.println(receivedColor.c_str());​ 
 +    } 
 +  } 
 +}; 
 + 
 +BLECharacteristic *brightCharacteristic;​ 
 +class BrightnessCallback:​ public BLECharacteristicCallbacks { 
 +  void onWrite(BLECharacteristic *brightCharacteristic) { 
 +    receivedBrightness = brightCharacteristic->​getValue().c_str()[0];​ 
 +    Serial.print("​Received Brightness: "); 
 +    Serial.println(receivedBrightnessDEC); 
 +  } 
 +}; 
 + 
 +[ ... ] 
 + 
 +// Initialize BLE 
 +BLEDevice::​init("​ESP32_LED_Strip"​);​ 
 +BLEServer *pServer = BLEDevice::​createServer();​ 
 +pServer->​setCallbacks(new MyServerCallbacks());​ 
 + 
 +BLEService *bmeService = pServer->​createService(SERVICE_UUID);​ 
 + 
 +// Create colorCharacteristic 
 +colorCharacteristic = bmeService->​createCharacteristic( 
 +                    COLOR_UUID,​ 
 +                    BLECharacteristic::​PROPERTY_READ | 
 +                    BLECharacteristic::​PROPERTY_WRITE 
 +                ); 
 +colorCharacteristic->​setCallbacks(new ColorCallback());​ 
 +colorCharacteristic->​setValue("​Hello,​ World!"​);​ 
 + 
 +// Create colorCharacteristic 
 +brightCharacteristic = bmeService->​createCharacteristic( 
 +                    BRIGHTNESS_UUID,​ 
 +                    BLECharacteristic::​PROPERTY_READ | 
 +                    BLECharacteristic::​PROPERTY_WRITE 
 +                ); 
 +brightCharacteristic->​setCallbacks(new BrightnessCallback());​ 
 +int defaultBrightness = 255; 
 +brightCharacteristic->​setValue(defaultBrightness);​ 
 + 
 +// Start bme service. 
 +bmeService->​start();​ 
 + 
 +// Start Advertising 
 +pServer->​getAdvertising()->​start();​ 
 +Serial.println("​Waiting a client connection to notify..."​);​ 
 + 
 +</​code>​ 
 + 
 +Setting up the LedStrip and control logic is straight-forward. We have global variables holding the current state of the strip that get update on BLECallback triggers. We also have a chgStrip boolean that prevents unneccesary updating of the LedStrip if no changes are currently performed. 
 +<code c++> 
 +// Initialize the NeoPixel library 
 +strip.begin();​ 
 +// Set all pixels to '​off'​ 
 +strip.show();​ 
 + 
 +// Set some default strip values; 
 +actualBrightness = 128; 
 +actualColor = strip.Color(0,​ 75, 0); // moderately bright green 
 +chgStrip = true; 
 + 
 +[ ... ] 
 + 
 +// Check if a device was connected 
 +if (deviceConnected) { 
 +  if (!receivedColor.isEmpty()) { 
 +    actualColor = getColor(receivedColor);​ 
 +    receivedColor = "";​ 
 +    chgStrip = true; 
 +  } 
 + 
 +  if (receivedBrightness != 0) { 
 +    actualBrightness = receivedBrightness;​ 
 +    receivedBrightness = 0; 
 +    chgStrip = true; 
 +  } 
 +
 + 
 +// Update Strip. 
 +if (chgStrip) { 
 +  strip.clear();​ 
 +  
 +  for(int i=0; i<​NUM_PIXELS;​ i++) { // For each pixel... 
 +    strip.setPixelColor(i,​ actualColor);​ 
 +  } 
 + 
 +  strip.setBrightness(actualBrightness);​ 
 +  strip.show();​ 
 + 
 +  // Do not change strip next cycle 
 +  chgStrip = false; 
 +
 + 
 +</​code>​ 
 +====== Challenges ====== 
 + 
 +Not having proper soldering tools leads to bad electrical contacts and makes it a nightmare to debug any issues. Thankfully, jamming a wire through the ESP32 DevBoard pins worked brilliantly,​ just don't ask me to move it anywhere. 
 + 
 +Initially I wanted to use both BLE and a webpage hosted on the ESP32 itself to allow control of the LED strip from multiple sources but due to memory constraints on the ESP32 I had to choose only one (91% memory usage with the BLE implementation alone). 
 + 
 +I find it very annoying how BLE handles characteristics,​ only having a predefined set of BLEUUID'​s available to pick and choose from. For example, the was no readily available UUID for brightness or color, just a generic "LED Array" or "Led Strip"​. 
 + 
 +I choose BLE due to the easy implementaion ​as baking-in ​HTML page in the Arduino IDE seems janky to me. The right way to approach would be by installing a lightweight RTOS such as NuttX or freeRTOS and ditching the BLE for a more customizable webpage, as in our case  battery and power constraints are irrelevant. 
 + 
 +====== References ====== 
 +  * Adafruit_NeoPixel:​ https://​github.com/​adafruit/​Adafruit_NeoPixel 
 +  * ArduinoBle: https://​docs.arduino.cc/​libraries/​arduinoble/​ 
 +  * Our OCW labs. 
 +  * Some helpful StackOverflow threads.
iothings/proiecte/2025sric/ledstrip.1744263317.txt.gz · Last modified: 2025/04/10 08:35 by andrei.besliu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0