- Placing serial print statements @9600 might not be the wisest thing to do when clocking data.
Did something similar a while back:
#include "IRremoteNEC.h"
//=============================================================================
//IR remote
//NEC - IR code
//By: LarryD, Huge thanks to Jack Christensen
//
//For the remote control, see: http://goo.gl/nvDuhD
//
//"IRremoteNEC.cpp IRremoteNEC.h"
// PERMISSION TO DISTRIBUTE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// LIMITATION OF LIABILITY
// The software is provided "as is", without warranty of any kind, express or implied,
// including but not limited to the warranties of merchantability, fitness for a particular
// purpose and noninfringement. In no event shall the authors or copyright holders be liable
// for any claim, damages or other liability, whether in an action of contract,
// tort or otherwise, arising from, out of or in connection with the software
// or the use or other dealings in the software.
//
//IRremoteNEC.cpp(.h) - A class to retrieve IR commands from 44/17 Button IR Remote
//Tested with Arduino IDE 1.06 on an UNO
//
// Rev 1.00 January 25, 2015 functional code
// Rev 1.01 February 1, 2015 created the library files IRremoteNEC.cpp and .h
//
//=============================================================================
//*****************************************************************************
void irISR(void);
//======== VARIABLES USED BY THE ISR -- Must be accessed atomically!
volatile byte irFlag; //a flag stating we have seen an edge
volatile unsigned long thisMicros; //time the current edge happened
//======== LOCAL COPIES OF ISR VARIABLES ========
unsigned long thisMicrosLocal;
//
//*****************************************************************************
// c l a s s I R r e m o t e N E C
//*****************************************************************************
//Constructor
IRremoteNEC::IRremoteNEC(byte IRpin)
{
IRpin_ = IRpin;
} // END of IRremoteNEC()
//**********************************************************
//Initialization
void IRremoteNEC::beginIR()
{
pinMode(IRpin_, INPUT_PULLUP);
counter = 0;
validStart = false;
thisMicrosLocal = micros();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
thisMicros = thisMicrosLocal;
}
irFlag = 0;
//We must convert the pin # to the interrupt # (i.e. 2-2=0 or 3-2=1)
attachInterrupt (IRpin_ - 2, irISR, FALLING); // attach IR interrupt handler using D2 or D3
} // END of beginIR()
//**********************************************************
//Return the current state of the interrupt flag.
byte IRremoteNEC::getIRflag()
{
return irFlag;
} // END of getIRflag()
//**********************************************************
//Reset the state of the interrupt flag.
void IRremoteNEC::resetIRflag()
{
irFlag = 0;
} // END of resetIRflag()
//**********************************************************
//Handle falling edge detection, return IR code if a valid one exists.
//NOTE: IR remote "repeat" codes are ignored and not returned.
byte IRremoteNEC::checkCode()
{
byte byteRecived = 0; //returned variable to the CALLing code
byte rxBit = 0; //the value of the received bit
//Calculate the time between the last two falling edges.
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
thisMicrosLocal = thisMicros;
}
unsigned long temp = thisMicrosLocal - lastMicros;
//For the next iteration, save the edge time, which just happened.
lastMicros = thisMicrosLocal;
//Are we over the start bit upper limit of 13.8mS for the 44/17 button IR remote code?
if (temp > 13800)
{
//There must have been quite some time since the last falling edge.
//Save the current time (beginning time) as the starting edge for this message.
startMillis = millis();
}
//One complete message is (measured 67.5mS) ~75mS long.
//If we go over this, reset things i.e. get ready for the next message.
//As a benefit this removes (ignores) any repeat codes that come in.
else if(millis() - startMillis > 75)
{
//Too much time has elapsed since the first edge of the message.
//Start over.
validStart = false;
}
//Are we inside the limit of the start bit: (measured 13480) 13200uS to 13800uS
else if((validStart == false) && (temp > 13200))
{
//This is a valid start time
counter = 0;
validStart = true;
//4 bytes are coming, initialize their storage.
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
}
//Are we into data bits: (measured 1130) 900 to 1300uS is a 0 bit,
//(measured 2250), 2000 to 2500uS is a 1 bit.
else if((validStart == true) && (temp > 900) && (temp < 2500))
{
//Is this bit a 1?
if(temp > 2000)
{
rxBit = 1;
}
//Is this bit a 0?
else if(temp < 1300)
{
rxBit = 0;
}
//Timing was not valid!
else
{
//The bit width was not within the above range, start over.
validStart = false;
counter = 0;
}
//Put this bit in the correct position in the current byte.
//example: let us say we are doing bit 19
// data[19/8 is byte 2] |= rxBit << (19%8 gives a shift of 3))
// data[2] = data[2] | rxBit << 3
data[counter/8] |= (rxBit << (counter%8));
//Have we received all the bits yet? (0-31 is 32 bits)
if(counter >= 31)
{
//This remote always sends: 0x00 as Address and 0xFF as ~Address
//Example: 0x00 0xFF 0x04 0xFB would be a valid message
//Was this a valid IR code? i.e. Address = ~Address && Data = ~Data
if((data[0] == (~data[1] & 0xFF)) && (data[2] == (~data[3] & 0xFF)))
{
//data[2] contains the valid IR button code
byteRecived = data[2];
}
//We are now finished with this IR code, get ready for the next valid start.
validStart = false;
} //END of if(counter >= 31)
//Get ready for the next bit.
counter++;
} //END of if(validStart == true && (temp > 900) && (temp < 2500))
return byteRecived; //If zero (0) there is no valid IR button code
} // END of checkCode()
//=============================================================================
// H E L P E R F U N C T I O N S
//=============================================================================
//*****************************************************************************
// Interrupt Service Routine (ISR)
void irISR()
{
thisMicros = micros(); //record the time the edge happened
irFlag = 1; //Flag that we have seen a falling edge
} // END of irISR()
//*****************************************************************************