3

I'm trying to control a series of LEDs using an IR remote. I have a problem when I try to play a sequence with the LEDs where they all light up in a line and turn off accordingly. I loop through the sequence and I am trying to make it so the instant I press a button on the remote it breaks out of that sequence. The issue lies in the Flash(); function, I think. What can I do?

#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>

int recvPin = 11;
IRrecv irrecv(recvPin);
decode_results results;

#define BUTTON_ON 0xF076C13B    // codes for different buttons on the remote
#define BUTTON_OFF 0xFF9186B7
#define BUTTON_R 0xE5CFBD7F
#define BUTTON_G 0x8C22657B
#define BUTTON_B 0x2A89195F
#define BUTTON_FLASH 0x35A9425F

int rLED = 5;
int gLED = 4;
int bLED = 3;
int stR = LOW;  // intital state of red LED
int stG = LOW;  // intital state of green LED
int stB = LOW;  // initial state of blue LED
int flash = false;

void setup() {
  Serial.begin(9600);   // Status message will be sent to PC at 9600 baud
  pinMode(rLED, OUTPUT);
  pinMode(gLED, OUTPUT);
  pinMode(bLED, OUTPUT);

  irrecv.enableIRIn();
}

void Flash() {    // flashing function
  while (flash == false) {
    digitalWrite(rLED, LOW);
    digitalWrite(gLED, LOW);
    digitalWrite(bLED, LOW);
    digitalWrite(rLED, HIGH);
    delay(75);
    digitalWrite(gLED, HIGH);
    delay(75);
    digitalWrite(bLED, HIGH);
    delay(75);
    digitalWrite(rLED, LOW);
    delay(75);
    digitalWrite(gLED, LOW);
    delay(75);
    digitalWrite(bLED, LOW);
    delay(75);
    stR = LOW;
    stG = LOW;
    stB = LOW;
    if (results.value == BUTTON_OFF)    // attempting to make it so when i press the OFF button on the remote,
    {                                   // the loop breaks/stops and I can go back to pressing any button on
      break;                            // the remote 
    }
  }
}



void loop() {
  if (irrecv.decode(&results))
  {
    if (results.value == BUTTON_ON)
    {
      digitalWrite(rLED, HIGH);
      digitalWrite(gLED, HIGH);
      digitalWrite(bLED, HIGH);
      stR = HIGH;
      stG = HIGH;
      stB = HIGH;
    }
    if (results.value == BUTTON_OFF)
    {
      digitalWrite(rLED, LOW);
      digitalWrite(gLED, LOW);
      digitalWrite(bLED, LOW);
      stR = LOW;
      stG = LOW;
      stB = LOW;
    }
    if (results.value == BUTTON_R)
    {
      digitalWrite(rLED, !stR);
      stR = !stR;
    }
    if (results.value == BUTTON_G)
    {
      digitalWrite(gLED, !stG);
      stG = !stG;
    }
    if (results.value == BUTTON_B)
    {
      digitalWrite(bLED, !stB);
      stB = !stB;
    }
    if (results.value == BUTTON_FLASH)
    {
      Flash();    // calling flash func
    }
    irrecv.resume();
  }
}
2

Replace delay with millis in Flash().

You do this by making every delay it's own state and give each state a number. Then inside flash you check which state you are in to set the LEDs and how long you have been in it to trigger the next state.

boolean flashing = false;
int flashingState = -1;
long nextFlashingState = 0;

void Flash() {    // flashing function
  if(!flashing ){
    flashingState =-1;
    return;
  }

  long ms = millis();
  switch(flashingState ){
  case -1:
    flashingState =0;
    nextflashingState = ms+75; //init "timer"
    //fallthrough
  case 0:
    digitalWrite(rLED, LOW);
    digitalWrite(gLED, LOW);
    digitalWrite(bLED, LOW);
    digitalWrite(rLED, HIGH);
    if(nextflashingState < ms){
        flashingState =1;
        nextflashingState +=75;
    }
    break;
 case 1:
    digitalWrite(gLED, HIGH);
    if(nextflashingState < ms){
        flashingState = 2;
        nextflashingState +=75;
    }
    break;
 case 2:
    digitalWrite(bLED, HIGH);
    if(nextflashingState < ms){
        flashingState = 3;
        nextflashingState +=75;
    }
    break;
  case 3:
    digitalWrite(rLED, LOW);
    if(nextflashingState < ms){
        flashingState = 4;
        nextflashingState +=75;
    }
    break;
  case 4:
    digitalWrite(gLED, LOW);
    if(nextflashingState < ms){
        flashingState = 5;
        nextflashingState +=75;
    }
    break;
  case 5:
    digitalWrite(bLED, LOW);
    if(nextflashingState < ms){
        flashingState = 0;
        nextflashingState +=75;
    }
    break;
  }
}

I used state -1 as the init state to start the timer, the case block will fall through to the next case. The millis() function returns the number of milliseconds since the arduino booted up (it overflows every ~1.5 months). So when I start a timer I set the the nextFlashingState to the time when it should start the next state.

Then in loop you call it every time.

void loop() {
  if (irrecv.decode(&results))
  {
    if (results.value == BUTTON_ON)
    {
      digitalWrite(rLED, HIGH);
      digitalWrite(gLED, HIGH);
      digitalWrite(bLED, HIGH);
      stR = HIGH;
      stG = HIGH;
      stB = HIGH;
    }
    if (results.value == BUTTON_OFF)
    {
        flashing =false;
      digitalWrite(rLED, LOW);
      digitalWrite(gLED, LOW);
      digitalWrite(bLED, LOW);
      stR = LOW;
      stG = LOW;
      stB = LOW;
    }
    if (results.value == BUTTON_R)
    {
      digitalWrite(rLED, !stR);
      stR = !stR;
    }
    if (results.value == BUTTON_G)
    {
      digitalWrite(gLED, !stG);
      stG = !stG;
    }
    if (results.value == BUTTON_B)
    {
      digitalWrite(bLED, !stB);
      stB = !stB;
    }
    if (results.value == BUTTON_FLASH)
    {
        flashing =true;
    }
    irrecv.resume();
  }

  Flash();
}
4
  • 1
    Thanks for the answer! I don't really understand your code, however, I uploaded it and it doesn't seem to do what I wanted it to do. When I press the flash button on the remote, it still flashes endlessly, but now when I press something on the remote the lights do kinda respond to it but keep flashing endlessly. – EdD Sep 5 '17 at 14:50
  • 1
    it will stop flashing when you press off. If you add flashing =false; to the other if blocks then flashing will stop when that button is pressed – ratchet freak Sep 5 '17 at 14:52
  • 1
    Alright, thanks, it works! I wonder how I will make it work with more complicated sequences but for now I do wanna understand what you did there in the void Flash() function and anything else you added cause I am a beginner and if you could possibly refer me to some website where I can learn more about this I would greatly appreciate it :) – EdD Sep 5 '17 at 16:19
  • 1
    @EdD I edited my answer to explain a bit how you would go about replacing delay with millis – ratchet freak Sep 5 '17 at 17:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.