Sketch umbauen für D1 Wemos

Hallo zusammen.
Ich habe ein kleines Problem und hoffe hier einen Fachmann zu finden, der mir helfen kann.
Ich habe im Netz einen Sketch gefunden, der auf einem Arduino Uno oder Mega läuft, das habe ich auch getestet und funktioniert einwandfrei. Jetzt würde ich gerne den Sketch auf einen D1 Wemos packen, damit ich ihn in ESPHome steuern kann und somit ins Smarthome kriege. Meine Versuche es umzubauen, schlugen bis jetzt immer fehl und vernünftige Alternativen zu dem Sketch konnte ich auch nicht finden.

// Arduino Mega - NeoPixel Kaminfeuer
// Version 1.1
// Simulation eines Kaminfeuers mit einem Neopixel Streifen

/// Grunddaten festlegen
  #include <Adafruit_NeoPixel.h>
  
  #define PIN 13 // Datenpin
  
  #define CNT 20 // LED Anzahl
  
  Adafruit_NeoPixel strip = Adafruit_NeoPixel(CNT, PIN, NEO_GRB + NEO_KHZ800);
  
  uint32_t fire_color   = strip.Color ( 100,  35,  0); // RGB Farbwert ( 80,  35,  00), Orange Rot ( 205,  55,  0)
  uint32_t off_color    = strip.Color (  0,  0,  0);

  int min = 100; // Minimalwert für Flackergeschwindigkeit
  int max = 200; // Maximalwert für Flackergeschwindigkeit

/// Feuer Simulation
  class NeoFire
    {
      Adafruit_NeoPixel &strip;
      public:
      
      NeoFire(Adafruit_NeoPixel&);
      void Draw();
      void Clear();
      void AddColor(uint8_t position, uint32_t color);
      void SubstractColor(uint8_t position, uint32_t color);
      uint32_t Blend(uint32_t color1, uint32_t color2);
      uint32_t Substract(uint32_t color1, uint32_t color2);
    };

/// Konstrukt
  NeoFire::NeoFire(Adafruit_NeoPixel& n_strip)
  : strip (n_strip)
    {
    }

/// Alle Farben setzen
  void NeoFire::Draw()
    {
      Clear();
    
      for(int i=0;i<CNT;i++)
        {
          AddColor(i, fire_color);
          int r = random(80);
          uint32_t diff_color = strip.Color ( r, r/2, r/2);
          SubstractColor(i, diff_color);
        }
      
      strip.show();
    }

/// Farbe der LED setzen
  void NeoFire::AddColor(uint8_t position, uint32_t color)
    {
      uint32_t blended_color = Blend(strip.getPixelColor(position), color);
      strip.setPixelColor(position, blended_color);
    }

/// Farbe der LED setzen
  void NeoFire::SubstractColor(uint8_t position, uint32_t color)
    {
      uint32_t blended_color = Substract(strip.getPixelColor(position), color);
      strip.setPixelColor(position, blended_color);
    }

/// Farbmischung
  uint32_t NeoFire::Blend(uint32_t color1, uint32_t color2)
    {
      uint8_t r1,g1,b1;
      uint8_t r2,g2,b2;
      uint8_t r3,g3,b3;
    
      r1 = (uint8_t)(color1 >> 16),
      g1 = (uint8_t)(color1 >>  8),
      b1 = (uint8_t)(color1 >>  0);
    
      r2 = (uint8_t)(color2 >> 16),
      g2 = (uint8_t)(color2 >>  8),
      b2 = (uint8_t)(color2 >>  0);
    
      return strip.Color(constrain(r1+r2, 0, 255), constrain(g1+g2, 0, 255), constrain(b1+b2, 0, 255));
    }

/// Farbmischung
  uint32_t NeoFire::Substract(uint32_t color1, uint32_t color2)
    {
      uint8_t r1,g1,b1;
      uint8_t r2,g2,b2;
      uint8_t r3,g3,b3;
      int16_t r,g,b;
      
      r1 = (uint8_t)(color1 >> 16),
      g1 = (uint8_t)(color1 >>  8),
      b1 = (uint8_t)(color1 >>  0);
      
      r2 = (uint8_t)(color2 >> 16),
      g2 = (uint8_t)(color2 >>  8),
      b2 = (uint8_t)(color2 >>  0);
      
      r=(int16_t)r1-(int16_t)r2;
      g=(int16_t)g1-(int16_t)g2;
      b=(int16_t)b1-(int16_t)b2;
      if(r<0) r=0;
      if(g<0) g=0;
      if(b<0) b=0;
      
      return strip.Color(r, g, b);
    }

/// Jede LED ist aus
  void NeoFire::Clear()
    {
      for(uint16_t i=0; i<strip.numPixels (); i++)
      strip.setPixelColor(i, off_color);
    }
  
  NeoFire fire(strip);
  
  /// Setup
  void setup()
    {
      strip.begin();
      strip.show(); // Alle LED's auf "aus" initialisieren
    }

/// Haupzschleife
  void loop()
    {
      fire.Draw();
      delay(random(min,max)); // Einstellen der Flackergeschwindigkeit
    }

Kann mir da bitte jemand helfen? Danke.

Netten Gruß
ErzGabriel

Warum verwendest du nicht WLED?

Weil man da nicht ein so realistisches flackern hinkriegt, wie mit dem Sketch.

Die Effekte “Fire*” hast du gesehen? Und sind nicht zufriedenstellend?
Dann mit Hilfe der WLED Community einen verbesserten Effekt erstellen. Ist sicher einfacher, als deinen Code ESPHome-passend oder HA-passend zu machen.

Nachtrag:
Bei WLED gibt es die Möglichkeit “Usermodes” hinzuzufügen. Dein Kaminfeuer wäre ein gutes Beispiel, dies als Usermode zu implementieren.
Damit habe ich aber keine praktische Erfahrung. Vielleicht kann jemand anderer weiterhelfen.

:crayon:by HarryP: Zusammenführung Doppelpost (bitte über “bearbeiten” Ergänzungen hinzufügen)

Hab schon lange die Dinger nicht mehr programmiert. Aber was beanstandet er beim kompilieren denn?

Grüße Markus

Hier mal der Fehlercode, der mir ausgegeben wird.

INFO ESPHome 2024.2.2
INFO Reading configuration /config/esphome/fackel.yaml...
Failed config

captive_portal: [source /config/esphome/fackel.yaml:29]
  
  [neopixel] is an invalid option for [captive_portal]. Please check the indentation.
  neopixel: 
  
  [pin] is an invalid option for [captive_portal]. Please check the indentation.
  pin: D4
  
  [num_leds] is an invalid option for [captive_portal]. Please check the indentation.
  num_leds: 20
c++: [source /config/esphome/fackel.yaml:41]
  
  Component not found: c++.
  |-
    #include "esphome.h"
    #include <Adafruit_NeoPixel.h>
    
    class NeoFire {
      Adafruit_NeoPixel &strip;
    
    public:
      NeoFire(Adafruit_NeoPixel &);
      void Draw();
      void Clear();
      void AddColor(uint8_t position, uint32_t color);
      void SubstractColor(uint8_t position, uint32_t color);
      uint32_t Blend(uint32_t color1, uint32_t color2);
      uint32_t Substract(uint32_t color1, uint32_t color2);
    };
    
    NeoFire::NeoFire(Adafruit_NeoPixel &n_strip) : strip(n_strip) {}
    
    void NeoFire::Draw() {
      Clear();
    
      for (int i = 0; i < strip.numPixels(); i++) {
        AddColor(i, fire_color);
        int r = random(80);
        uint32_t diff_color = strip.Color(r, r / 2, r / 2);
        SubstractColor(i, diff_color);
      }
    
      strip.show();
    }
    
    void NeoFire::AddColor(uint8_t position, uint32_t color) {
      uint32_t blended_color = Blend(strip.getPixelColor(position), color);
      strip.setPixelColor(position, blended_color);
    }
    
    void NeoFire::SubstractColor(uint8_t position, uint32_t color) {
      uint32_t blended_color = Substract(strip.getPixelColor(position), color);
      strip.setPixelColor(position, blended_color);
    }
    
    uint32_t NeoFire::Blend(uint32_t color1, uint32_t color2) {
      uint8_t r1, g1, b1;
      uint8_t r2, g2, b2;
    
      r1 = (uint8_t)(color1 >> 16);
      g1 = (uint8_t)(color1 >> 8);
      b1 = (uint8_t)(color1 >> 0);
    
      r2 = (uint8_t)(color2 >> 16);
      g2 = (uint8_t)(color2 >> 8);
      b2 = (uint8_t)(color2 >> 0);
    
      return strip.Color(constrain(r1 + r2, 0, 255), constrain(g1 + g2, 0, 255), constrain(b1 + b2, 0, 255));
    }
    
    uint32_t NeoFire::Substract(uint32_t color1, uint32_t color2) {
      uint8_t r1, g1, b1;
      uint8_t r2, g2, b2;
      int16_t r, g, b;
    
      r1 = (uint8_t)(color1 >> 16);
      g1 = (uint8_t)(color1 >> 8);
      b1 = (uint8_t)(color1 >> 0);
    
      r2 = (uint8_t)(color2 >> 16);
      g2 = (uint8_t)(color2 >> 8);
      b2 = (uint8_t)(color2 >> 0);
    
      r = (int16_t)r1 - (int16_t)r2;
      g = (int16_t)g1 - (int16_t)g2;
      b = (int16_t)b1 - (int16_t)b2;
      if (r < 0)
        r = 0;
      if (g < 0)
        g = 0;
      if (b < 0)
        b = 0;
    
      return strip.Color(r, g, b);
    }
    
    void NeoFire::Clear() {
      for (uint16_t i = 0; i < strip.numPixels(); i++)
        strip.setPixelColor(i, off_color);
    }
    
    NeoFire fire(neopixel);
1 „Gefällt mir“

@erzgabriel
Du hast ja oben im Post den Sketch drinnen.
Ich werde wenn ich Zeit habe es mal ausprobieren.
Was mir auffällt Du hast oben in Grunddaten die Rauten drin.
Somit lädt er die Bibliotheken nicht. Nimm die 3 Rauten raus. Alles mit Raute ist ein Kommentar. Anzahl der LED angleichen.

 #include <Adafruit_NeoPixel.h>
  
  #define PIN 13 // Datenpin
  
  #define CNT 20 // LED Anzahl

Hab das selbe Problem: " Wie schreibe ich ein vorhandenes ARDUINO Programm so um, dass es in YAML für Homeassistant verwendbar ist"
Finde da gar nix erläuterndes. Jegliche Hinweise sind willkommen…

@erzgabriel Marcus, kannst du vielleicht ein Video im WLED Forum posten, um den Request besser zu unterstützen?

Wovon ein Video? Verstehe den Zusammenhang gerade nciht so wirklich.
Ein video wie der Sketch aussieht, wenn er arbeitet? Da habe ich leider keinen Aufbau von hier, weil das bei nem Kollegen im Kamin eingebaut ist und der ist momentan in Urlaub.

Ja, ein Video, auf dem der Effekt zu sehen ist, um diesen zu implementieren.