Hello to all, I'm another new member.
I've searched a bit about IR Receiving recently. Most arduino sketches or AVR code are using the main loop for fetching High or Low pulses time. I haven't found any multi-protocol AVR/Arduino code yet.
I tried the current sketches, and they work ok, but for my purpose, I need to be able to recognize most protocols, live, not asking to press a button multiple times to record it, but decoding it to know it's value. I will gladly release any working code, in the best case making a library for IR receivers.
In order to be able to decode multiple protocols, both High and Low pulses times are required. Sony protocol uses high pulses, Recs-80 uses low pulses, RC5 uses both.
Also, in order to be useful (and to fit my coding standards), the main loop needs to be freed.
Another thing I want to do is to verify the code by testing many protocols at the same time. This can be done by verifying the same array of raw times or having an array for each protocol.
Finally, the pulses time in Microseconds needs to be pretty accurate, but from what I saw, the pulses are at 300 microseconds appart (in the Sharp protocol) or more.
There is a multi-protocol ir receiver code already existing, but it's not for the arduino, and I don't have the knowledge to convert this time critical and interrupt based code to arduino code. So I'll try to make my own version from what I understand.
For the implementation, I think the best thing to do would be to attachInterrupt using CHANGE to monitor both HIGH and LOW times and a flag variable for the current value (High or Low). To get the times, I think micros() should be accurate enough.
My problem right now, (the reason of this post, and this incomplete code), is that the interrupt function is too slow. That means that the interrupt keeps interrupting itself, and my previous time is now bigger than my current time.
Still, I'm currently debugging the RC5 protocol which should be around 800 microseconds before launching another interrupt, so I don't know what is taking so much time, except perhaps a serial print for debugging.
Here's my current code. If there are some who think that this might be useful and are willing to help me get through this, or if this is undoable because of technical reasons that I don't know yet, feel free to help me go in the right direction.
int LedPin = 13; // For debugging purposes
int InterruptNb = 0; // Number of the interrupt
int InterruptPin = 2; // Matching pin number of the interrupt
int CurrDir; // High or Low
unsigned long PrevTime; // What was the time in the previous call
unsigned long CurrTime; // What was the time in the previous call
unsigned long PrevHigh = 0; // Previous High pulse in Microseconds
unsigned long PrevLow = 0; // Previous Low pulse in Microseconds
unsigned long CurrHigh = 0; // Current High pulse in Microseconds
unsigned long CurrLow = 0; // Current Low pulse in Microseconds
void IRDirectionChange (void)
{
// First thing, let's get the current time, it's the most time critical element
CurrTime = micros ();
// TODO: take care of the overflow every 70 mins...
if (CurrDir = HIGH) {
// The High pulse just ended, let's get it's time
PrevHigh = CurrHigh;
CurrHigh = CurrTime - PrevTime;
} else {
// The Low pulse just ended, let's get it's time
PrevLow = CurrLow;
CurrLow = CurrTime - PrevTime;
}
// Let's change direction for the next one
CurrDir = !CurrDir;
// Let's get ready for the next call
PrevTime = CurrTime;
// Let's send the current value to the decoders
// IRDecode ();
/*
Serial.print (PrevHigh);
Serial.print (" ");
Serial.print (PrevLow);
Serial.print (" ");
Serial.print (CurrHigh);
Serial.print (" ");
Serial.print (CurrLow);
Serial.println (" ");
*/
}
void setup (void)
{
Serial.begin (115200);
// First, let's get the current direction
pinMode (LedPin,OUTPUT);
pinMode(InterruptPin, INPUT);
CurrDir = digitalRead (InterruptPin);
// Let's get ready to calculate
PrevTime = micros ();
// Starting now, every change of direction will be timed by this procedure
attachInterrupt (InterruptNb,IRDirectionChange,CHANGE);
}
void loop (void)
{
// Do anything here...
}
void IRDecode (void)
{
IR_Decode_Sony ();
IR_Decode_RC5 ();
IR_Decode_RC6 ();
// etc.
}
void IR_Decode_Sony (void)
{
// Sony: Uses High pulse time
// We check if we are in a low pulse to know what was the HighTime
/* Pseudo Code
if CurrDir = LOW
if Sony.Valid = False and CurrHigh < Sony.MaxStart and CurrHigh > Sony.MinStart
Sony.Valid = True
Sony.ArrayIdx = 1
else if Sony.Valid and CurrHigh < Sony.MAX and CurrHigh > Sony.Min
Sony.ArrayIdx++
Add this bit to the Sony Array
else
Sony.Valid = False
*/
}
void IR_Decode_RC5 (void)
{
// RC5: 889 microseconds pulses
// High pulse + Low pulse for a 0
// Low pulse + High pulse for a 1
// For example, 889us low, 1778us high, 889us low = 1,0
/* Very rough Pseudo Code
if CurrHigh <> 1778 and CurrHigh <> 889
RC5.valid = false
if CurrLow <> 1778 and CurrLow <> 889
RC5.valid = false
if RC5.valid and CurrHigh = 889 and CurrLow = 889 and CurrDir = LOW
RC5.ArrayIdx++
Add a 0 to the index
else if RC5.valid and CurrHigh = 889 and CurrLow = 889 and CurrDir = HIGH
RC5.ArrayIdx++
Add a 1 to the index
etc.
*/
}
void IR_Decode_RC6 (void)
{
}