-1

My goal is to be able to send/receive IR messages in my own custom format and send messages ~10 bytes long. My message object will get serialized down to individual bits, which are transmitted by turning the IR LED on/off at specific timings of my choosing to represent logical ones and zeros. From what I've seen, an IR LED can be turned on/off in either a while loop or as a PWM signal in order to transmit the message. I'm under the assumption the only thing gained by using a PWM signal is that the work there is done on a timer callback and let other code run seemingly simultaneously. For simplicity, I opted for the while loop approach.

The issue I am seeing is one of two. Either the receiver is not reading the timings right, or the transmitter is not turning the LED on/off as fast as I would expect.

For the example code below, the IR LED is turned on for 600 microseconds, and off for 300. (Eventually, my custom messages will be built up using something along these lines.) However, as you can see in the Sample Outputs below the receiver is not seeing the IR signal as on or off for anywhere near that amount of time.

Not sure if this is a setup issue, or something else. The two Arduino boards I'm using are both Arduino Pro ATmega328p boards. For the board sending the IR signal, Pin 6 goes to a 330 Ohm resistor, then to the LED, then to ground. The IR Receiver on the other board has no resistors, just direct connections to pins. When reading the IR signals, I hold the receiver a few centimeters away from the LED.

My questions are:

  1. Is this a viable setup? Should this work? Or am I all wrong in my assumptions and need to look some other way of doing this?
  2. Is my assumption about turning the LED on/off with a while loop vs. a PWM signal true? Or should I remove the loop concept and only use a PWM signal.

IR Transmit Code:

#define IRpin          6

void setup() {
  pinMode(IRpin, OUTPUT);
}

void loop() {
  //LED On
  PORTD |= (1 << IRpin);
  delayMicroseconds(600);

  //LED Off
  PORTD &= ~(1 << IRpin);
  delayMicroseconds(300);
}

IR Receive Code (taken from an online example, only modifications are to output text):

#define IRpin_PIN      PIND
#define IRpin          2

// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define RESOLUTION 20

uint16_t pulses[300][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 (IRpin_PIN & (1 << IRpin)) {
    // 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)) {
      Serial.println("Breaking - Hit max Pulse Low");
      printpulses();
      currentpulse = 0;
      return;
    }
  }
  pulses[currentpulse][1] = lowpulse;

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

void printpulses(void) {
  uint32_t totalMicroseconds = 0;
  for (uint8_t i = 0; i < currentpulse - 1; i++) {
    Serial.print("On(");
    Serial.print(pulses[i][1] * RESOLUTION , DEC);
    Serial.print(");");
    Serial.println("");
    Serial.print("   Off(");
    Serial.print(pulses[i + 1][0] * RESOLUTION , DEC);
    Serial.println(");");

    totalMicroseconds += pulses[i][1] * RESOLUTION;
    totalMicroseconds += pulses[i + 1][0] * RESOLUTION;

    if (i % 8 == 0) {
      Serial.println("");
    }
  }

  Serial.print("On(");
  Serial.print(pulses[currentpulse - 1][1] * RESOLUTION, DEC);
  Serial.print(");");
  totalMicroseconds += pulses[currentpulse - 1][1] * RESOLUTION;

  Serial.println("");
  Serial.print("Total Microseconds: ");
  Serial.println(totalMicroseconds, DEC);
}

Sample Outputs:

Ready to decode IR!
On(20);
   Off(62064);

On(0);
   Off(12060);
On(360);
   Off(1860);
On(440);
   Off(8940);
On(20);
   Off(15460);
On(80);
   Off(25672);
On(40);
Total Microseconds: 127016
On(40);
   Off(6740);

On(300);
   Off(6740);
On(20);
   Off(8520);
On(40);
   Off(6740);
On(1540);
   Off(15720);
On(40);
   Off(34860);
On(20);
Total Microseconds: 81320

On(3000);
   Off(35384);

On(40);
   Off(14180);
On(1220);
   Off(54440);
On(980);
Total Microseconds: 109244

On(200);
Total Microseconds: 200
On(20);
   Off(29160);

On(60);
   Off(26700);
On(60);
   Off(22880);
On(20);
   Off(2928);
On(20);
Total Microseconds: 81848
  • I don't know for sure, but my guess is that while 65 milliseconds is a long time for a microprocessor, it may not be a long time for LED lighting and receiving. It may take the LED longer than you or I would think to emit at a readable level, for instance- I don't know. I would at least consider slowing things waaaay down- like seconds - and see if you get reliable transmission and reception at very very slow speeds. You may also need to consider outside light interference, movement of your hand, etc – mikeY Jan 14 at 20:34
0

I ended up also asking this question at electronics.stackexchange.com. I know that's frowned upon, but the topic really did toe the line between being an Arduino subject or electronics.

To summarize the accepted answer, no IR messages cannot be sent/received the way I thought. The IR LED needs to be on/off at a frequency that matches what the receiver is set to be able to receive. Generally 38kh. So On for 13 microseconds, then Off for 13 microseconds. Then repeat.

https://electronics.stackexchange.com/questions/417387/precise-on-off-control-for-ir-led/417391

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.