I have two Infrared Transceiver modules from TFDU4101-TR3 on two separate boards each interfaced to ATMega164PA microcontroller. To drive these transceivers an endec is needed which I have not used in my design due to budget constraints.

So what I am trying to do is bit-banging. The RX and TX follow normal standard, RX is active low and TX is active high. I am toggling the TxD pin one 'Board A' 50 times at 5 Khz to send 50 pulses to the receiver. On 'Board B' I have implemented a PIN change interrupt which should technically receive 100 pulses (2 pulses for each transmit pulse that it receives). This is not the final design, I just learning and experimenting how to transmit data from one board to another.

Now the problem is that when I send 50 pulses from Board A to Board B, I do not get 100 pulses, but instead I sometimes get 90 or 81 or 98. In short I don't get the intended number of pulses. Is there something wrong with my approach?

Please let me know if any further information is needed.


2 Answers 2


The general approach sounds OK but you need to be careful that you don't exceed the maximum transmit pulse length. It appears from the datasheet 20 uS is a typical pulse length and if exceeded by too much you can see it will cause the LED driver to be disabled:

This Schmitt-Trigger input is used to transmit serial data when SD is low. An on-chip protection circuit disables the LED driver if the TXD pin is asserted for longer than 50 μs (max. 300 μs).

So assuming your 5 KHz is a square wave you'll have exceeded that pulse duration. Once that's sorted out things should be more reliable, although the last time I used an IrDA transceiver I was getting on or two percent of packets that were corrupted so it's worth considering error detection depending on what you're doing.

It's also worth noting that some Atmel (and other) microcontrollers have a USART mode that complies with IrDA timing, although after a quick look at the datasheet that particular part doesn't appear to have that feature.

  • \$\begingroup\$ Thanks for your answer PeterJ. You are correct about not being able to use USART. I connected it to the micro through USART but I was receiving rubbish on the other side. The datasheet is not clear about this and has a very small note saying 'an endec is required for interface to USART' which is very annoying. As far as the typical pulse length is concerned, 20uS is about 50 KHz that means the max speed the transmitter can be toggled at is 50 KHz, but the frequency I'm running at is 5 KHz. \$\endgroup\$ Aug 10, 2014 at 5:43
  • \$\begingroup\$ Also, I just found that I do have packet loss. With a revised version of my code, I am receiving the same amount of pulses on the other size from the transmitter but sometimes here and there there are losses \$\endgroup\$ Aug 10, 2014 at 5:44
  • \$\begingroup\$ @David, IrDA can go to higher speeds but I guess that typical amount is a good one to stick with when you don't need anything faster. Might be something to play around to see what difference it makes in practice, for the project I was doing (that had to connect to a PC) I found 57600 seemed to be the best standard baud rate. \$\endgroup\$
    – PeterJ
    Aug 10, 2014 at 5:51
  • \$\begingroup\$ How would you define 'best'? Is that in terms of less packet loss or greater range or something else? \$\endgroup\$ Aug 10, 2014 at 6:01
  • \$\begingroup\$ @David yes seemed to have the lowest packet loss / besr range, but it was a different manufacturer so you may get different results. It was something where the data transfer was only 50 KB or so speed wasn't a big issue. \$\endgroup\$
    – PeterJ
    Aug 10, 2014 at 6:04

The TFDU4101 is designed to transmit data at 115.2 kbit/s. That is one of the IrDA standard speeds. So the device is optimised around that.

So one bit duration is about 1,000,000us/1152.kbit/s = 8.7us

The datasheet says the typical RXD (received) pulse width is specified as 2.2us, which would mean 4 pulses per bit of a roughly 460,800kHz carrier signal. So it looks like it adds up.

You don't have to send data at that rate. However aim to use similar base-carrier modulation, and then the chip won't be fighting you. Use an integer number of cycles of that carrier frequency to send your data, with a distinctive number of cycles to represent 0 an d 1, and it should be reasonably robust and reliable. Though you might need to use error detection as well.

460,800kHz is quite high-speed to bit bang, though it is do-able. You might start by trying to send data that way.

I try to get the base carrier modulation signal done in hardware to reduce the load on the CPU.

The way I do transmission is to set up an MCU timer to get be as close to the base-modulation cycle time as practical, and use that to drive the transmitter LED. Some of the ATmel timers let you set the maximum count, and with a capture/compare value of 1/2 maximum count, it'll generate a square wave. (An alternative is to divide the clock, using a pre-scale value)

Then I use the capture/compare register value (0 or max, depending on the modulation scheme) to gate that signal with the data. The base carrier signal will be generated correctly using a compare value of 1/2 maximum count, even if my software is a bit busy.

  • \$\begingroup\$ I have bit banged it and now I receive the signal on the other side but there are small (although very rare) that the packets do not reach the other end. One problem with bit bang is that it is hard to implement a long high pulse or a long low pulse because it has to co-ordinate with the timer. Secondly, I like the idea of keeping the carrier modulation separate from the CPU but because of space constraints I cannot implement that \$\endgroup\$ Aug 10, 2014 at 20:48
  • \$\begingroup\$ @David Norman - I don't understand "I like the idea of keeping the carrier modulation separate from the CPU but because of space constraints I cannot implement that" I use one of the timers inside the MCU (I have edited my answer because I wasn't clear), so it takes no more board space; all the electronics are inside the existing MCU if there is a timer free. This should reduce the number of clashes between modulating the signal and other events. \$\endgroup\$
    – gbulmer
    Aug 10, 2014 at 21:39
  • \$\begingroup\$ Oh k, I think I misunderstand. I thought you suggested using external components like a timer IC \$\endgroup\$ Aug 10, 2014 at 23:03
  • \$\begingroup\$ @DavidNorman - I apologise for that, my answer was ambiguous. I've hope I've fixed it now. An internal timer generating the carrier modulation saves quite a lot of work, and makes modulating the 0 or 1 a bit easier. Even better if you have two internal timers available. \$\endgroup\$
    – gbulmer
    Aug 10, 2014 at 23:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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