Differences

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

Link to this comparison view

iothings:proiecte:2023sric:smartled [2024/05/30 00:47]
dragos.petre [How it works]
iothings:proiecte:2023sric:smartled [2024/05/30 01:56] (current)
dragos.petre [Software]
Line 3: Line 3:
   * Email: <​dragso.petre@stud.acs.pub.ro>​   * Email: <​dragso.petre@stud.acs.pub.ro>​
   * Master: SCPD   * Master: SCPD
 +  * Video link: [[https://​youtu.be/​PxzQ7asWBro]]
 +  * Source Code: {{:​iothings:​proiecte:​2023sric:​petredragos_sourcecode.zip|}}
  
 ===== Overview ===== ===== Overview =====
Line 15: Line 17:
 ==== Hardware Components Used ==== ==== Hardware Components Used ====
   * **ESP32-WROOM-32**:​ 1 x ESP32 Sparrow development board (purchased from [[https://​www.emag.ro/​placa-dezvoltare-esp-wroom-32-esp-32s-cl398/​pd/​D3NF9VBBM/​|here]])   * **ESP32-WROOM-32**:​ 1 x ESP32 Sparrow development board (purchased from [[https://​www.emag.ro/​placa-dezvoltare-esp-wroom-32-esp-32s-cl398/​pd/​D3NF9VBBM/​|here]])
-  * **NeoPixel LED Strip**: 1 x 5m NeoPixel LED Strip (became ​4m after an accident =)) (300 NeoPixel LEDs for 5m or 270 NeoPixel LEDs for 4m)+  * **NeoPixel LED Strip**: 1 x 5m NeoPixel LED Strip (became ​4.5m after an accident =)) (300 NeoPixel LEDs for 5m or 270 NeoPixel LEDs for 4.5m)
   * **Breadboard**:​ 1 x 830 holes Breadboard   * **Breadboard**:​ 1 x 830 holes Breadboard
   * **OLED Display**: 1 x 0.91inch OLED Display   * **OLED Display**: 1 x 0.91inch OLED Display
Line 23: Line 25:
   * **Arduino IDE** for code development and Serial Monitor   * **Arduino IDE** for code development and Serial Monitor
   * **BLE Scanner Android App** for connecting my phone to the ESP32 board via BLE   * **BLE Scanner Android App** for connecting my phone to the ESP32 board via BLE
 +
 +=== Libraries needed ===
 +  * Adafruit_BusIO
 +  * Adafruit_GFX_Library
 +  * Adafruit_NeoPixel
 +  * Adafruit_SSD1306
 +  * ArduinoBLE
  
 ===== Architecture ===== ===== Architecture =====
Line 121: Line 130:
     mode = command;     mode = command;
   }   }
 +}
 +</​code>​
 +
 +=== Choose the lighting mode ===
 +<code cpp>
 +void loop() {
 +  // Check if the lights are turned on or off
 +  if (lightsOn) {
 +    unsigned long currentMillis = millis();
 +    if (currentMillis - previousMillis >= interval) {
 +      previousMillis = currentMillis;​
 +      updateLEDs();​
 +    }
 +  }
 +}
 +
 +// 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;
 +    if (mode == "​red"​) {
 +      setAllPixels(strip.Color(255,​ 0, 0));
 +    } else if (mode == "​blue"​) {
 +      setAllPixels(strip.Color(0,​ 0, 255));
 +    } else if (mode == "​yellow"​) {
 +      setAllPixels(strip.Color(255,​ 255, 0));
 +    } else if (mode == "​green"​) {
 +      setAllPixels(strip.Color(0,​ 255, 0));
 +    } else if (mode == "​purple"​) {
 +      setAllPixels(strip.Color(128,​ 0, 128));
 +    } else if (mode == "​orange"​) {
 +      setAllPixels(strip.Color(255,​ 100, 0)); // Adjusted towards red
 +    } else if (mode == "​cyan"​) {
 +      setAllPixels(strip.Color(0,​ 255, 255));
 +    } else if (command.find("​-"​) != std::​string::​npos) {
 +      mode = "​split";​
 +      std::string color1 = command.substr(0,​ command.find('​-'​));​
 +      std::string color2 = command.substr(command.find('​-'​) + 1);
 +      setSplitPixels(getColor(color1),​ getColor(color2));​
 +    }
 +    strip.show();​
 +  }
 +}
 +
 +// Set all the pixels to one color
 +void setAllPixels(uint32_t color) {
 +  for (int i = 0; i < NUM_LEDS; i++) {
 +    strip.setPixelColor(i,​ color);
 +  }
 +}
 +
 +// Set half the pixels to one color and the otehr half to the other
 +void setSplitPixels(uint32_t color1, uint32_t color2) {
 +  for (int i = 0; i < NUM_LEDS / 2; i++) {
 +    strip.setPixelColor(i,​ color1);
 +  }
 +  for (int i = NUM_LEDS / 2; i < NUM_LEDS; i++) {
 +    strip.setPixelColor(i,​ color2);
 +  }
 +  strip.show();​
 +}
 +
 +uint32_t getColor(const std::​string&​ color) {
 +  if (color == "​red"​) return strip.Color(255,​ 0, 0);
 +  if (color == "​blue"​) return strip.Color(0,​ 0, 255);
 +  if (color == "​yellow"​) return strip.Color(255,​ 255, 0);
 +  if (color == "​green"​) return strip.Color(0,​ 255, 0);
 +  if (color == "​purple"​) return strip.Color(128,​ 0, 128);
 +  if (color == "​orange"​) return strip.Color(242,​ 133, 0);
 +  if (color == "​cyan"​) return strip.Color(0,​ 255, 255);
 +  return strip.Color(0,​ 0, 0); // Default to black if color not recognized
 +}
 +
 +// Run the selected mode
 +void updateLEDs() {
 +  if (mode == "​cycle"​) {
 +    cycleColors();​
 +  } else if (mode == "​rainbow"​) {
 +    rainbowCycle();​
 +  } else if (mode == "​snake"​) {
 +    snakeMode();​
 +  } else if (mode == "​random_blink"​) {
 +    randomBlink();​
 +  }
 +}
 +
 +// Function to cycle through colors
 +void cycleColors() {
 +  static int currentColor = 0;
 +  uint32_t colors[] = {
 +    strip.Color(255,​ 0, 0),    // Red
 +    strip.Color(0,​ 0, 255),    // Blue
 +    strip.Color(255,​ 255, 0),  // Yellow
 +    strip.Color(0,​ 255, 0),    // Green
 +    strip.Color(128,​ 0, 128),  // Purple
 +    strip.Color(242,​ 132, 0),  // Orange
 +    strip.Color(0,​ 255, 255)   // Cyan
 +  };
 +  setAllPixels(colors[currentColor]);​
 +  currentColor = (currentColor + 1) % 7;
 +  strip.show();​
 +}
 +
 +// Function that lights the LED strip in an evolving rainbow
 +void rainbowCycle() {
 +  static uint16_t j = 0;
 +  for (int i = 0; i < strip.numPixels();​ i++) {
 +    strip.setPixelColor(i,​ Wheel((i + j) & 255));
 +  }
 +  strip.show();​
 +  j++;
 +  if (j >= 256) j = 0;
 +}
 +
 +// Auxilary function that helps the rainbow function
 +uint32_t Wheel(byte WheelPos) {
 +  WheelPos = 255 - WheelPos;
 +  if (WheelPos < 85) {
 +    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
 +  }
 +  if (WheelPos < 170) {
 +    WheelPos -= 85;
 +    return strip.Color(0,​ WheelPos * 3, 255 - WheelPos * 3);
 +  }
 +  WheelPos -= 170;
 +  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
 +}
 +
 +// Build a snake that slitters through the light strip
 +void snakeMode() {
 +  static int head = 0;
 +  strip.clear();​
 +  for (int i = 0; i < 10; i++) {
 +    int pos = (head - i + NUM_LEDS) % NUM_LEDS;
 +    strip.setPixelColor(pos,​ strip.Color(0,​ 255 - i * 25, 0)); // Body is darker green
 +  }
 +  strip.show();​
 +  head = (head + 1) % NUM_LEDS;
 +}
 +
 +// Function that makes the light strip to blink random LEDs with random colors
 +void randomBlink() {
 +  strip.clear();​
 +  for (int i = 0; i < NUM_LEDS; i++) {
 +    if (random(10) < 2) {
 +      strip.setPixelColor(i,​ strip.Color(random(256),​ random(256),​ random(256)));​
 +    }
 +  }
 +  strip.show();​
 +}
 +</​code>​
 +
 +=== Display setup and printing ===
 +<code cpp>
 +// OLED display settings
 +#define SCREEN_WIDTH 128
 +#define SCREEN_HEIGHT 32
 +#define OLED_RESET -1
 +Adafruit_SSD1306 display(SCREEN_WIDTH,​ SCREEN_HEIGHT,​ &Wire, OLED_RESET);​
 +
 +void setup() {
 +  // Initialize the OLED display
 +  // Address 0x3C for 128x32 OLED display
 +  if(!display.begin(SSD1306_SWITCHCAPVCC,​ 0x3C)) {
 +    Serial.println(F("​SSD1306 allocation failed"​));​
 +    for(;;);
 +  }
 +  display.display();​
 +  delay(2000);​ // Pause for 2 seconds
 +  display.clearDisplay();​
 +}
 +
 +void loop() {
 +  // Update the display with the current status
 +  updateDisplay();​
 +}
 +
 +// Update the OLED display with the current status
 +void updateDisplay() {
 +  display.clearDisplay();​
 +  display.setTextSize(1);​
 +  display.setTextColor(SSD1306_WHITE);​
 +
 +  // Show if any device is connected
 +  display.setCursor(0,​ 0);
 +  display.print("​Device:​ ");
 +  display.print(deviceConnected ? "​Connected"​ : "​Disconnected"​);​
 +
 +  // Show if the lights are on or off
 +  display.setCursor(0,​ 10);
 +  display.print("​Lights:​ ");
 +  display.print(lightsOn ? "​On"​ : "​Off"​);​
 +
 +  // Show the current lighting mode
 +  display.setCursor(0,​ 20);
 +  display.print("​Mode:​ ");
 +  display.print(mode.c_str());​
 +
 +  display.display();​
 } }
 </​code>​ </​code>​
 ==== How it works ==== ==== How it works ====
-{{ :​iothings:​proiecte:​2023sric:​petredragos_ble_service.jpg?​200 |}} +=== Main service page === 
-{{ :​iothings:​proiecte:​2023sric:​petredragos_static.jpg?​200 |}} +{{ :​iothings:​proiecte:​2023sric:​petredragos_ble_service.jpg?​300 |}} 
-{{ :​iothings:​proiecte:​2023sric:​petredragos_split.jpg?​200 |}} +=== Command for a static color === 
-{{ :​iothings:​proiecte:​2023sric:​petredragos_cycle.jpg?​200 |}} +{{ :​iothings:​proiecte:​2023sric:​petredragos_static.jpg?​300 |}} 
-{{ :​iothings:​proiecte:​2023sric:​petredragos_rainbow.jpg?​200 |}} +=== Command for splitting the strip in 2 colors === 
-{{ :​iothings:​proiecte:​2023sric:​peterdragos_snake.jpg?​200 |}} +{{ :​iothings:​proiecte:​2023sric:​petredragos_split.jpg?​300 |}} 
-{{ :​iothings:​proiecte:​2023sric:​petredragos_random.jpg?​200 |}}+=== Command for cycling through colors === 
 +{{ :​iothings:​proiecte:​2023sric:​petredragos_cycle.jpg?​300 |}} 
 +=== Command for having a rainbow show === 
 +{{ :​iothings:​proiecte:​2023sric:​petredragos_rainbow.jpg?​300 |}} 
 +=== Command for having a snake-like moving === 
 +{{ :​iothings:​proiecte:​2023sric:​peterdragos_snake.jpg?​300 |}} 
 +=== Command for lighting-up random LEDs with random colors === 
 +{{ :​iothings:​proiecte:​2023sric:​petredragos_random.jpg?​300 |}}
 ===== Challenges ===== ===== Challenges =====
 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. 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.
Line 142: Line 362:
 First of all, buy a better development board, one that has at leas a LTR308 module on it. 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. After that, I will implement the automatic light detection function and have the lights start automatically when it becomes dark in the room.
 +I also have to actually fix the connection that I screwed up and had to glue together.
 +Lastly, I have to find a way to mount this thing.
  
 ===== Resources ===== ===== Resources =====
 +  * IoT Laboratories 
 +  * Lots of sites, especially StackOverflow (for debugging ;-))
iothings/proiecte/2023sric/smartled.1717019274.txt.gz · Last modified: 2024/05/30 00:47 by dragos.petre
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