Thursday, 21 June 2012

Infra red Decoder

As i have been playing with robots, i decided either to use Infra red for a remote control, or Radio Control.
So for now ill be testing some Infra red.
As we all have older remotes at home lost in our drawers, i decided t use the Arduino Mega to decode one of them and use it maybe.

So lets start with what a Infra red emitter/receiver does in a remote control
Also check

So, i ordered a TSOP2438 IR receivr that works with a modulated carrier at 38Khz.
And i got it connected like this, after reading the datasheet:
-Yellow to Digital Pin 19 ( remember i am using the Mega 2560...)
-Black to ground
-Red to 5V

So, lets see the code

/* Raw IR decoder sketch!
 This sketch/program uses the Arduno and a TSOP2438 to 
 decode IR received. This can be used to make a IR receiver
 (by looking for a particular code)
 or transmitter (by pulsing an IR LED at ~38KHz for the
 durations detected 
 Code is public domain
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the Pin D19 on the Mega2560(PD2
// see for the 
// UNO pin mapping with ATMega168/328

#define IRpin_PIN      PIND
#define IRpin          2
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20 
// we will store up to 100 pulse pairs (THIS IS A LOT)
uint16_t pulses[100][2];  // pair is high and low pulse 
uint8_t currentpulse = 0; // index for pulses we're storing
void setup(void) {
  Serial.println("Ready to decode IR!");
void loop(void) {
  uint16_t highpulse, lowpulse;  // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length
//  while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & _BV(IRpin)) {
     // pin is still HIGH
     // count off another few microseconds
     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
  pulses[currentpulse][1] = lowpulse;
  // we read one high-low pulse successfully, continue!
void printpulses(void) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");

So , i then pointed the remote to the receiver and pressed the UP in the cursor,
and this is what i got...

If we ignore the first OFF pulse (its just the time from when 
the Arduino turned on to the first IR signal received) and 
the last ON pulse (it the beginning of the next code), 
you'll find the power code is:

920  usec, 820 usec, 
900  usec, 820 usec, 
1760 usec, 820 usec,
900  usec, 820 usec, 
900  usec, 820 usec, 
900  usec, 1680 usec, 
1780 usec, 1680 usec, 
1760 usec, 1680 usec, 
1760 usec, 820 usec, 
920  usec, 22624 usec, 
920  usec, 800 usec, 
920  usec, 800 usec, 
1780 usec, 820 usec, 
900  usec, 820 usec, 
900  usec, 820 usec, 
900  usec, 1680 usec, 
1780 usec, 1660 usec, 
1780 usec, 1680 usec, 
1780 usec, 800 usec

( be continued)

PS- Of course we can use a Oscilloscope instead...

No comments:

Post a Comment

Feel free to contact me with any suggestions, doubts or requests.