Ok here's my first post asking for a bit of help. I have been trying to do a simple task which is when I press and hold the ir remote button to loop a block of code, for example, make an LED go high only while holding down the key. When the key is released, have the LED go low. I can use switch case but if you hold down the ir remote button it does not repeat. My goal is to eventually drive a DC motor that will drive my bot in different directions depending on the ir input.
#include "IRremote.h"
#include "IR.h"
IRrecv irrecv(RECEIVER); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
void setup() {
Serial.begin(9600);
Serial.println("IR Receiver Button Decode");
irrecv.enableIRIn();
}
void loop()
{
if (irrecv.decode(&results)){ // have we received an IR signal?
switch(results.value){
case KEY_1: //Red Keypad Button
// Turn on LED for 2 Seconds
digitalWrite(9, HIGH);
delay(2000);
digitalWrite(9, LOW);
break;
case KEY_2:
Serial.println("key #2");
break;
}
irrecv.resume();
}
}
Let's MAKE the droids you've been looking for...
If you haven't had a chance to look at Bill's video on IR controls here is the link.
I hope it helps 😊
Thanks so much for the link. I missed that. I will take a look at it.
I have another question. How can I edit the topic to correct the typo. I meant to type module!
Let's MAKE the droids you've been looking for...
So I wired up an IR Receiver Module and found some code online to try it out using a Samsung remote control to see what your issue was. When you hold a key down there is a delay between each transmission. First I used this code to get the values for the numerical keys 1, 2, 3 and 4 on the remote.
#include <IRremote.h> // use the IRRemote.h const int irReceiverPin = 8; //the SIG of receiver module attach to pin2 IRrecv irrecv(irReceiverPin); //Creates a variable of type IRrecv decode_results results; // define results void setup() { Serial.begin(9600); //initialize serial,baudrate is 9600 irrecv.enableIRIn(); // enable ir receiver module } void loop() { if (irrecv.decode(&results)) //if the ir receiver module receiver data { Serial.print("irCode: "); //print "irCode: " //Serial.print(results.value, HEX); //print the value in hexdecimal Serial.println(results.value); // print the value in decimal irrecv.resume(); // Receive the next value } delay(600); //delay 600ms }
This code below seems to work using the values obtained using the code in the previous post. Essentially it uses a timer. If you press a key 1 to 4 the selected LED will remain on long enough to be reset to on again without having been turned off if the same key is held down. Note I used a Mega so you will have to change the LED pin numbers to your particular choices if using a Uno. I used pin 8 to input IR the signal.
#include <IRremote.h> // use the IRRemote.h const int irReceiverPin = 8; //the SIG of receiver module attach to pin2 IRrecv irrecv(irReceiverPin); //Creates a variable of type IRrecv decode_results results; // define results const int LED1 = 30; // change these four lines to the pin numbers you use const int LED2 = 31; const int LED3 = 32; const int LED4 = 33; long previousMillis = 0; // will store last time LED was updated long currentMillis = 0; long interval = 200; // interval led has been on (milliseconds) void setup() { //Serial.begin(9600); //initialize serial,baudrate is 9600 irrecv.enableIRIn(); // enable ir receiver module } void loop() { unsigned long currentMillis = millis(); if (irrecv.decode(&results)) //if the ir receiver module receiver data { if (results.value == 3772784863){ digitalWrite(LED1,HIGH); previousMillis = currentMillis; } if (results.value == 3772817503){ digitalWrite(LED2,HIGH); previousMillis = currentMillis; } if (results.value == 3772801183){ digitalWrite(LED3,HIGH); previousMillis = currentMillis; } if (results.value == 3772780783){ digitalWrite(LED4,HIGH); previousMillis = currentMillis; } irrecv.resume(); // Receive the next value } if(currentMillis - previousMillis > interval) { digitalWrite(LED1,LOW); digitalWrite(LED2,LOW); digitalWrite(LED3,LOW); digitalWrite(LED4,LOW); } delay(60); //delay 60ms }
I tried your code and it works the same as my code but the only difference is that your code removes the road block that allows the code to move on like a finite state machine. The problem remains that if the button is pressed and held down, it will not re execute the same condition unless you release the button and press it again. I tried everything and my lack of understanding of what is going on is making it hard to figure this out.
I need a "do while condition is true" or "do until button is released" but my results are that it either loops forever, or it will loop only once when a button is pressed, but then I run into the problem that if i can get it to loop while holding down the button any key that it pressed will now trigger the loop because the value is different than the trigger value which is not what I want to have happen either.
apparently the event only happens once after the remote button is pressed but there needs to be a way to monitor to see if the button remains pressed.
#include "IRremote.h"
//#include "IR.h"
#define KEY_1 (0xFF30CF)
IRrecv irrecv(11); // pin #11
decode_results results; // create instance of 'decode_results'
void setup() {
Serial.begin(9600);
Serial.println("IR Receiver Button Decode");
irrecv.enableIRIn();
}
void loop()
{
if (irrecv.decode(&results)){ // Did we received an IR signal?
if (results.value == KEY_1){ //#1 button on Elegoo remote. #define KEY_1 (0xFF30CF)
//Need to loop While button is pressed
digitalWrite(9, HIGH);
delay(50);
digitalWrite(9, LOW);
//Need to exit loop after button released
}
irrecv.resume();
}
}
Let's MAKE the droids you've been looking for...
@xybitz I have found that some IR controllers output 0xFFFFF if you hold the button down, indicating a repeat signal. You need to set a variable to the last action, and then if you receive a repeat signal, re-execute that action. You can use a Serialprint to see if this is happening on your controller.
Pat Wicker (Portland, OR, USA)
This is the first time I have used an IR receiver so it is a learning experience for me too. I will try to work it out and get an IR remote control of a car working as required!! I will do more research on the problem.
The code I sent works fine for me. The only loop you should need is the main loop(). While the Arduino is executing a delay it can't do other things that is why it is better to use an interrupt or as I have done a timer.
In the code I posted when the Arduino gets an IR code it turns on the LED for that key. If after the interval time it doesn't get another IR code it turns off all the LEDs (as it doesn't record which one it turned on). Actually that is a bug as I now realise that if another key is pressed before the interval time limit is up the previous LEDs remain on!!
I am using a Samsung tv remote using the number keys 1,2,3 and 4. I am using the infrared receiver module shown below. The Samsung remote sends codes at fixed intervals, and in my opinion at a rather slow rate, while a key is being held down. It sends nothing when none of the keys are pressed.
Just reviewed,
https://dronebotworkshop.com/using-ir-remote-controls-with-arduino/
and I see you can easily build your own remote controller using another Arduino.
Thanks so much for the feedback. That's the exact same IR module that I'm using. It came with my Elegoo Uno Super starter kit. I'm also using the remote that came with that kit.
I need to try to do a loop while the incoming IR data is 0xFFFFFF and exit the loop only if the data stops. When the proper key is selected it goes to the right case but then I need a loop that will continue as long as the incoming data is true. After the button is released, the code can return to the beginning to scan for the next button press.
Let's MAKE the droids you've been looking for...
Ok I was able to get my code to work. It now turns on a LED HIGH as long as the button on the remote is pressed.
Once inside the correct case, it executes the block of code then does another remote button check within that block to see if the button is still pressed. Pressing and holding any other button will not do anything because there are no cases to handle the repeat code. The repeat code is only checked after its already inside the proper case.
I have included my code for others to use if interested. I'm sure there are better ways of doing this but this is the simplest way I could figure out how to do this with my level of programming abilities.
// Modified Code By: XybitZ
// ------------------------------------------------------
// Connect IR module pins to Arduino Uno:
// G = Ground, R = 5v, Y = Pin# 11
// LED Anode (+) long lead, to 220 Ohm resistor to pin #9
// LED Cathode (-) Flat side, to Arduino GND pin
// Example code turns on a LED as long as the correct remote button is held down.
// LED is turned OFF when button is released.
#include "IRremote.h"
#define KEY_REPEAT (0xFFFFFFFF)
#define KEY_1 (0xFF30CF) //Elegoo Super Starter Kit remote. Code may differ
IRrecv irrecv(11); // Pin #11 Arduino Uno
decode_results results; // create instance of 'decode_results'
void setup() {
Serial.begin(9600);
Serial.println("IR receiver button code");
irrecv.enableIRIn();
}
void loop()
{
if (irrecv.decode(&results)) { //Check remote button state
Serial.println(results.value, HEX); //Print the value
irrecv.resume(); //Receive the value
switch(results.value){ //Compare values
case KEY_1: //if the button #1 is pressed
redo: //if key held down, code jumps back to here
digitalWrite(9,HIGH); //Turn on LED
delay(130); //Wait 130ms so remote has time to respond. This delay is needed to work
if (irrecv.decode(&results)) { //Check again the button state
Serial.println(results.value, HEX);
irrecv.resume(); //Receive the next value
if (results.value == KEY_REPEAT){ //if value = (0xFFFFFFFF) "still pressed" then redo
goto redo; //
}//end if
} //end if
break; //end case
}//end if
digitalWrite(9,LOW); //turn off LED
}//end if
}//end if
The video
https://youtu.be/xl4-2xWA6Dk
Let's MAKE the droids you've been looking for...
I wouldn't give up on the code yet I am sure you can make it better?
Does this code run?
#include "IRremote.h" int receiver = 11; IRrecv irrecv(receiver); decode_results results; void setup() { Serial.begin(9600); Serial.println("IR Receiver Button Decode"); irrecv.enableIRIn(); // start receiver } void loop() { if (irrecv.decode(&results)) { translateIR(); irrecv.resume(); } } void translateIR(){ // describing remote IR codes { switch(results.value) { case 0xFF629D: Serial.println("FORWARD");break; case 0xFF22DD: Serial.println("LEFT"); break; case 0xFF02FD: Serial.println("-OK-"); break; case 0xFFC23D: Serial.println("RIGHT"); break; case 0xFFA857: Serial.println("REVERSE"); 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 0xFF42BD: Serial.println(" *"); break; case 0xFF4AB5: Serial.println(" #"); break; case 0xFFFFFFFF: Serial.println(" REPEAT"); break; default: Serial.println(" other button "); } // end case } delay(500); // do not get immediate repeat } // end translateIR
It come from this utube video,
https://www.youtube.com/watch?v=iFpAqG90zY0
I didnt give up on the code. It does exactly what i needed. I needed it to loop inside the propper case condition allowing the user to press and hold a key to drive a LED HIGH. The challenge i had was when you press a key and hold the key down (long press), it would only do the operation one time and stop. That was the problem I was having. I solved this issue.
As I demonstrated in my video, the LED turns on and stays on as long as the remote button remains pressed and this is the desired effect. I pressed other keys on the remote in the video to demonstrate that the LED does not turn on which is also the proper result, because if you press and hold a different key it will generate the same repeat code so you dont want that repeat code to triger an undesired case condition.
Let's MAKE the droids you've been looking for...
Have you looked at these two videos: Paul McWhorter Lesson 64 and Paul McWhorter Lesson 65
Haven't watched them myself, but he always gives plenty of good instruction.
SteveG
@codecage i watched both video links you provided and they were informative. I watch a lot of his videos and like the instruction. The only thing not really covered in either video was how to controll somthing by holding down a particular button.
Thanks for the link, I appreciate it.
Let's MAKE the droids you've been looking for...