FastLED (WS2812) and RF receiver issues

Hello all. I have written the following sketch to activate an LED effect when an RF code is received. If I send value 721409 (see sketch) using a remote for a split second, the effect works as expected. However if I press the button for only a few millis too long or press the button a second time, the effect “freezes” and I have to hit the button again to get it to restart.

My second issue is that I have to send the stop value (721413) twice to turn the LEDs off. Sending it once freezes the effect, sending it a second time turns it off. I’m assuming this is linked to the first issue, but I could be off the mark.

What am I doing wrong? Thanks in advance.

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

#include "FastLED.h"
#define NUM_LEDS 100
CRGB leds[NUM_LEDS];
#define PIN 4

unsigned long previousMillis = 0;
const long interval = 20;

void showStrip() {
  #ifndef ADAFRUIT_NEOPIXEL_H
    // FastLED
    FastLED.show();
  #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
  #ifndef ADAFRUIT_NEOPIXEL_H
    // FastLED
    leds[Pixel].r = red;
    leds[Pixel].g = green;
    leds[Pixel].b = blue;
  #endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS];
  int cooldown;
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
   
      if(cooldown>heat[i]) {
        heat[i]=0;
      } else {
        heat[i]=heat[i]-cooldown;
      }
    }
 
    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= NUM_LEDS - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
    }
   
    // Step 3.  Randomly ignite new 'sparks' near the bottom
    if( random(255) < Sparking ) {
      int y = random(7);
      heat[y] = heat[y] + random(160,255);
      //heat[y] = random(160,255);
    }

    // Step 4.  Convert heat to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      setPixelHeatColor(j, heat[j] );
    }
    showStrip();
  }
}

void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round(temperature);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
 
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) {                     // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // interrupt 0 = D2
  FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  setAll(0,0,0);
}

void loop() {

  if (mySwitch.available()) {
    unsigned long value = mySwitch.getReceivedValue();
        
    if (value == 721409) {
      Serial.println(mySwitch.getReceivedValue());
      Fire(40,120,10);
    }
    
    if (value == 721413) { // off
      Serial.println(mySwitch.getReceivedValue());
      setAll(0,0,0);
      mySwitch.resetAvailable();
    }
    
    //mySwitch.resetAvailable(); - don't use, stops effect immediately
  }
}

Not familiar with the RCSwitch library, but why do you use

Serial.println(mySwitch.getReceivedValue())

and not

Serial.println(value)

sterretje:
Not familiar with the RCSwitch library, but why do you use

Serial.println(mySwitch.getReceivedValue())

and not

Serial.println(value)

Good question. I know there was some reason why I had that in one of my older sketches, but I don’t remember why so I just replaced it with your suggestion to clean up the code.

I noticed that with my code, the serial monitor spams 721409 (the "on" RF code) non-stop. If I remove the Serial.println bit, it doesn't spam it (obviously) and the effect runs flawlessly; hitting the button again does not freeze the effect. However in that case, hitting the off button does not work at all because the Arduino is busy the whole time.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.