Feuer simulieren mit ir Ferbedienung

Ich habe den Code mal etwas umgemodelt. Der Ursprüngliche hatte doch einige Warnings und etwas Durcheinander bei den Datentypen. Da ich nur eine 64er LED habe und die Fernbedienung eine Sony ist, passt das nicht so ganz für Dich.

Die NumPixels müssen wieder auf 300 gesetzt werden und der Fernbedienungstyp von DECODE_SONY auf DECODE_SAMSUNG geändert werden.

Außerdem musst Du die Codes für die Tasten 1 bis 6 neu auslesen und die Pinnummern an Deine Schaltung anpassen.

Edit:

Ich habe den Code jetzt auf eine Samsung Fernbedienung angepasst. Du muss jetzt eigentlich nur noch die passenden Pinnummern wieder angeben (im namespace gc Bereich)

#include <Adafruit_NeoPixel.h>

#define DECODE_SAMSUNG
// #define DECODE_SONY
#define RAW_BUFFER_LENGTH 100
#define EXCLUDE_UNIVERSAL_PROTOCOLS   // Saves up to 1000 bytes program space.
#define EXCLUDE_EXOTIC_PROTOCOLS      // saves around 650 bytes program space if all other protocols are active
#include <IRremote.hpp>

using Millis_t = decltype(millis());
using IrCommand_t = decltype(IrReceiver.decodedIRData.command);

namespace gc {
constexpr uint8_t neoPixelPin {8};     // Which on the Arduino is connected to the NeoPixels?
constexpr uint8_t irReceiverPin {9};   // define IR input  on Arduino
constexpr size_t numPixels {300};      // How many NeoPixels are attached to the Arduino?
constexpr Millis_t remodeDebounce_ms {300};
constexpr Millis_t sequenceDelay_ms {250};
}   // namespace gc

class Timer {
public:
  void start() { timestamp = millis(); }
  bool operator()(const Millis_t duration) const { return millis() - timestamp >= duration; }

private:
  Millis_t timestamp {0};
};

struct FireEnvironment_t {
//                              T1      T2      T3      T4     T5       T6
#if defined(DECODE_SAMSUNG)
  const IrCommand_t irCodes[6] {0x0704, 0x0705, 0x0706, 0x0708, 0x0709, 0x070A};   // Samsung
#elif defined(DECODE_SONY)
  const IrCommand_t irCodes[6] {0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105};   // Sony
#endif
  const size_t numIrCodes {sizeof(irCodes) / sizeof(irCodes[0])};
  const size_t numPixels {gc::numPixels};
  IrCommand_t irCmd;
  IrCommand_t oldIrCmd;
  uint8_t lightValue[gc::numPixels * 3 + 2];
  uint8_t sequence {0};
  bool fireON {false};
  bool fireOFF {false};
  Millis_t interval {gc::sequenceDelay_ms};
  Timer sequenceTimer;
} fireEnvironment;

Adafruit_NeoPixel pixels(gc::numPixels, gc::neoPixelPin, NEO_GRB + NEO_KHZ800);
Timer remoteDebounceTimer;

inline void showLED(Adafruit_NeoPixel& px) {
  noInterrupts();
  px.show();
  interrupts();
}

void setPixelLightValues(Adafruit_NeoPixel& px, FireEnvironment_t& fireEnv) {
  for (size_t i {0}; i < fireEnv.numPixels; ++i) {
    px.setPixelColor(i, fireEnv.lightValue[i * 3], fireEnv.lightValue[i * 3 + 1], fireEnv.lightValue[i * 3 + 2]);
  }
}

void selectSequence(Adafruit_NeoPixel& px, FireEnvironment_t& fireEnv) {
  switch (fireEnv.sequence) {
    case 0:
      fireEnv.interval = gc::sequenceDelay_ms;
      for (size_t i {0}; i < fireEnv.numPixels; ++i) {    // For each pixel...
        fireEnv.lightValue[i * 3] = random(200, 255);     // 250
        fireEnv.lightValue[i * 3 + 1] = random(30, 70);   // 50
        fireEnv.lightValue[i * 3 + 2] = 0;
      }
      setPixelLightValues(px, fireEnv);
      break;
    case 1:
      for (size_t i {0}; i < fireEnv.numPixels; ++i) {   // For each pixel...
        px.setPixelColor(i, 250, 50, 0);
      }
      break;
    case 2: {
      fireEnv.interval = random(50, 100);
      for (size_t i {0}; i < fireEnv.numPixels; ++i) {    // For each pixel...
        fireEnv.lightValue[i * 3] = random(240, 255);     // 250
        fireEnv.lightValue[i * 3 + 1] = random(30, 60);   // 50
        fireEnv.lightValue[i * 3 + 2] = 0;
      }
      // Switch some lights out
      uint8_t LightsOff = random(0, 6);
      for (size_t i {0}; i < LightsOff; ++i) {
        byte Selected = random(fireEnv.numPixels);
        fireEnv.lightValue[Selected * 3] = 0;
        fireEnv.lightValue[Selected * 3 + 1] = 0;
        fireEnv.lightValue[Selected * 3 + 2] = 0;
      }
      setPixelLightValues(px, fireEnv);
    } break;
    case 3: {
      fireEnv.interval = random(80);
      for (size_t i {0}; i < fireEnv.numPixels; ++i) {   // For each pixel...
        fireEnv.lightValue[i * 3] = 250;                 // random(240,255); // 250
        fireEnv.lightValue[i * 3 + 1] = 50;              // random(30,60); // 50
        fireEnv.lightValue[i * 3 + 2] = 0;
      }
      // Switch some lights out if Chance Hit

      uint8_t ChanceForLightsOff = random(0, 40);
      if (ChanceForLightsOff > 35) {
        byte LightsOff = random(5);
        for (size_t i {0}; i < LightsOff; ++i) {
          byte Selected = random(fireEnv.numPixels);
          fireEnv.lightValue[Selected * 3] = 0;
          fireEnv.lightValue[Selected * 3 + 1] = 0;
          fireEnv.lightValue[Selected * 3 + 2] = 0;
        }
      }
      setPixelLightValues(px, fireEnv);
    } break;
    case 4: {
      fireEnv.interval = random(150, 200);
      for (size_t i {0}; i < fireEnv.numPixels; ++i) {    // For each pixel...
        fireEnv.lightValue[i * 3] = random(240, 255);     // 250
        fireEnv.lightValue[i * 3 + 1] = random(30, 60);   // 50
        fireEnv.lightValue[i * 3 + 2] = 0;
      }
      // Switch some lights darker
      uint8_t LightsOff = random(0, 4);
      for (size_t i {0}; i < LightsOff; ++i) {
        byte Selected = random(fireEnv.numPixels);
        fireEnv.lightValue[Selected * 3] = random(50, 60);
        fireEnv.lightValue[Selected * 3 + 1] = random(5, 10);
        fireEnv.lightValue[Selected * 3 + 2] = 0;
      }
      setPixelLightValues(px, fireEnv);
    } break;
    case 5: {
      fireEnv.interval = random(80);
      for (size_t i {0}; i < fireEnv.numPixels; ++i) {    // For each pixel...
        fireEnv.lightValue[i * 3] = random(240, 255);     // 250
        fireEnv.lightValue[i * 3 + 1] = random(40, 60);   // 50
        fireEnv.lightValue[i * 3 + 2] = 0;
      }
      // Switch some lights out if Chance Hit
      uint8_t ChanceForLightsOff = random(0, 40);
      if (ChanceForLightsOff > 35) {
        byte LightsOff = random(5);
        for (size_t i {0}; i < LightsOff; ++i) {
          byte Selected = random(fireEnv.numPixels);
          fireEnv.lightValue[Selected * 3] = 0;
          fireEnv.lightValue[Selected * 3 + 1] = 0;
          fireEnv.lightValue[Selected * 3 + 2] = 0;
        }
      }
      setPixelLightValues(px, fireEnv);
    } break;
    default: fireEnv.fireON = false; break;   // switch off if not existing sequence number is given.
  }
}

void simulateFire(IRrecv& irRcv, Adafruit_NeoPixel& px, FireEnvironment_t& fireEnv) {
  if (fireEnv.sequenceTimer(fireEnv.interval)) {
    if (fireEnv.fireON) {
      fireEnv.sequenceTimer.start();
      fireEnv.fireOFF = false;
      selectSequence(px, fireEnv);
      // https://github.com/Arduino-IRremote/Arduino-IRremote?tab=readme-ov-file#problems-with-neopixels-fastled-etc
      if (irRcv.isIdle()) { showLED(px); }
    } else if (!fireEnv.fireOFF && irRcv.isIdle()) {
      px.clear();
      showLED(px);
      fireEnv.fireOFF = true;
    }
  }
}

IrCommand_t receiveIrCommand(IRrecv& irRcv) {
  IrCommand_t command {0};
  if (irRcv.decode()) {
    command = (irRcv.decodedIRData.address << 8) + irRcv.decodedIRData.command;
    irRcv.resume();
    // Serial.println(Command,HEX);
  }
  return command;
}

void irCommandProcessor(IRrecv& irRcv, FireEnvironment_t& fireEnv, Timer& wait) {
  bool isKnownCode {false};
  if (fireEnv.irCmd == fireEnv.oldIrCmd) { wait.start(); }   // Start debouncetimer
  if (fireEnv.irCmd && fireEnv.irCmd != fireEnv.oldIrCmd)    // Valid new IR Signal Received
  {
    fireEnv.oldIrCmd = fireEnv.irCmd;
    for (size_t i {0}; i < fireEnv.numIrCodes; ++i) {
      if (fireEnv.irCodes[i] == fireEnv.irCmd) {
        fireEnv.sequence = i;
        fireEnv.fireON = !fireEnv.fireON;
        isKnownCode = true;
      }
    }
    if (!isKnownCode) { irRcv.printIRResultShort(&Serial); }
  }
  if (wait(gc::remodeDebounce_ms)) { fireEnv.oldIrCmd = 0; }   // Some stuff about debouncing IR Remote
}

void setup() {
  Serial.begin(115200);
  while (!Serial);                       // Wait until Serial is established - required on some Platforms
  IrReceiver.begin(gc::irReceiverPin);   // Start the receiver
  pixels.begin();                        // Initialize NeoPixels
  pixels.setBrightness(50);
  pixels.show();                         // Set all pixels to 'off'
  randomSeed(analogRead(0));
}

void loop() {
  fireEnvironment.irCmd = receiveIrCommand(IrReceiver);
  irCommandProcessor(IrReceiver, fireEnvironment, remoteDebounceTimer);
  simulateFire(IrReceiver, pixels, fireEnvironment);
}