IR Remote controllers for Arduino are super cheap and quite useful. Unfortunately all the libraries I've seen used polling, which makes them tough to use in a project. So, I wrote an interrupt driven IR remote library. This makes it really easy to have your project doing all sorts of activities and still be able to receive IR remote controls. It uses PCINT, so the IR controller can be on any interrupt handling pin (including support for PCINT on Mega 2560). You can download the lib from here: http://www.zbotic.com/index.php/download/
Note that zipfile includes other libraries - for just the remote control, only unzip IRController, Device, and PCInterrupt. Also, this has codes for one type of remote - you will likely have to replace the codes with your remote's codes.
Sample usage
#include "PCInterrupt.h"
#include "Device.h"
#include "irController.h"
IRController irController;
// Note: modify myHardware.h in libraries\device and add change IR_PIN to the value of the pin you have your IR controller on.
void setup()
{
Serial.begin(9600);
Serial.println("Started");
int res = irController.begin(IR_PIN, OTHER_DEVICE);
if (res != SUCCESS) {Serial.println("error="); Serial.println(res);}
}
void loop(){
int val = irController.read(); // Returns negative value if no new command rcvd
if (val >0) Serial.println(val);
delay(500);
}
I think/hope that it's just a matter of changing the key mapping section for other remotes (shown below).
//! Decode specific remote-control keys - override this with routine for your Remote
int IRController::decode(int rawCmd)
{
switch (rawCmd)
{
case 32640: // turns on/off power
return(POWER_BUTTON);
break;
case 32385: // FUNC/STOP
return(FUNC_BUTTON);
break;
case 32130: // |<<
return(BACK_BUTTON);
break;
case 32002: // >||
return(PLAY_BUTTON);
break;
case 31875: // >>|
return(FORWARD_BUTTON);
break;
case 32512: // VOL+
return(VLMUP_BUTTON);
break;
case 31492: // VOL-
return(VLMDOWN_BUTTON);
break;
case 31620: // v scroll down
return(DOWN_BUTTON);
break;
case 31365: // ^ scroll up
return(UP_BUTTON);
break;
case 30982: // EQ
return(EQ_BUTTON);
break;
case 30855: // ST/REPT
return(REP_BUTTON);
break;
case 31110: // 0
return(0);
break;
case 30600: // 1
return(1);
break;
case 30472: // 2
return(2);
break;
case 30345: // 3
return(3);
break;
case 30090: // 4
return(4);
break;
case 29962: // 5
return(5);
break;
case 29835: // 6
return(6);
break;
case 29580: // 7
return(7);
break;
case 29452: // 8
return(8);
break;
case 29325: // 9
return(9);
break;
default:
errorCode = ERROR_UNKNOWN_RSP;
return(key); // Set errorCode code but return unrecognized raw key
break;
}
}
So I'm trying to use this library, but I can only get one keypress and then it won't receive any more. I modified the example code loop function to this:
void loop(){
int val = irController.read();
if (val == 0) Serial.println(val);
}
The output comes out like this on the Serial Monitor
Hi guys, I am getting a weird result in the Serial Monitor when receiving remote commands. On each button press, Raw Val is a different number! Also the Bits rcvd field seems to retain the bits long after I let go of the button. Is that supposed to happen? I'm reading over ircontroller.cpp but haven't quite understood it all yet. Thanks for any suggestions you have!
Here's the debug output:
Started
** IRController v1.3
using pin=2
Interrupt attached
Bits rcvd=2
Bits rcvd=2
Bits rcvd=2
Bits rcvd=2
Bits rcvd=2
Bits rcvd=9
Bits rcvd=18
Bits rcvd=28
Bits rcvd=33
Raw Val=16513
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=33
Raw Val=23077
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=39
Bits rcvd=2
Bits rcvd=2
Bits rcvd=2
Bits rcvd=2
Bits rcvd=5
Bits rcvd=13
Bits rcvd=24
Bits rcvd=33
Raw Val=259
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=30
Raw Val=23077
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=31
Raw Val=30568
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=9
Bits rcvd=11
Bits rcvd=20
Bits rcvd=32
Raw Val=1799
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=31
Raw Val=24480
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=33
Raw Val=20617
Unable to map. Update IRMapping.h with the raw val above.
Bits rcvd=18
Bits rcvd=18
Bits rcvd=18
Bits rcvd=18
Bits rcvd=18
Bits rcvd=18
Bits rcvd=18
When I try to compile IRRControllerTest code, I get these messages:
IRControllerTest.cpp:3:26: error: IRController.h: No such file or directory
IRControllerTest:7: error: 'IRController' does not name a type
IRControllerTest.cpp: In function 'void setup()':
IRControllerTest:11: error: 'controller' was not declared in this scope
IRControllerTest.cpp: In function 'void loop()':
IRControllerTest:19: error: 'controller' was not declared in this scope
I have the same problems, as well. The interrupt handling seems to be broken, it just polls an interrupt for every 2-3 touch. Beside that, it returns a random code, regardless of the pressed key.