1

I am using an amazing code to send/read infrared pulses without any external library. The code is fine and I took about 1 hour to fully understand it. The only thing I didnt understand is the variable RESOLUTION. I believe it should be 0 not 20. I think it should be as low as possible.

You can see the code at:

https://learn.adafruit.com/ir-sensor/using-an-ir-sensor

or below:

/* Raw IR decoder sketch!
This sketch/program uses the Arduino and a PNA4602 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, check out www.ladyada.net and adafruit.com
for more tutorials!
*/

// 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 same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
// for MEGA use these!
//#define IRpin_PIN PINE
//#define IRpin 4

// 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.begin(9600);
  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 & (1 << IRpin)) {
     // pin is still HIGH

     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // 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)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // 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
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses
* RESOLUTION, DEC);

    Serial.print(" usec, ");
    Serial.print(pulses[1] * RESOLUTION, DEC);
    Serial.println(" usec");
  }

  // print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
}
per1234
  • 4,088
  • 2
  • 22
  • 42
Samul
  • 215
  • 2
  • 9

1 Answers1

2

Most IR remotes send pulses that are at least 400 micro seconds long. E.g. on a NEC IR remote you get pulses that are 560 or 2240 microseconds long (depending on whether it's sending a 1 or a 0).

So with a RESOLUTION of 20 you get at least 20 'pulse counts' for a 0 and 80 for a 1. Because remotes aren't that precise in you'll get somewhere between e.g. 18 and 22 or 78 and 82. Those values are different enough to easily detect whether a 0 or 1 was send.

Changing this RESOLUTION to e.g. 2 will give you 200 or 800 pulsecounts. You'll get a more precise timings from a still imprecise source. But this better precision is useless.

PS setting it to 0 could break the code, as the highpulse and lowpulse are only 16 bit integers so they will overflow after 65536, which will happen pretty fast.

Hope that helps somewhat. Just let me know is anything is still unclear.

Gerben
  • 11,286
  • 3
  • 20
  • 34
  • Thank you so much! But I still didnt understand one thing you said: I agree that 20 of resolution would allow me to get 20 'pulse counts' of 400 microseconds. But the problem is that in the code the delay is 20 microseconds ->> delayMicroseconds(RESOLUTION); <<--. With a delay of 20 microseconds I could not even get a complete pulse according to your explanation cause a 0 pulse would request 400 microseconds. What am I understanding wrong? – Samul Nov 22 '14 at 16:56
  • This 'RESOLUTION' is a kind of misleading name. It is limiting the number of measurements per second. With a value of 20, you'd end up with 20 measurements per 400uS. (Note the the IR receiver doesn't return the 38kHz signal, just a LOW or HIGH, depending on whether it's detecting a 38kHz light-source). Hope that helps, otherwise let me know. – Gerben Nov 22 '14 at 17:23
  • you are amazing. Now I can understand it. I read your answer 6 times and finally I (think) I understand it. The only thing wasnt clear (to me) is your 3rd paragraph's answer. A smaller resolution would definately provide more precise pulsecounts (or pulse lenght) so why should it be 1 or 2 instead of 20? I understand that 0 could overflow the highpulse variable and maybe 1 too, but what about 2 or 3? Why 20? If a pulse lenght is 100us then a 20 value for resolution would generate 20% of error that could break my goal when I try to send back the signal. – Samul Nov 22 '14 at 20:32
  • If your goal it to replay the IR pulses, a lower value might indeed be a good idea. But if you just want to decode the signal, the ir "protocols" have such a huge difference in 0 or 0 signals, that even very inaccurate data is good enough to decode. – Gerben Nov 23 '14 at 19:22
  • Hi Gerben, yes I read about the most used protocols of infrared like NED but still RESOLUTION looks a little weird in that code. Do you have any idea a better value than 20? Maybe 3? Could you please clear what you wanted to say with " have such a huge difference in 0 or 0 signals, that even very inaccurate data is good enough to decode."? – Samul Nov 24 '14 at 02:21
  • Oops. Should have been 0 or 1. E.g. in NEC a 1 takes 4 times as long as a 0. Pretty hard to misread that. By the way, it is NEC, not NIC or NED. – Gerben Nov 24 '14 at 14:17
  • Thank you for correcting me, it's NEC! :) Finally I understood it! – Samul Nov 25 '14 at 00:10