I am working on IR remote code run on Arduino UNO I can already get it work. but when I press the button and hold, the output is sent with the same value repeatly. So,the quesion is how can I do to make it send out only one output while I press and hold the button.
this is my code
#include <IRremote.h>
int RECV_PIN = 5;
#define PB 3392264773 // button code
#define VUP 3476004267 // button code
#define VDN 2998643817 // button code
#define SRC 387001607 // button code
#define MUTE 305976139 // button code
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
if (results.value == PB) {
Serial.println("Power");
}
if (results.value == VUP) {
Serial.println("Vol UP");
}
if (results.value == VDN) {
Serial.println("Vol Down");
}
if (results.value == SRC) {
Serial.println("Select");
}
if (results.value == MUTE) {
Serial.println("Mute");
}
irrecv.resume(); // Receive the next value
}
}
and this is output when I press and hold the button
Power
Power
Power
Power
Power
Vol UP
Vol UP
Vol UP
Vol UP
Vol UP
Vol UP
Vol UP
Vol UP
Thank you for all answers. Tanwa
2 Answers 2
by adapting chrisl's idea, I got it done. the code is here.
#include <IRremote.h>
int RECV_PIN = 5;
#define PB 3392264773 // button code
#define VUP 3476004267 // button code
#define VDN 2998643817 // button code
#define SRC 387001607 // button code
#define MUTE 305976139 // button code
int pre_p = 0;
int pre_src = 0;
int pre_mu = 0;
//trigger
int p = 0;
int src = 0;
int mu = 0;
int pw = 0;
int s = 0;
int m = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long previous_timestamp;
unsigned long check_timestamp;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
if (results.value == PB){
p = 1;
if(p != pre_p){
pw = !pw;
//Serial.println(pw);
Serial.println("pw");
Serial.println(pw);
}
}
if (results.value == VUP) {
Serial.println("Vol UP");
}
if (results.value == VDN) {
Serial.println("Vol Down");
}
if (results.value == SRC) {
src = 1;
if(src != pre_src){
s = !s;
Serial.println("s");
Serial.println(s);
//Serial.println("Select");
}
}
if (results.value == MUTE) {
mu = 1;
if(mu != pre_mu){
m = !m;
//Serial.println("Mute");
Serial.println("mu");
Serial.println(m);
}
}
irrecv.resume(); // Receive the next value
pre_p = p;
pre_src = src;
pre_mu = mu;
p=0;
src = 0;
mu = 0;
previous_timestamp = millis();
}
if(millis() - previous_timestamp > 200){
pre_p = 0;
pre_src = 0;
pre_mu = 0;
}
}
As noted in the comments, you cannot change what the remote is sending. Though I guess, that it would be OK for you to just react to the first occurence of a specific value send consecutively. For that you first need to check the time between these consecutive values send, when holding the button down. That (plus a small margin) will be the threshold to recognize multiple distinct button presses. Note: Depending on the rate, that the remote is sending when holding a button, this might mean, that you cannot distinguish between holding a button and pressing it multiple times in a fast pace.
First define a variable to hold the previous decode results and a timestamp for saving when it arrived:
decode_results previous_results;
unsigned long previous_timestamp;
On receiving a new value via IR, check if the new value is the same as in previous_results
. If yes, don't execute the code checking for the actual value. If no, then update previous_results
with the new value and act upon the actual received value. Then set the timestamp to the current millis()
value and resume receiving.
if (irrecv.decode(&results)) {
if(results != previous_results){
previous_results = results;
if (results.value == PB) {
Serial.println("Power");
}
....
}
previous_timestamp = millis();
irrecv.resume(); // Receive the next value
}
Now you need to reset the previous_results
variable after a specific time threshold, so that consecutive presses on the same button can be registered. Add a corresponding millis()
statement to your loop()
function:
if(millis() - previous_timestamp > 500){
previous_results = 0;
}
Note: The value of 500ms is just a wild guess. As described at the start, you need to find that value yourself, fitting to your remote. Play a bit with this value until you are satisfied.
All in all something like this:
#include <IRremote.h>
int RECV_PIN = 5;
#define PB 3392264773 // button code
#define VUP 3476004267 // button code
#define VDN 2998643817 // button code
#define SRC 387001607 // button code
#define MUTE 305976139 // button code
IRrecv irrecv(RECV_PIN);
decode_results results;
decode_results previous_results;
unsigned long previous_timestamp;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
if(results != previous_results){
previous_results = results;
if (results.value == PB) {
Serial.println("Power");
}
if (results.value == VUP) {
Serial.println("Vol UP");
}
if (results.value == VDN) {
Serial.println("Vol Down");
}
if (results.value == SRC) {
Serial.println("Select");
}
if (results.value == MUTE) {
Serial.println("Mute");
}
}
previous_timestamp = millis();
irrecv.resume(); // Receive the next value
}
if(millis() - previous_timestamp > 500){
previous_results = 0;
}
}
Note: I have not tested this code in any way.
-
I got it done by adapting your comment. Thank you very muchTanwa Kankang– Tanwa Kankang08/29/2023 17:14:17Commented Aug 29, 2023 at 17:14
repeat
code instead of key code when a button is held down ... if that is the case, then the IR library could be modified to generate repeated code that is distinct from the keypress code