Played around with it a bit more...and this version only has 2 x 2 keys that return duplicate numbers, on my MCE infrared remote control.
You will notice now that you get the toggle effect included (e.g. for the power key you will get 2 different numbers, alternating every press and for every key).
This version compiles only slightly larger than the previous one. So all you need to do is trigger your own code when you get either value for a Power press.
The main changes in the new code is that it now measures the lenght of each full pulse, whereas the previous version measured only the length of the high part of each pulse.
(Also note, IR receivers deliver an inverted signal to the Arduino).
This is indeed a cool way to detect IR signals for a small footprint device like the ATTiny family, without using a full blown library, like IRremore or IRLib. However, there is no guarantee that other remotes would activate the signal. I tested an LG remote using an NEC IR protocol and it only returns '0' every time and on a Sony remote, it returns a different set of values, which is good. To change this to work with NEC, it should only be a matter of changing the value '444' in the code to match the NEC timings.
Let me know if there are any problems or 'scope creep'
Code: Select all
/*
Software to demonstrate how to decode IR signals from a Microsoft style MCE Infrared Remote Control.
This code detects the keys pressed, with a minimum of overlap between keys.
The purpose was to have a small footprint of code less using less than 1.5k flash, to fit on to an ATTiny and to detect when the power key was pressed o nthe remote,
without using up all of the memory on the ATTiny
.
Remove the all Serial statements to shrink the code to under 1.5k (UNO)
Author: AnalysIR, http://www.AnalysIR.com/
Licence: Free to use, without restriction, by people with AnalysIR (excluding demo).
Please credit the Author and provide a link to the website above, where feasible.
This code should filter out most other common IR protocols.
Also, works for Sony protocol and can be adjusted to work for almost any protocol, where a small footprint is required.
It identifies the keys pressed, but not using the official decoding methods. In some cases two or 3 keys may return the same value (for dummyValueIR)
If you need to uniquely identify every key then the code must be updated accordingly.
*/
//This is just a simple way to define what we want
#define pin2HIGH digitalRead(2)
const byte IR_Pin =2;//pin to receive demodulated IR signal
unsigned long timeA=0;
unsigned long dummyValueIR=0; //this store the 'dummy' value we calculate for each signal
byte retVal=0;
byte pulseCount=0; //counts the number of high pulses in each signal
void setup(){
Serial.begin(115200); //start serial connection
//configure pin2 as an input and enable the internal pull-up resistor
pinMode(2, INPUT_PULLUP);
while (!pin2HIGH); //wait here until pin 2 is high = default idle state
Serial.println("Get AnalysIR at www.AnalysIR.com");
}
void loop(){
if (!pin2HIGH) { //we want to measure the low pulses only on the IR Receiver (IR receiver provides the actual signal inverted)
timeA=micros(); //get the time now
retVal=getPulseTicks(); //return the number of 444 uSecs in the pulse
if (retVal>2 && retVal<6) dummyValueIR =dummyValueIR*2+retVal; //pretend this is a '1'
else dummyValueIR =dummyValueIR*2; ////pretend everything else is a '0'
//we are finishedlooking for the Power signal when we get 34 signals
if (pulseCount>33) delay(1000);//force timeout once we have enough pulses
}
if((micros()-timeA)>1000000){ //only report event 1 sec after last pulse
if (pulseCount>0) {
Serial.print(pulseCount);
Serial.println(" Pulses Counted");
Serial.print(dummyValueIR);
Serial.println(" Timer Expired");
}
dummyValueIR=0;
timeA=micros();
pulseCount=0; //reset for next one
}
}
byte getPulseTicks(){ //each tick is 444 uSecs, returns number of tics for full pulse
while (!pin2HIGH && micros() <(timeA+3500) );//wait here until it goes low or times out
if(micros() >(timeA+3500)) {
pulseCount=255;
return (micros()-timeA+200)/444;//error signal
}
while (pin2HIGH && micros() <(timeA+3500) );//wait here until it goes high or times out
//now we have captured the time for the full pulse (or timedout)
if(micros() >(timeA+3500)) return 2;//special for end of valid signal
//otherwise return value for normal bit
pulseCount +=1; //keep track of the number of pulse received
return (micros()-timeA+200)/444;//all RC6 pulses are in multiples of 444 uSecs, the 200 is to round it up to allow for variations caused by IR Receivers
}