So I press the button 2 in my IR remote, then the strobe blinks as coded, but it only blinks once. How do I code it in a manner that if I press button 2 on my remote, it turns the LED on and blinks on a loop, then pressing the button 2 again turns the LED off.
code for reference:
/*
source: www.electroschematics.com
You'll need to change the led pins and the codes
accordingly to your configuration and IR remote
*/
#include <IRremote.h>
int RECV_PIN = 12; // the pin where you connect the output pin of TSOP4838
int led1 = 3; //NAV
int led2 = 2; //STROBE
int itsONled[] = {0,0,0,0};
/* the initial state of LEDs is OFF (zero)
the first zero must remain zero but you can
change the others to 1's if you want a certain
led to light when the board is powered */
#define code1 12495 // code received from button 1
#define code2 6375 // code received from button 2
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600); // you can comment this line
irrecv.enableIRIn(); // Start the receiver
pinMode(3, OUTPUT); //NAV
pinMode(2, OUTPUT); //STROBE
}
void loop() {
if (irrecv.decode(&results)) {
unsigned int value = results.value;
switch(value) {
case code1:
if(itsONled[1] == 1) { // if first led is on then
digitalWrite(led1, LOW); // turn it off when button is pressed
itsONled[1] = 0; // and set its state as off
} else { // else if first led is off
digitalWrite(led1, HIGH); // turn it on when the button is pressed
itsONled[1] = 1; // and set its state as on
}
break;
case code2:
if(itsONled[2] == 1) {
digitalWrite(led2, LOW);
itsONled[2] = 0;
} else {
digitalWrite(led2, HIGH);
delay(50);
digitalWrite(led2, LOW);
delay(50);
digitalWrite(led2, HIGH);
delay(50);
digitalWrite(led2, LOW);
delay(1000);
itsONled[2] = 1;
}
break;
}
Serial.println(value); // you can comment this line
irrecv.resume(); // Receive the next value
}
}
you'll want a sub-function that does things separate from waiting for IR codes.
that sub-function would toggle an LED (e.g. digitalWrite (led, ! digitalRead(led)) when a state variable is set by the IR receiving code. it would use millis() to determine how often to toggle the LED. of course, that sub-function could do more than just handle one LED
the IR receiving would toggle that state variable when it recognizes a new occurrence of the IR code.
think about breaking thing down into parts and letting loop() process those parts relatively independently
Thanks for your input, I will try to digest this as I literally started coding 2 days ago and everything is overwhelming. But yes, I have read about millis function as well.
You have to separate the blinking from the place where it processes input. The input processing turns on a flag and in the loop() it blinks the light once a second while the flag is on.
/*
source: www.electroschematics.com
You'll need to change the led pins and the codes
accordingly to your configuration and IR remote
*/
#include <IRremote.h>
const int RECV_PIN = 12; // the pin where you connect the output pin of TSOP4838
const int led1 = 3; //NAV
const int led2 = 2; //STROBE
boolean itsONled[4]; // Defaluts to 'false'
/* the initial state of LEDs is OFF (zero)
the first zero must remain zero but you can
change the others to 1's if you want a certain
led to light when the board is powered */
#define code1 12495 // code received from button 1
#define code2 6375 // code received from button 2
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600); // you can comment this line
irrecv.enableIRIn(); // Start the receiver
pinMode(led1, OUTPUT); //NAV
pinMode(led2, OUTPUT); //STROBE
}
void loop()
{
static unsigned long previousMillis = 0;
// if led2 is 'on', show the blink pattern once per second.
if (itsONled[2] && millis() - previousMillis >= 1000)
{
previousMillis = millis();
digitalWrite(led2, HIGH);
delay(50);
digitalWrite(led2, LOW);
delay(50);
digitalWrite(led2, HIGH);
delay(50);
digitalWrite(led2, LOW);
}
if (irrecv.decode(&results))
{
unsigned int value = results.value;
switch (value)
{
case code1:
if (itsONled[1]) // if first led is on then
{
digitalWrite(led1, LOW); // turn it off when button is pressed
itsONled[1] = false; // and set its state as off
}
else // else if first led is off
{
digitalWrite(led1, HIGH); // turn it on when the button is pressed
itsONled[1] = true; // and set its state as on
}
break;
case code2:
if (itsONled[2])
{
digitalWrite(led2, LOW);
itsONled[2] = false;
}
else
{
itsONled[2] = true;
}
break;
}
Serial.println(value); // you can comment this line
irrecv.resume(); // Receive the next value
}
}
@johnwasser Thanks for the code again, but I do need 1 more advice.
I now added a button 3 in my input and coded a separate blink sequence.
If I press 3, it works perfectly as coded, but if I switch on the button 2, the delay sequence switches alternately with the button 3.
How can I code it that button 3's sequence is independent than that of button 2?
/*
source: www.electroschematics.com
You'll need to change the led pins and the codes
accordingly to your configuration and IR remote
*/
#include <IRremote.h>
const int RECV_PIN = 12; // the pin where you connect the output pin of TSOP4838
const int led1 = 3; //NAV
const int led2 = 2; //STROBE WING
const int led3 = 4; //STROBE TAIL
const int led4 = 5; //BEACON
boolean itsONled[13]; // Defaults to 'false'
/*old code int itsONled[] = {0,0,0,0};
/* the initial state of LEDs is OFF (zero)
the first zero must remain zero but you can
change the others to 1's if you want a certain
led to light when the board is powered */
#define code1 12495 // code received from button 1
#define code2 6375 // code received from button 2
#define code3 31365 // code received from button 3
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600); // you can comment this line
irrecv.enableIRIn(); // Start the receiver
pinMode(led1, OUTPUT); //NAV
pinMode(led2, OUTPUT); //STROBE WING
pinMode(led3, OUTPUT); //STROBE TAIL
pinMode(led4, OUTPUT); //BEACON
}
void loop()
{
static unsigned long previousMillis = 0;
// if led2 is 'on', show the blink pattern once per second.
if (itsONled[2] && millis() - previousMillis >= 1000)
{
previousMillis = millis();
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
delay(50);
digitalWrite(led2, LOW);
delay(50);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
delay(50);
digitalWrite(led2, LOW);
}
if (itsONled[4] && millis() - previousMillis >= 1000)
{
previousMillis = millis();
digitalWrite(led4, HIGH);
delay(50);
digitalWrite(led4, LOW);
delay(50);
}
if (irrecv.decode(&results))
{
unsigned int value = results.value;
switch (value)
{
case code1:
if (itsONled[1]) // if first led is on then
{
digitalWrite(led1, LOW); // turn it off when button is pressed
itsONled[1] = false; // and set its state as off
}
else // else if first led is off
{
digitalWrite(led1, HIGH); // turn it on when the button is pressed
itsONled[1] = true; // and set its state as on
}
break;
case code2:
if (itsONled[2])
{
digitalWrite(led2, LOW);
itsONled[2] = false;
}
else
{
itsONled[2] = true;
}
break;
case code3:
if (itsONled[4])
{
digitalWrite(led4, LOW);
itsONled[4] = false;
}
else
{
itsONled[4] = true;
}
break;
}
Serial.println(value); // you can comment this line
irrecv.resume(); // Receive the next value
}
}
You have to remove all delay() calls from all of your blink patterns and turn each pattern into a finite state machine. Call the FSM from loop() and each state will repeat until its time expires, then it will go on to the next state.
For example:
void LEDPattern2()
{
static int state = 0;
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
// if this pattern isn't playing, reset to the beginning
if (!itsONled[2])
{
if (state != 0) // Pattern was in progress
{
// Turn off the LEDs and start over at state 0
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
state = 0;
}
return;
}
switch (state)
{
case 0:
previousMillis = currentMillis;
state = 1;
break;
case 1:
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
// delay(50);
if (currentMillis - previousMillis > 50)
{
state = 2;
previousMillis = currentMillis;
}
break;
case 2:
digitalWrite(led2, LOW);
// delay(50);
if (currentMillis - previousMillis > 50)
{
state = 3;
previousMillis = currentMillis;
}
break;
case 3:
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
// delay(50);
if (currentMillis - previousMillis > 50)
{
state = 4;
previousMillis = currentMillis;
}
break;
case 4:
digitalWrite(led2, LOW);
// delay(1000);
if (currentMillis - previousMillis > 1000)
{
state = 1;
previousMillis = currentMillis;
}
break;
}
}
void loop()
{
static unsigned long previousMillis = 0;
LEDPattern2();