controlling NeoPixel RGB strip

Opera GX → MQTT → Raspberry Pi → ESP32 → NeoPixel RGB

Control a NeoPixel RGB Strip with Opera GX (MQTT + Raspberry Pi + ESP32 – Full Working Guide)

This article documents a fully tested and working setup where changing the Accent Color in Opera GX instantly changes the color of a physical NeoPixel (WS2812) RGB strip.

Opera GX → MQTT (Mosquitto on Raspberry Pi) → Python Bridge → USB Serial → ESP32 → NeoPixel RGB Strip


1. Requirements

1.1 Hardware

  • Raspberry Pi (any model)
  • ESP32 board
  • NeoPixel / WS2812 RGB strip (3 wires: 5V, GND, DATA)
  • USB data cable (ESP32 ↔ Raspberry Pi)
  • 5V power supply (required for larger LED counts)

1.2 Wiring

NeoPixel StripESP32
5V5V
GNDGND
DATAGPIO13 (recommended) or GPIO4
Important: GND must be shared between the RGB strip and the ESP32. If you use an external 5V power supply for the strip, connect its GND to ESP32 GND.

2. ESP32 Firmware (Final Working Code)

This firmware listens for text commands over Serial (RED, GREEN, BLUE, OFF, …), controls the RGB strip, prints READY at boot, and confirms each command with OK ....

#include <Adafruit_NeoPixel.h>

#define LED_PIN   13      // Stable pin for NeoPixel
#define LED_COUNT 30      // Change to match your strip length

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
String line;

void setAll(uint8_t r, uint8_t g, uint8_t b) {
  for (int i = 0; i < LED_COUNT; i++) {
    strip.setPixelColor(i, strip.Color(r, g, b));
  }
  strip.show();
}

void handleCmd(String s) {
  s.trim();
  s.toUpperCase();

  if (s == "OFF")     { setAll(0,0,0);         Serial.println("OK OFF"); return; }
  if (s == "RED")     { setAll(255,0,0);       Serial.println("OK RED"); return; }
  if (s == "GREEN")   { setAll(0,255,0);       Serial.println("OK GREEN"); return; }
  if (s == "BLUE")    { setAll(0,0,255);       Serial.println("OK BLUE"); return; }
  if (s == "WHITE")   { setAll(255,255,255);   Serial.println("OK WHITE"); return; }
  if (s == "YELLOW")  { setAll(255,255,0);     Serial.println("OK YELLOW"); return; }
  if (s == "CYAN")    { setAll(0,255,255);     Serial.println("OK CYAN"); return; }
  if (s == "MAGENTA") { setAll(255,0,255);     Serial.println("OK MAGENTA"); return; }
  if (s == "ORANGE")  { setAll(255,120,0);     Serial.println("OK ORANGE"); return; }
  if (s == "PURPLE")  { setAll(140,0,255);     Serial.println("OK PURPLE"); return; }

  Serial.print("ERR ");
  Serial.println(s);
}

void setup() {
  Serial.begin(115200);
  delay(2000); // USB/Serial stabilization

  strip.begin();
  strip.setBrightness(80);
  strip.clear();
  strip.show();

  Serial.println("READY");
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();
    if (c == '\r') continue;

    if (c == '\n') {
      if (line.length()) handleCmd(line);
      line = "";
    } else {
      line += c;
      if (line.length() > 64) line = "";
    }
  }
}

3. Raspberry Pi Setup

3.1 Install Required Packages

sudo apt update
sudo apt install -y mosquitto mosquitto-clients python3-serial python3-paho-mqtt

3.2 Enable MQTT Broker

sudo systemctl enable mosquitto
sudo systemctl start mosquitto
sudo systemctl status mosquitto

3.3 Find ESP32 Serial Port

ls -l /dev/serial/by-id/

You should see a stable path like:
/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0


4. Python Bridge: MQTT → Serial

Create the Script

nano ~/gx_rgb_serial.py

Full Working Code

#!/usr/bin/env python3
import serial
import time
import paho.mqtt.client as mqtt

SERIAL_PORT = "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0"
BAUD = 115200

MQTT_BROKER = "localhost"
MQTT_TOPIC  = "gx/rgb"

print("[SERIAL] using:", SERIAL_PORT)
ser = serial.Serial(SERIAL_PORT, BAUD, timeout=1)
time.sleep(0.5)

# Wait for READY from ESP32
start = time.time()
while time.time() - start < 5:
    line = ser.readline().decode(errors="ignore").strip()
    if line:
        print("[SERIAL] rx:", line)
    if line == "READY":
        break

def on_connect(client, userdata, flags, rc):
    print("[MQTT] connected:", rc)
    client.subscribe(MQTT_TOPIC)

def on_message(client, userdata, msg):
    cmd = msg.payload.decode().strip()
    print("[MQTT] cmd:", cmd)
    ser.write((cmd + "\n").encode())
    ser.flush()

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect(MQTT_BROKER, 1883, 60)
client.loop_forever()

5. Find Raspberry Pi IP Address (Host)

hostname -I

Example output:

192.168.1.50

Use this IP address in Opera GX as the MQTT Host with port 1883. Both devices must be on the same local network.


6. Opera GX → RGB Color Bridge

Opera GX publishes its accent color as a HEX value (for example #FF9900). This script converts it to the nearest named color and sends it to gx/rgb.

nano ~/opera_to_gx_rgb.py
#!/usr/bin/env python3
import paho.mqtt.client as mqtt

MQTT_BROKER = "localhost"
OPERA_TOPIC = "opera/+/sensor/accent_color"
OUT_TOPIC   = "gx/rgb"

PALETTE = {
    "RED": (255,0,0), "GREEN": (0,255,0), "BLUE": (0,0,255),
    "WHITE": (255,255,255), "YELLOW": (255,255,0),
    "CYAN": (0,255,255), "MAGENTA": (255,0,255),
    "ORANGE": (255,120,0), "PURPLE": (140,0,255)
}

def hex_to_rgb(h):
    h = h.lstrip("#")
    return tuple(int(h[i:i+2],16) for i in (0,2,4))

def nearest(rgb):
    return min(PALETTE, key=lambda k:
        sum((rgb[i]-PALETTE[k][i])**2 for i in range(3)))

def on_connect(c,u,f,rc):
    c.subscribe(OPERA_TOPIC)

def on_message(c,u,m):
    rgb = hex_to_rgb(m.payload.decode())
    c.publish(OUT_TOPIC, nearest(rgb))

c = mqtt.Client()
c.on_connect = on_connect
c.on_message = on_message
c.connect(MQTT_BROKER,1883,60)
c.loop_forever()

7. Run Everything

python3 ~/gx_rgb_serial.py
python3 ~/opera_to_gx_rgb.py
Now changing the Opera GX accent color will instantly change the NeoPixel RGB strip.

8. Increasing LED Count

#define LED_COUNT 60

WS2812 LEDs can draw up to ~60mA per LED at full white. Use an external 5V power supply for more than 30–40 LEDs.


References

  • Adafruit NeoPixel Library: https://github.com/adafruit/Adafruit_NeoPixel
  • NeoPixel Power Guide: https://learn.adafruit.com/adafruit-neopixel-uberguide
  • Mosquitto MQTT: https://mosquitto.org/

End of guide. This setup is stable, reproducible, and fully working.

Previous Post Next Post

نموذج الاتصال