ESP32 + MQTT + OpenHAB

Hallo an alle, die letzten Tage habe ich mit den LED-Stripes experimentiert und sie tatsächlich zum laufen bekommen. Jetzt habe ich ein 5 Meter Neopixel ws2812b Stripe und habe auch schon ein Programm dafür geschrieben. Allerdings flackern die LEDs so: https://1drv.ms/v/s!ApwRFzdtBkGqg5cGsoZUigPgdA_6Hg Die LEDs Flackern immer, egal ob ein fest definiertes Programm oder Farbwerte. Ich verwende ein externes 5V 3A Netzteil. Hier mein Programm:

// Adafruit_NeoPixel
#define PIN            19
#define NUMPIXELS      300
int delayval = 20;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

// WIFI
const char* ssid = "Philipp";
const char* password = "PW";

// MQTT
const char* mqtt_server = "192.168.200.1";

// INIT
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

// Pin
const int ledPin = 19;

// Var
int sMode = 0;
int A = 0;
int Bs = 0;

int R = 0;
int G = 0;
int B = 0;
// SETUP

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  #if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code
  pixels.begin(); // This initializes the NeoPixel library.
}



void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}




void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic esp32/output, you check if the message is either "on" or "off". 
  // Changes the output state according to the message
  if (String(topic) == "/WandLED/Mode") {
    Serial.print("WandLED Modus: ");
    Serial.println(messageTemp);
    sMode = messageTemp.toInt();
  }
  if (String(topic) == "/WandLED/R") {
    Serial.print("WandLED R: ");
    Serial.println(messageTemp);
    R = messageTemp.toInt();
  }
  if (String(topic) == "/WandLED/G") {
    Serial.print("WandLED G: ");
    Serial.println(messageTemp);
    G = messageTemp.toInt();
  }
  if (String(topic) == "/WandLED/B") {
    Serial.print("WandLED B: ");
    Serial.println(messageTemp);
    B = messageTemp.toInt();
  }
}




void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Subscribe
      client.subscribe("/WandLED/Mode");
      client.subscribe("/WandLED/R");
      client.subscribe("/WandLED/G");
      client.subscribe("/WandLED/B");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  if (sMode == 0){
        for(int i=0;i<150;i++){
            pixels.setPixelColor(i, pixels.Color(R,G,B)); // Moderately bright green color.
            pixels.show(); // This sends the updated pixel color to the hardware.
            delay(20);
        };
        delay(20);
  } else if (sMode == 1){
    A = 150;
    Bs = 150;
      for(int i=0;i<150;i++){

    pixels.setPixelColor(A, pixels.Color(0,100,0)); // Moderately bright green color.
    pixels.setPixelColor(Bs, pixels.Color(0,100,0)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    A--;
    Bs++;
    delay(delayval); // Delay for a period of time (in milliseconds).
  }
  A = 150;
  Bs = 150;
  for(int i=0;i<150;i++){

    pixels.setPixelColor(A, pixels.Color(0,0,100)); // Moderately Bsright green color.
    pixels.setPixelColor(Bs, pixels.Color(0,0,100)); // Moderately Bsright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    A--;
    Bs++;
    delay(delayval); // Delay for a period of time (in milliseconds).
  }
  A = 150;
  Bs = 150;
  for(int i=0;i<150;i++){

    pixels.setPixelColor(A, pixels.Color(100,0,0)); // Moderately Bsright green color.
    pixels.setPixelColor(Bs, pixels.Color(100,0,0)); // Moderately Bsright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    A--;
    Bs++;
    delay(delayval); // Delay for a period of time (in milliseconds).
  }
  A = 150;
  Bs = 150;
  } else if (sMode == 2){
    for(int i=0;i

Vielen Dank für eure Hilfe!

Hi

Deine ssid und das zugehörige Passwort sollten in dem Sketch ge-X-t werden!!

Denke, Du hast 30 LED pro Meter, macht 150 LEDs. Bei 60mA pro LED (3 Farben a 20mA) macht Das 9A - Dein Netzteil wird in die Knie gehen, wenn Man 'Mehr' kommt.

Was bekommst Du für serielle Ausgaben? Resettet der µC vll. die ganze Zeit?

Verabschiede Dich von delay() - schaue Dir das Beispiel 'Blink_without_delay' aus der IDE an - bisher sehe ich zwar nur delay(20), aber wo Eines ist, ist das Andere meist nicht weit ...

'Merke' Dir, daß der Stripe umgefärbt wurde. Du lässt bis jetzt ÜBERALL, wo Du irgend eine Farbe neu setzt, den Stripe neu mit Daten beschicken - das pixels.show() reicht 1x im Sketch und dort dann auch nur, wenn sich was geändert hat. Denke, Du setzt momentan die Pixel, schickst die Daten, setzt die Pixel in einem anderen Programm, schickst die Daten, ....

Wenn ich Das jetzt richtig sehe, braucht Dein loop() gefühlte Stunden, um 1x durchzulaufen - DAS muß in wenigen ms erledigt sein.

Dein Hauptproblem wird hier sein, daß Du nit delay() eine zügige Abarbeitung verhinderst und bei jedem 'Pfurz' die LEDs neu mit Daten versorgst.

MfG

Hallo,

Netzteil wurde schoin genannt, Einspeisung der 5V an mehreren Stellen ist bei 5m auch nötig, der Spannungsabfall über die Stripelänge wird sonst zu groß.
Je nach WS2812B (es gibt 3-4 Varianten im Laufe der Zeit, nicht zu unterscheiden, welche man hat, je nach dem, wielange die beim Händler lagen…), die etwas verschiedene Grenzen der Eingangspegel haben.
Speuiell beim ESP32 ist eigentlich immer ein Pegelwandler Pflicht. Meine Primitiv-Variante, die bisher zuverlässig läuft und die Grenzwerte des ESP8266/ESP32 einhält: ESP-IO → 330 Ohm → Din WS2812B → 1k → %v vom Stripe.
Der Reihenwiderstand ist ohnehin Pflicht, weil die älteren Versionen sauer reagieren konnten, wenn das Steuersignal an Din anlag und der Stripe keine Spannung hatte, kosttet irgendwann die erste LED.
Die aktuelle Version ist dagegen geschützt, kommt aber nun mit 3,3V Pegel wohl garnicht mehr zurecht.

Gruß aus Berlin
Michael