Arduino IRlib2 - Page 1
Forum section: electronics / general

author: IvoS
author_rank: Frequent Contributor
timestamp: June 19, 2023, 09:20:20 pm
content: I am using this library and I was able to decode my RC5 remote buttons and implement those decoded values (0x2ED1C03F for example) in my loop. However, I am not happy with the decoding behaviorbecause the decoded values stay "latched" in the buffer until the new value is read. If used with switch-case it is not a problem because the new value clears the old one. I am trying to figure out how I can get the value out while I am pressing and holding the remote button, when released, it goes away. On my example:press and hold LED HIGH, button released LED LOW.if (myDecoder.value==0x2ED1C03F) {digitalWrite(greenLED,HIGH);}else {digitalWrite(greenLED,LOW);}I really don't know if I have to go to interrups or to some other file to change this behavior. I am using bare minimum for NEC protocol decode. #include <IRLibDecodeBase.h> #include <IRLib_P01_NEC.h>#include <IRLibRecvLoop.h> Anyone familiar with this library? Thanks.

author: Fire Doger
author_rank: Regular Contributor
timestamp: June 20, 2023, 10:21:13 am
content: Your remote sends the value again and again while holding that's why it goes away when you release the button.You need to rework your code to trigger action on value change, ie it was 0x00 and it became 0x2ED1C03F, not while value == 0x2ED1C03F.

author: IvoS
author_rank: Frequent Contributor
timestamp: June 21, 2023, 09:33:20 pm
content: No, unfortunately it's not the case. It sends the value once and only once the button is pressed and released, not repeatedly while holding it down.

author: macboy
author_rank: Super Contributor
timestamp: July 03, 2023, 01:39:42 am
content: Some remotes will send the code once then send a special "repeat" code while the button is held down. Check if the library you are using exposes that. If it isn't working as you like them modify the code yourself. That's the beauty of open source.

author: ledtester
author_rank: Super Contributor
timestamp: July 03, 2023, 02:31:09 am
content: Quote from: IvoS on June 19, 2023, 09:20:20 pmRemote controls generally don't sent a code when a button is _released_ - they only send a code when a button is pressed or held down. See, for example this stackexchange quesiton:https://arduino.stackexchange.com/questions/66081/how-can-i-stop-dc-motor-when-button-on-remote-is-releasedYou could create your own control which sends one code when a button is pressed and another when it is released.

author: IvoS
author_rank: Frequent Contributor
timestamp: July 05, 2023, 08:21:30 pm
content: OK, so I did some more work with this code while using Serial.print trying to figure out what's going on. Short press returs decoded value quite quickly. Long press returns decoded value and then it goes into the loop in approximately 200ms intervals while holding it down keeps sending 4294967295, which I think is the same as 0xffffffff in HEX.The code structure can be set up in 2 ways. One is a "loop" with <IRLibRecvLoop.h> which is counterintuitive because it does behave like a loop but runs only once the button is pressed, or keeps going in the loop when button is being held down but then it stops when button is released. The second way is a Or, the second way is with <IRLibRecvBase.h> that actually runs continuously in a loop. I think the last decoded value stays in the buffer until the new value is decoded in both ways.

author: cv007
author_rank: Frequent Contributor
timestamp: July 06, 2023, 02:22:39 am
content: QuoteThat is the value of REPEAT_CODE. When a button is held, you get the REPEAT_CODE value from your decoder object (myDecoder.value).The use of IRLibRecvLoop.h means you are blocking on getResults(), which only returns (always returns true) when an ir code is seen (or at least one bit is seen, which then eventually activates a timeout). So is easy enough to deal with your desired code and the REPEAT_CODE, but there is no ir code seen when a button is released so you would be waiting in a loop ( getResults() ) waiting for an ir code that will not be seen so cannot turn off the led when a button is released.You could add an additional timeout to the getResults function-https://github.com/cyborg5/IRLib2/blob/master/IRLib2/IRLibRecvLoop.cppinsert after line 27-Code:if( oldState == HIGH && recvGlobal.recvLength == 0 && ((micros() - startTime) > 300000ul) ){return false;}which would then have getResults() return false for an inactivity timeout (300ms in this case). You can then turn off the led when no activity is seen.Code:void loop(){if( myReceiver.getResults() ){uint32_t ircode = myDecoder.value;if( ircode == 0x2ED1C03F ) digitalWrite( greenLED, HIGH ); //valid ir code, turn on ledelse if( ircode != REPEAT_CODE ) digitalWrite( greenLED, LOW ); //some other ir code (and not a repeat), turn off led//if REPEAT_CODE, do nothing (led is still on, or off)myReceiver.enableIRIn(); //rearm}else digitalWrite( greenLED, LOW ); //inactivity timeout, so turn off led}Using a timeout in getResults() now allows being a little 'late' to the next call and may miss the initial bit transition, so will also depend on how much other code executes between calls and how much tolerance is given for the ir sync timing. If you end up missing codes because of this scheme, then you should just use the interrupt version (or maybe use that anyway).

author: IvoS
author_rank: Frequent Contributor
timestamp: July 06, 2023, 10:17:52 pm
content: QuoteThank you very much for your time. I just did some tests with your sugeestions and it works! It works exactly as you described! I think that interrupt loop would be a better choice since I will have more code for start up sequence and 2 temp sensors watching the channels, so it will definitelly introduce some delay to the loop. It would work but not bulletproof. Here is the loop I tested with: (and thanks again)Code:void loop(){myReceiver.enableIRIn();if (myReceiver.getResults()) {if (myDecoder.decode()) {uint32_t ircode = myDecoder.value;if( ircode == 0x2ED1C03F ) digitalWrite( greenLED, HIGH ); //valid ir code, turn on ledelse if( ircode != REPEAT_CODE ) digitalWrite( greenLED, LOW ); //some other ir code (and not a repeat), turn off led//if REPEAT_CODE, do nothing (led is still on, or off)myReceiver.enableIRIn(); //rearm}}else digitalWrite( greenLED, LOW ); //inactivity timeout, so turn off leddigitalWrite(redLED,HIGH); // test loop to confirm it is looping; other code will go here insteaddelay(100);digitalWrite(redLED,LOW);delay(100);// it works, however; the longer the delay is on this "redLED" the worse it gets and it starts missing// values while holding the button down. Instead of returning 4294967295 all the time// it will randomly return 0 and the greenLED shuts offSerial.print("Decoded value: ");Serial.println(myDecoder.value);}

author: ledtester
author_rank: Super Contributor
timestamp: July 07, 2023, 12:02:05 pm
content: Instead of the delays in this code:Code:digitalWrite(redLED,HIGH); // test loop to confirm it is looping; other code will go here insteaddelay(100);digitalWrite(redLED,LOW);delay(100);just toggle the redLED pin:Code:digitalWrite(redLED, !digitalRead(redLED));This avoids using delay() and you'll still see the redLED blink as it goes through the main loop.If you are going through the main loop too fast, just toggle after every N-th iteration, e.g.:Code:int count = 10;...// in the main loopcount--;if (count == 0) {count = 10;// toggle redLED here}...

author: IvoS
author_rank: Frequent Contributor
timestamp: July 07, 2023, 10:07:11 pm
content: Tried that, very good, thank you.