I'm currently working on a project to control red and green LED's by using an IR remote.
The goal is to be able to chose from different modes of lighting the LED's by first choosing the program on the remote, program 1 is selected by pressing '1' and so on.
Enlighting the LED's will be controlled by pressing the 'ON' button, but before they turn on you have to first select the program you want, otherwise the LED's stay off.
Once a program is selected and started by pressing the 'on' button you should be able to cancel the program and instantly turn off the LED's by again pressing the 'on' button.
Now that's where I'm stuck...
I know that in order to be able to turn the LED's off while a program is running I need to check whether an IR signal is received while running the different programs.
And I don't have any idea how to implement checking for a received IR signal while the LED's turn on and off in the programs without having a ton of code.
So can anybody help me with my problem?
I appreciate every comment helping me to find a solution.
Here is my code:
void loop() {
static bool programChoosed = false; //'programChoosed' checks wether a program was chosen already
static bool programRunning = false;
static int program = 0; //Selected program to play on the LED's is saved in 'program'
if (IrReceiver.decode()) { //If IR receiver decodes a signal
int pressedButton = IrReceiver.decodedIRData.command; //The number of the button that is pressed on the remote is saved in 'pressedButton'
IrReceiver.resume();
if (pressedButton == IR_BUTTON_1) {
program = 1;
programChoosed = true;
} else if (pressedButton == IR_BUTTON_2) {
program = 2;
programChoosed = true;
} else if (pressedButton == IR_BUTTON_ON && programRunning == true) {
offMode();
programRunning = false;
} else if (pressedButton == IR_BUTTON_ON && programChoosed == true) {
programRunning = true;
switch (program) {
case 1: program1(); break;
case 2: program2(); break;
}
}
}
}
void program1() {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(7000);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
delay(8000);
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(3500);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
}
void program2() {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(7000);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
delay(6000);
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(3500);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
}
Get rid of the delays. They make Your idea impossible to achieve.
Search for the topic "How to do several things at the same time".
The sketch "Blink without delay" is also good to check up.
You have to break your program1() and program2() functions into tiny little bits that you can call every time through loop(). It is much like a state machine. I've re-written program1() but left program2() for you
void loop() {
static bool programChoosed = false; //'programChoosed' checks wether a program was chosen already
static bool programRunning = false;
static int program = 0; //Selected program to play on the LED's is saved in 'program'
if (IrReceiver.decode()) { //If IR receiver decodes a signal
int pressedButton = IrReceiver.decodedIRData.command; //The number of the button that is pressed on the remote is saved in 'pressedButton'
IrReceiver.resume();
if (pressedButton == IR_BUTTON_1) program = 1;
if (pressedButton == IR_BUTTON_2) program = 2;
if (pressedButton == IR_BUTTON_ON && programRunning == true) {
offMode();
programRunning = false;
}
if (pressedButton == IR_BUTTON_ON && programRUnning == false && program > 0) {
programRunning = true;
}
}
if ( programRunning ) {
switch (program) {
case 1: program1(); break;
case 2: program2(); break;
}
}
}
void program1() {
static unsigned long lastTime;
static byte state;
switch ( state ) {
case 0: // start pattern
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++; // next state
break;
case 1: // delay 7 sec
if ( millis() - lastTime >= 7000 ) {
// waited long enough, next pattern
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
lastTime = millis();
state++; // next state
}
break;
case 2: // delay 8 sec
if ( millis() - lastTime >= 7000 ) {
// waited long enough, next pattern
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++; // next state
}
break;
case 3: // delay 3.5 sec
if ( millis() - lastTime >= 7000 ) {
// waited long enough, next pattern
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++; // next state
}
break;
default: // start again
state = 0;
}
}
void program2() {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(7000);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
delay(6000);
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
delay(3500);
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
}
True, but the OP posted a snippet of code that did not compile so I did not try to make it compilable either. I would hardly label the OP as a "victim"
I implemented the code the way you suggested but while running it on the Arduino there is now the problem that if the on button is pressed the red LED turns on and stays on until the on button is pressed again.
After that you first have to choose the program again otherwise the LED's stay off, when pressing the on button again now the green LED turns on and also stays on until the on button is pressed again.
Do you have any suggestions how to make the code work?
Here is the complete source code:
//Library for the use of the IR receiver/remote
#include <IRremote.h>
//Declare pin of IR receiver
#define IR_RECEIVE_PIN 5
//Declare button's of remote
#define IR_BUTTON_ON 69
#define IR_BUTTON_1 12
#define IR_BUTTON_2 24
//Declare in-/output's
const int greenLED = 3, redLED = 4;
void setup() {
//Initialize in-/output's
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
//Initialize Serial communication and the IR receiver
Serial.begin(9600);
IrReceiver.begin(IR_RECEIVE_PIN);
}
void loop() {
static bool programChoosed = false; //'programChoosed' checks wether a program was chosen already
static bool programRunning = false;
static int program = 0; //Selected program to play on the LED's is saved in 'program'
if (IrReceiver.decode()) { //If IR receiver decodes a signal
int pressedButton = IrReceiver.decodedIRData.command; //The number of the button that is pressed on the remote is saved in 'pressedButton'
IrReceiver.resume();
if (pressedButton == IR_BUTTON_1) {
program = 1;
programChoosed = true;
} else if (pressedButton == IR_BUTTON_2) {
program = 2;
programChoosed = true;
} else if (pressedButton == IR_BUTTON_ON && programRunning == true) {
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
programRunning = false;
} else if (pressedButton == IR_BUTTON_ON && programChoosed == true) {
programRunning = true;
switch (program) {
case 1: program1(); break;
case 2: program2(); break;
}
}
}
}
void program1() {
static unsigned long lastTime;
static byte state;
switch (state) {
case 0:
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++;
break;
case 1:
if (millis() - lastTime >= 7000) {
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
lastTime = millis();
state++;
}
break;
case 2:
if (millis() - lastTime >= 8000) {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++;
}
break;
case 3:
if (millis() - lastTime >= 3500) {
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++;
}
break;
default:
state = 0;
}
}
void program2() {
static unsigned long lastTime;
static byte state;
switch (state) {
case 0:
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++;
break;
case 1:
if (millis() - lastTime >= 7000) {
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
lastTime = millis();
state++;
}
break;
case 2:
if (millis() - lastTime >= 6000) {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++;
}
break;
case 3:
if (millis() - lastTime >= 3500) {
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
lastTime = millis();
state++;
}
break;
default:
state = 0;
}
}
You did not change the loop() portion of the code. You switch() statement needs to be outside of your if/else clauses and outside of your if .decode() so that it can run every time through loop.
What did you try to get the leds to blink the way you want?