IR Remote LED Control Question

Hi Arduino community,

i keep on updating my first small LED project and am now trying to replace my 3 physical buttons which have been switching in between 2 led animations (3rd button was for off), with buttons on a IR remote.

Im using the IRremote library and things are pretty stright forward. I am getting clean readouts in the serial monitor from the remote. But when i try to plug in the remote code into my sketch suddenly the serial monitor starts showing random values even while pressing the same button.

This is the full sketch.

#include <FastLED.h>
#include <IRremote.h>

int IR_Recv = 12;
IRrecv irrecv(IR_Recv);
decode_results results;

#define DATA_PIN    2
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define NUM_LEDS    72
CRGB leds[NUM_LEDS];

#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  180

int ledspeed;
int ledcolorR;
int ledcolorG;
int ledcolorB;

const unsigned long eventInterval1 = 26000;
const unsigned long eventInterval2 = 21000;
unsigned long startTime1 = 0;
unsigned long startTime2 = 0;

void setup() {

  Serial.begin(9600);

  delay(3000); // 3 second delay for recovery
  irrecv.enableIRIn(); // Starts the receiver  
  
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
  
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 500);

}


void loop()
{

  if (irrecv.decode(&results)) {    //Wenn Daten empfangen wurden,

  Serial.println(results.value, DEC); //werden sie als Dezimalzahl (DEC) an den Serial-Monitor ausgegeben.

  irrecv.resume();  //Der nächste Wert soll vom IR-Empfänger eingelesen werden
  }

  unsigned long currentTime = millis();

  if (results.value == 16753245) {
    startTime1 = currentTime;
    ledspeed=80;
    ledcolorR = 128;
    ledcolorG = 255;
    ledcolorB = 200;
  }

    if (startTime1 > startTime2 && currentTime - startTime1 >= eventInterval1) {
    ledspeed=0;
    ledcolorR = 0;
    ledcolorG = 0;
    ledcolorB = 0;
  }

  if (irrecv.decode(&results) == 16736925) {
    startTime2 = currentTime;
    ledspeed=100;
    ledcolorR = 128;
    ledcolorG = 255;
    ledcolorB = 200;
  }

  if (startTime2 > startTime1 && currentTime - startTime2 >= eventInterval2) {
    ledspeed=0;
    ledcolorR = 0;
    ledcolorG = 0;
    ledcolorB = 0;
  }

  if (digitalRead(button3) == LOW) { 
    ledcolorR = 0;
    ledcolorG = 0;
    ledcolorB = 0;
  }

  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy(leds, NUM_LEDS, 254);

   int pos = beatsin16(ledspeed, 0, NUM_LEDS-1 );
   leds[pos] += CRGB(ledcolorR, ledcolorG, ledcolorB);

  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(50/FRAMES_PER_SECOND); 

}

I already identified that when i remove the last part of the code I again get a clean readout in the serial monitor. So removing this helps getting a clean readout again but of course breaks the sketch.

  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy(leds, NUM_LEDS, 254);

   int pos = beatsin16(ledspeed, 0, NUM_LEDS-1 );
   leds[pos] += CRGB(ledcolorR, ledcolorG, ledcolorB);

  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(50/FRAMES_PER_SECOND);

Been stuck with this for the past 3 hours and i can not see where the issue might be. Initially replacing physical buttons with remote buttons seemed like a very easy task. Looks like it isnt.

Appreciate any help.

Thanks already.

The FastLED show() function disables interrupts because of the very tight timing needed to control the LEDs. The IRremote library depends on interrupts. Any IR message that comes along when interrupts are disabled will be corrupted or ignored. You need to suspend calling the show() function when receiving IR messages.

Thank you @groundFungus . That makes sense. I m still a noob and this is my first project. Do you have any recommendation in how i would be able to do this or is this something way out of the noob league?

I have not tried with IR, but I did have a project using Bluetooth (serial port) to change parameters for a WS2812 strip. I looked for anything coming in over the serial port and when something (did not care what, exactly) came into the serial port I stop calling show(), send a message to the sender that it was ready for data, read the incoming data form the serial port, parse and act on the message then return to calling the show() function. I am not sure how to implement this with IR.

Thank you. I have a bluetooth remote in the mail as well. So i will give this a try as alternative then if i will not be able to figure it out for ir.

@groundFungus i m trying to read up a bit on how to suspend the show function. Is this being done via interrupts? Just trying to see what keywords to google here to learn a bit more about this.

Here is the loop from my Bluetooth program. The sender is the serial Bluetooth terminal app on my Android tablet.

The code watches for an incoming byte from the sender. I matters not the value, it just warns the Arduino that data is forthcoming. The Arduino program clears the serial buffer and exits the mode that controls the display (calls show()) and sends a message to the sender to say that it is ready for data. The sender then sends data and the Arduino reads each packet and acts on it. After the last data packet a <d> is sent to tell the Arduino that all data has been sent. When the Arduino receives the <d> it sets the mode back to controlling the LED strip (calling show(). The serial reading and parsing is done with code from the serial input basics tutorial.

Here is the loop() to show how I switch modes on incoming serial data.

void loop()
{
   if (mode == 0) // show mode
   {
      showMiles();
      showDP(dpColor);

      if (bt.available()) // if a character has come in
      {
         while (bt.available()) 
         {
            // read and throw away alert character
            bt.read();  // clear bt buffer
         }
         mode = 1; // go to the serial input mode
      }
   }
   else if (mode == 1) // read serial mode
   {
      if (setupMsg == 0) // send setup message if it hasn't been sent
                // tells the sender that the Arduino is ready for real data
      {
         Serial.println("Entered set up mode");
         bt.println("Entered set up mode");
         setupMsg = 1; // setup message sent
      }
      recvWithStartEndMarkers(); // get packet
      if (newData == true)  // new packet recieved
      {
         parseData(); 
         // the parseData function will set mode back to 0
         // when all serial is received and processed and <d> is sent
      }
   }
}

Thanks a lot @groundFungus will give this a try with the app as well.

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