Hello, I'm doing a simple project for my university where I turn on/off a lamp with a IR Remote control. I just used the switch/case to read the inputs and make the decisions. I alredy can turn the light on and off and also make blink, but just when I press the button. How can I make a loop to keep my light blinking and stop it when press the button again (or the same button to turn off)?
There is my actual code:
#include <IRremote.h>
const int RECV_PIN = 8; //Receiver Pin
const int Rele = 10; //Light bulb
const int Led=13;
int timer=1000;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(Rele,OUTPUT);
pinMode(Led,OUTPUT);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
switch(results.value){
case 0X40BF807F: //Turn light on
digitalWrite(Rele,HIGH);
break;
case 0X40BF40BF: //Turn light off
digitalWrite(Rele,LOW);
break;
case 0X40BFA05F: //Decrease Timer
timer=timer-250;
break;
case 0X40BF609F: //Increase Timer
timer=timer+250;
break;
case 0X40BF20DF: //Blink
digitalWrite(Rele,LOW);
delay(timer);
digitalWrite(Rele,HIGH);
}
irrecv.resume();
}
}
When your code is in the IDE, press Ctrl-T to reformat to a style most of us can read easily. Also, get rid of the "magic numbers" in your code. They also make it hard to read. For example:
#include <IRremote.h>
#define LIGHTON 0X40BF807F
#define LIGHTOFF 0X40BF40BF
#define REDUCETIMER 0X40BFA05F
#define INCREASETIMER 0X40BF609F
#define BLINK 0X40BF20DF
const int RECV_PIN = 8; //Receiver Pin
const int Rele = 10; //Light bulb
const int Led = 13;
int timer = 1000;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(Rele, OUTPUT);
pinMode(Led, OUTPUT);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
switch (results.value) {
case LIGHTON: //Turn light on
digitalWrite(Rele, HIGH);
break;
case LIGHTOFF: //Turn light off
digitalWrite(Rele, LOW);
break;
case REDUCETIMER: //Decrease Timer
timer = timer - 250;
break;
case INCREASETIMER: //Increase Timer
timer = timer + 250;
break;
case BLINK: //Blink
digitalWrite(Rele, LOW);
delay(timer);
digitalWrite(Rele, HIGH);
default:
Serial.print("I shouldn't be here. value = "):
Serial.println(results.value);
break;
}
irrecv.resume();
}
}
Now, think about your problem and write a function to start and stop blinking based on the state of your switch
//**********************************************************************
#include "IRremote.h"
//LarryD
//Sketch to demonstrate using an IR hand remote to control Arduino outputs.
//The remote used here uses the NEC protocol.
//This remote sends the button code (example 0xFF629D) then a repeat code 0xFFFFFFFF
//The repeat code is re-sent as long as an IR remote button is pressed.
//The IR receiver used is the TSOP4838
/* 17 IR button remote layout http://i.imgur.com/X1KIdqI.png
^
< OK >
v
1 2 3
4 5 6
7 8 9
* 0 #
*/
const byte RECV_PIN = 7; //IR receive pin
IRrecv irrecv(RECV_PIN); //create instance of 'IRrecv'
decode_results results; //create instance of 'decode_results'
unsigned long TimerUp; //UP arrow on the remote
boolean TimerUpFlag = false;
unsigned long TimerDown; //DOWN arrow on the remote
boolean TimerDownFlag = false;
unsigned long TimerIntensity;
unsigned long TimerIncDec;
boolean intesityUpFlag = false;
boolean intesityDownFlag = false;
int brightness;
unsigned long dummy;
unsigned long * TimerPtr = &dummy; //pointer to the current timer
const byte upLED = 13; //turns on as long as the UP button is pressed
const byte downLED = 12; //turns on as long as the DOWN button is pressed
const byte leftLED = 11; //toggles on/off
const byte rightLED = 10; //toggles on/off
const byte intensityLED = 9; //a LED which can have its intensity adjusted
// s e t u p ( )
//**********************************************************************
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); //start receive
pinMode(upLED, OUTPUT);
pinMode(downLED, OUTPUT);
pinMode(leftLED, OUTPUT);
pinMode(rightLED, OUTPUT);
pinMode(intensityLED, OUTPUT); //this is a PWM output pin
} // E N D O F s e t u p ( )
// l o o p ( )
//**********************************************************************
void loop()
{
if (irrecv.decode(&results)) //is there IR remote button code
{
//Serial.println(results.value);
processButton(); //process button press
irrecv.resume(); //restart for next button press
}
//********************** //Turn off upLED
//if timing is enabled, is it time to stop
if (TimerUpFlag && millis() - TimerUp >= 250ul)
{
TimerUpFlag = false; //disable timing
TimerPtr = &dummy; //pointer to dummy timer
digitalWrite(upLED, LOW);
}
//********************** //Turn off downLED
//if timing is enabled, is it time to stop
if (TimerDownFlag && millis() - TimerDown >= 250ul)
{
TimerDownFlag = false; //disable timing
TimerPtr = &dummy; //pointer to dummy timer
digitalWrite(downLED, LOW);
}
//********************** //LED intensity
//are we still within the adjustment time
if (millis() - TimerIntensity <= 300ul)
{
//is it time to increase/decrease the intensity
if (millis() - TimerIncDec >= 200ul)
{
TimerIncDec = millis();
if (intesityUpFlag == true) //Increase
{
brightness += 5;
if (brightness > 255)
{
brightness = 255;
}
}
else if (intesityDownFlag == true) //Decrease
{
brightness -= 5;
if (brightness < 0)
{
brightness = 0;
}
}
analogWrite(intensityLED, brightness);
//Serial.println(brightness); //debug
}
}
//stop increasing/decreasing intensity
else
{
intesityUpFlag = false;
intesityDownFlag = false;
}
//************************************
//Other non blocking code goes here
//************************************
} // E N D O F l o o p ( )
//======================================================================
// F U N C T I O N S
//======================================================================
// p r o c e s s B u t t o n ( )
//**********************************************************************
//process IR remote button presses
void processButton()
{
switch (results.value)
{
//**********************
case 0xFF629D: //UP Arrow
{
Serial.println("UP");
TimerPtr = &TimerUp; //point to this timer
TimerUpFlag = true; //enable timing
digitalWrite(upLED, HIGH);
TimerUp = millis();
}
break;
//**********************
case 0xFFA857: //DOWN Arrow
{
Serial.println("DOWN");
TimerPtr = &TimerDown; //point to this timer
TimerDownFlag = true; //enable timing
digitalWrite(downLED, HIGH);
TimerDown = millis();
}
break;
//**********************
case 0xFF22DD: //LEFT Arrow
{
Serial.println("LEFT");
digitalWrite(leftLED, !digitalRead(leftLED)); //Toggle LED
}
break;
//**********************
case 0xFFC23D: //RIGHT Arrow
{
Serial.println("RIGHT");
digitalWrite(rightLED, !digitalRead(rightLED)); //Toggle LED
}
break;
//**********************
case 0xFF42BD: // * button
{
Serial.println("*");
TimerPtr = &TimerIntensity; //point to this timer
intesityUpFlag = true; //enable intensity up adjustment
intesityDownFlag = false;
TimerIncDec = millis();
TimerIntensity = millis();
}
break;
//**********************
case 0xFF52AD: // # button
{
Serial.println("#");
TimerPtr = &TimerIntensity; //point to this timer
intesityDownFlag = true; //enable intensity down adjustment
intesityUpFlag = false;
TimerIncDec = millis();
TimerIntensity = millis();
}
break;
//**********************
case 0xFF02FD:
Serial.println("OK");
break;
//**********************
case 0xFF6897:
Serial.println("1");
break;
//**********************
case 0xFF9867:
Serial.println("2");
break;
//**********************
case 0xFFB04F:
Serial.println("3");
break;
//**********************
case 0xFF30CF:
Serial.println("4");
break;
//**********************
case 0xFF18E7:
Serial.println("5");
break;
//**********************
case 0xFF7A85:
Serial.println("6");
break;
//**********************
case 0xFF10EF:
Serial.println("7");
break;
//**********************
case 0xFF38C7:
Serial.println("8");
break;
//**********************
case 0xFF5AA5:
Serial.println("9");
break;
//**********************
case 0xFF4AB5:
Serial.println("0");
break;
//**********************
case 0xFFFFFFFF: //Repeat code
{
Serial.println("REPEAT");
*TimerPtr = millis(); //reset the current timer
}
break;
} // END switch case
} // E N D o f p r o c e s s B u t t o n ( )
//**********************************************************************
//======================================================================
// E N D O F C O D E
//======================================================================
#include <IRremote.h>
#define LIGHTON 0X40BF807F
#define LIGHTOFF 0X40BF40BF
#define REDUCETIMER 0X40BFA05F
#define INCREASETIMER 0X40BF609F
#define BLINK 0X40BF20DF
const int RECV_PIN = 8; //Receiver Pin
const int Rele = 10; //Light bulb
const int Led = 13;
int timer = 1000;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(Rele, OUTPUT);
pinMode(Led, OUTPUT);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
switch (results.value) {
case LIGHTON: //Turn light on
Mode = 1;
break;
case LIGHTOFF: //Turn light off
Mode = 0;
break;
case REDUCETIMER: //Decrease Timer
timer = timer - 250;
break;
case INCREASETIMER: //Increase Timer
timer = timer + 250;
break;
case BLINK: //Blink
Mode = 2;
digitalWrite(Rele, LOW);
delay(timer);
digitalWrite(Rele, HIGH);
default:
Serial.print("I shouldn't be here. value = ");
Serial.println(results.value);
break;
}
// The IR receiver reuslts change each cycle so you need to latch the "Mode" into a sequence so the light will keep blinking while you reduce or increase timer
switch (Mode) {
case 1: //Turn light on
digitalWrite(Rele, HIGH);
break;
case 0: //Turn light off
digitalWrite(Rele, LOW);
break;
case 2: //Blink
static unsigned long _DelayTimer;
if ( (unsigned long)(millis() - _DelayTimer) >= (timer)) { // Blink without delay timer allowing your IR receiver to work
_DelayTimer = millis();
digitalWrite(Rele, !digitalRead(Rele)); // reads the output and uses the opposite
}
break;
}
irrecv.resume();
}
}