Putting two ir.decodes into two different functions?

Hello,

I've got a project combining Neopixels and an IR remote as a controller. The code is a bit buggy, and I believe it is due to multiple calls for:

  if (irrecv.decode(&results)) {
    if (results.value == 0XFFFFFFFF)
      results.value = key_value;

(once in each function). The premise of the code is to wait for a LED strip number to be chosen on the remote, and then allow the colour to be chosen. However, I think they may be clashing in some way. I've put the code below, is there some way to combine them in some way so they don't clash over each other?

Or alternatively, could there be some other issue at play?

#include <IRremote.h> //include IR library
#include <Arduino.h>
#include <FastLED.h> //include LED library
#define NUM_LEDS1 18 //say how many leds is in row 1
#define NUM_LEDS2 17 //say how many leds is in row 2
#define NUM_LEDS3 20 //say how many leds is in row 3
const int RECV_PIN = 8; //say what pin IR sensor is plugged into
const int LEDPIN = 13;//say what pin blue STATUS led is plugged into
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
int shiftbutton = 0;
CRGB leds1[NUM_LEDS1]; //link leds1 with how many leds are in it
CRGB leds2[NUM_LEDS2]; //link leds2 with how many leds are in it
CRGB leds3[NUM_LEDS3]; //link leds3 with how many leds are in it
size_t NumLeds[3] = { NUM_LEDS1, NUM_LEDS2, NUM_LEDS3 };
CRGB* strips[3] = { leds1, leds2, leds3 };

void setup() {
  irrecv.enableIRIn(); //Enables IR
  irrecv.blink13(true); //Flashes onboard LED when IR input detected
  pinMode(LEDPIN, OUTPUT); //set signal led as an ourput
  FastLED.addLeds<NEOPIXEL, 5>(leds1, NUM_LEDS1); //setup for row 1
  FastLED.addLeds<NEOPIXEL, 3>(leds2, NUM_LEDS2); //setup for row 2
  FastLED.addLeds<NEOPIXEL, 6>(leds3, NUM_LEDS3); //setup for row 3

}

void loop() {
  ShiftButtons();
  LEDStrip();
}

void ShiftButtons() {
  if (irrecv.decode(&results)) {

    if (results.value == 0XFFFFFFFF)
      results.value = key_value;

    switch (results.value) {

      case 0xFF30CF:
        shiftbutton = 1;
        break;
      case 0xFFB04F:
        shiftbutton = 2;
        break;
      case 0xFF708F:
        shiftbutton = 3;
        break;
    }
    key_value = results.value;
    irrecv.resume();
  }
}

void setStrip (size_t index, CRGB color) {
  fill_solid( strips[index], NumLeds[index], color);
  FastLED.show();
}


void LEDStrip () {
  if (irrecv.decode(&results)) {
    if (results.value == 0XFFFFFFFF)
      results.value = key_value;

    if (shiftbutton == 0) return; // no strip selected

    CRGB color = CRGB::Black;
    switch (results.value) {
      case 0xFF1AE5:
        color = CRGB::Red;
        break;
      case 0xFF9A65:
        color = CRGB::Green;
        break;
      case 0xFFA25D:
        color = CRGB::Blue;
        break;
    }
    setStrip(shiftbutton - 1, color);
    shiftbutton = 0;  // reset the flag
    key_value = results.value;
    irrecv.resume();
  }
}

Thanks!
Tom

Sorry I do not have the time to build your project and find out what code is "Buggy". This is especially hard without a schematic. You might want to give us that, not a frizzy thing. I assume you drew one! I was always taught by marketing that bugs were undocumented features! It would also help if you defined the unwanted features you have.

Process your IR once. Write a function for it; it only has to safe results.value. Use that saved value in your existing functions.

Thanks for the responses. Sterretje, would you mind giving me a hand in how I might achieve that? I'm struggling to think of a way to put it into a function.

Thanks,

Tom

I think the below will do; I've added some debugging through serial monitor so you can see what is happening. You can remove it afterwards.

#include <IRremote.h> //include IR library
#include <Arduino.h>
#include <FastLED.h> //include LED library
#define NUM_LEDS1 18 //say how many leds is in row 1
#define NUM_LEDS2 17 //say how many leds is in row 2
#define NUM_LEDS3 20 //say how many leds is in row 3
const int RECV_PIN = 8; //say what pin IR sensor is plugged into
const int LEDPIN = 13;//say what pin blue STATUS led is plugged into

IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
int shiftbutton = 0;

CRGB leds1[NUM_LEDS1]; //link leds1 with how many leds are in it
CRGB leds2[NUM_LEDS2]; //link leds2 with how many leds are in it
CRGB leds3[NUM_LEDS3]; //link leds3 with how many leds are in it
size_t NumLeds[3] = { NUM_LEDS1, NUM_LEDS2, NUM_LEDS3 };
CRGB* strips[3] = { leds1, leds2, leds3 };

void setup()
{
  Serial.begin(57600);

  irrecv.enableIRIn(); //Enables IR
  irrecv.blink13(true); //Flashes onboard LED when IR input detected
  pinMode(LEDPIN, OUTPUT); //set signal led as an ourput
  FastLED.addLeds<NEOPIXEL, 5>(leds1, NUM_LEDS1); //setup for row 1
  FastLED.addLeds<NEOPIXEL, 3>(leds2, NUM_LEDS2); //setup for row 2
  FastLED.addLeds<NEOPIXEL, 6>(leds3, NUM_LEDS3); //setup for row 3
}

void loop()
{
  readIR();
  ShiftButtons();
  LEDStrip();
}

void readIR()
{
  if (irrecv.decode(&results))
  {
    // debug
    Serial.println("processing received IR");
    // if not repeat key
    if (results.value != 0XFFFFFFFF)
    {
      key_value = results.value;

      // debug
      Serial.print("using new value ");
      Serial.println(key_value, HEX);
    }
    else
    {
      // nothing to do
      // key_value still contains the result of the previous read

      // debug
      Serial.print("using old value ");
      Serial.println(key_value, HEX);
    }
    irrecv.resume();
  }
}

void ShiftButtons()
{
  switch (key_value)
  {
    case 0xFF30CF:
      shiftbutton = 1;
      break;
    case 0xFFB04F:
      shiftbutton = 2;
      break;
    case 0xFF708F:
      shiftbutton = 3;
      break;
  }

  // debug
  Serial.print("shiftbutton set to ");
  Serial.println(shiftbutton);
}

void setStrip (size_t index, CRGB color)
{
  fill_solid(strips[index], NumLeds[index], color);
  FastLED.show();
}

void LEDStrip()
{
  if (shiftbutton == 0) return; // no strip selected

  // debug
  Serial.print("LEDStrip: using key value ");
  Serial.println(key_value, HEX);

  CRGB color = CRGB::Black;
  switch (key_value)
  {
    case 0xFF1AE5:
      color = CRGB::Red;
      // debug
      Serial.println("color set to red");
      break;
    case 0xFF9A65:
      color = CRGB::Green;
      // debug
      Serial.println("color set to green");
      break;
    case 0xFFA25D:
      color = CRGB::Blue;
      // debug
      Serial.println("color set to blue");
      break;
  }

  setStrip(shiftbutton - 1, color);
  shiftbutton = 0;  // reset the flag
}

Not tested!

Hi mate, thank you so much for the response! It isn't quite working - looking at the (very handy) debugging via the serial monitor, the shift keys work, but when trying to select a colour, it seems to throw up a random input HEX number rather than the expected associated colour? for example, when shift key has been pressed, and then I press the red button, this is what comes up in the serial monitor:

19:44:59.050 -> LEDStrip: using key value FF30CF
19:44:59.050 -> processing received IR
19:44:59.096 -> using new value 5A9FB1CA
19:44:59.096 -> shiftbutton set to 0

Any ideas?

thanks,

Tom

OK, there was one bug in the code. shiftbutton is always reset to 0, regardless of the fact if a second key for the colour was received. One way around it is to only do that if a valid color key was received and processed in LEDStrip().
1)
The delay in loop() is so I could follow what happened; your can remove it.
2)
The IR codes were changed so I could test it with my remote; you need to restore your values in the case statements.
3)
Stripped all FastLED code so I did not have to change my setup.

#include <IRremote.h>     //include IR library
const int RECV_PIN = 8;   //say what pin IR sensor is plugged into
const int LEDPIN = 13;    //say what pin blue STATUS led is plugged into

IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
int shiftbutton = 0;


void setup()
{
  Serial.begin(57600);

  irrecv.enableIRIn(); //Enables IR
  irrecv.blink13(true); //Flashes onboard LED when IR input detected
  pinMode(LEDPIN, OUTPUT); //set signal led as an ourput
}

void loop()
{
  readIR();
  ShiftButtons();
  LEDStrip();

  // delay so one can follow the debug
  delay(2000);
}

void readIR()
{
  if (irrecv.decode(&results))
  {
    // debug
    Serial.println("processing received IR");
    // if not repeat key
    if (results.value != 0XFFFFFFFF)
    {
      key_value = results.value;

      // debug
      Serial.print("using new value ");
      Serial.println(key_value, HEX);
    }
    else
    {
      // nothing to do
      // key_value still contains the result of the previous read

      // debug
      Serial.print("using old value ");
      Serial.println(key_value, HEX);
    }
    irrecv.resume();
  }
}

void ShiftButtons()
{
  switch (key_value)
  {
    case 0xA41:
      //case 0xFF30CF:
      shiftbutton = 1;
      break;
    case 0xBE1:
      //case 0xFFB04F:
      shiftbutton = 2;
      break;
    case 0x621:
      //case 0xFF708F:
      shiftbutton = 3;
      break;
  }

  // debug
  Serial.print("shiftbutton set to ");
  Serial.println(shiftbutton);
}


void LEDStrip()
{
  if (shiftbutton == 0) return; // no strip selected

  // debug
  Serial.print("LEDStrip: using key value ");
  Serial.println(key_value, HEX);

  switch (key_value)
  {
    case 0x841:
      //case 0xFF1AE5:
      // debug
      Serial.println("color set to red");
      shiftbutton = 0;  // reset the flag
      break;
    case 0xC41:
      //case 0xFF9A65:
      // debug
      Serial.println("color set to green");
      shiftbutton = 0;  // reset the flag
      break;
    case 0x441:
      //case 0xFFA25D:
      // debug
      Serial.println("color set to blue");
      shiftbutton = 0;  // reset the flag
      break;
  }
}

The output:

shiftbutton set to 0
shiftbutton set to 0
shiftbutton set to 0
shiftbutton set to 0
processing received IR
using new value A41
shiftbutton set to 1
LEDStrip: using key value A41
processing received IR
using new value 441
shiftbutton set to 1
LEDStrip: using key value 441
color set to blue
shiftbutton set to 0
processing received IR
using new value BE1
shiftbutton set to 2
LEDStrip: using key value BE1
shiftbutton set to 2
LEDStrip: using key value BE1
shiftbutton set to 2
LEDStrip: using key value BE1
processing received IR
using new value C41
shiftbutton set to 2
LEDStrip: using key value C41
color set to green
shiftbutton set to 0
processing received IR
using new value 621
shiftbutton set to 3
LEDStrip: using key value 621
shiftbutton set to 3
LEDStrip: using key value 621
shiftbutton set to 3
LEDStrip: using key value 621
processing received IR
using new value 841
shiftbutton set to 3
LEDStrip: using key value 841
color set to red
shiftbutton set to 0
shiftbutton set to 0
shiftbutton set to 0
shiftbutton set to 0

Note:
My remote does not have repeat functionality so no 0xFFFFFFFF.

Odd ID data can be due to stray light; I've noticed that in the past.

You can write a simple sketch that displays the hex codes when a button is pressed. Press one key repeatedly and see if what you read is consistent.

I’ve just tested it with no lights on and it still seems to be displaying the random hex codes. Interestingly, when the shift key isn’t pressed, it shows the correct hex code every time. I’m figuring the shift button function must be messing something up by triggering the IR first but I’m absolutely clueless as to why?

I’ve just tested that sketch you mentioned and what I’m getting back is consistent

It's probably the protocol. I have an old remote with various protocols (no idea why and no idea for what most of them are).

In one of the modes it generates a different code on each keypress or when you keep the key pressed.

In another mode, a keypress sends a code; keeping it pressed results in a repeat code (that is different for every key).

In a 3rd mode, continously pressing a key results in a consistent code but repeatedly pressing results in two alternating codes.

And in a 4th mode, a single press or keeping it pressed consistently results in the same code.

None of the modes uses 0xFFFFFFFF as a repeat code.

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