I am looking for an easy way to implement a line code (both the encode and decode parts). This could be something like Biphase Mark Code, Differential Manchester, or anything else that has the following properties:

  • Considerable jitter is ok (edge timings can be off by ~20% of the time of a bit)
  • No separate clock or clock synchronization needed (this can't use SPI or UART, there is only one line which can only transmit two levels)
  • Approximately balanced 1's and 0's (not worse than 2:1 imbalance) and no long runs of the same symbol (not more than 3-5 consecutive 1's or 0's)
  • Fast! Need 1Mbit/s or more. (I have 80MIPS microcontrollers on either side, but software decoding is probably still impractical)
  • Cheap! Ideally something that can be done with microcontroller peripherals, or an inexpensive encoder/decoder IC.
  • \$\begingroup\$ Sounds like USB, except for the line count. \$\endgroup\$ – Ignacio Vazquez-Abrams Dec 25 '15 at 0:43
  • \$\begingroup\$ @IgnacioVazquez-Abrams: A bit like USB, yes. Also maybe a bit like 10Mbit ethernet PHY, and a lot like IRDA. \$\endgroup\$ – Alex I Dec 25 '15 at 2:44
  • \$\begingroup\$ Over what distance, between the encode and decode, must this work? Is there a common ground? Why only one signal? Is that a limitation of the MCU or the 'wiring'? \$\endgroup\$ – gbulmer Dec 25 '15 at 13:55
  • \$\begingroup\$ What's the line bandwith? Is that jitter between one bit and the next or will it vary more slowly, or is it a constant deviation from the "ideal" clock rate? \$\endgroup\$ – JimmyB Dec 25 '15 at 19:32
  • \$\begingroup\$ Where does the jitter come from anyway? You're transmitting along a line, and you're providing sender and receiver? \$\endgroup\$ – JimmyB Dec 25 '15 at 19:40

The bad news is: Some problems are simply unfixable in software; you must either relax your constraints or else add new hardware.

Many optical coupling systems have turn-on delays not exactly equal to turn-off-delays, as you already noticed: "..00100.. the 1 appears longer ... ..11011.. the 0 appears shorter.". In this system, the 1-to-0 delay is longer than the 0-to-1 delay. If you are lucky, those delays are consistent enough to be compensated for. A pulse stretcher can be as simple as a diode, a capacitor, and a couple of resistors.

Many line codes seem to meet your criteria, including 4B5B coding, 8b/10b encoding (or either one of the 3b/4b or 5b/6b codes typically used in it), 6b/8b encoding, Manchester coding and its variants such as Differential Manchester encoding, Three of Six, Fiber Optical, Pulse-position modulation, etc.

software compensation

I'm guessing you already have some free-space optical communication hardware set up that is a little quirky, and you're trying to compensate for hardware quirks entirely in software.

One quick-and-dirty scheme is:

  • Send a preamble just before sending each packet of data, typicaly a "balanced" pattern, perhaps 'U' characters (binary 0101_0101), to help the bit-slicer in the receive hardware find the appropriate setpoint to distinguish between 0 and 1.
  • Send bytes (perhaps using the UART or the SPI peripheral in the sender) from a short list that are "easily discriminated" at the receiver. I've seen some systems that send only two unique bytes out a UART configured as 8N1 -- 0x00 (i.e., 9 zero bits followed by 1 one bit) and 0xFF (i.e., 1 zero bit followed by 9 one bits). (They have only 2 bytes in that list). If you are lucky, you can use a larger list.
  • The receiver, for each byte received (perhaps using the UART peripheral), use a lookup table to decode it into the appropriate bits. With the above example, the receiver decodes "short" pulses of zeros as a 1 bit, and "long" pulses of zeros as a 0 bit.

Many line codes can be adequately approximated by dividing bytes up into a sequence of hexadecimal digits (nybbles), quaternary digits, or individual binary digits (bits), and then designing a lookup table that transforms that digit into 8 or 10 or 16 or so bits (chips) that, when sent out the UART or the SPI peripheral, adequately approximates that line code.

Perhaps your system can reliably distinguish between 16 different transmitted bytes, so each transmitted byte transmitted can be decoded into 4 data bits -- your transmitter uses one of 16 bytes in its short list. When you send a byte with an isolated 1 bit, and the hardware stretches it enough that the receiver sometimes sees a pattern with a single 1 bit and other times sees a pattern with two 1 bits, both of those patterns must be decoded into the same 4 data bits. (Also, the receiver must somehow throw away any between-packet noise, throw away the 'U' preamble bits, etc.).


Sometimes you can insert a pulse stretcher somewhere in the transmitter hardware, and tune the resistors in the transmitter such that, at the critical point in the receiver, the 1-to-0 delay is practically the same as the 0-to-1 delay.


Sometimes you can insert a pulse stretcher somewhere in the receiver hardware, and tune the resistors in the receiver such that, at the critical point in the receiver, the 1-to-0 delay is practically the same as the 0-to-1 delay.

Existing implementations

There are several existing implementations of free-space optical communication that run at 1 megabit/second or faster.

  • Infrared Data Association (IrDA); if you are lucky your microcontroller already has some hardware support for IrDA)
    • MIR at 1 Mbit/s (?)
    • FIR at 4 megabit/second (Searching http://Digikey.com/ for "irda fir", without quotes, turns up a bunch of transciever modules. Perhaps "Can IrDA FIR module (A) be directly connected to the SPI or UART pins of microcontroller (B)?" would make a good independent question?)(Would any of the circuit diagrams in the LT1328 datasheet work for you?).
    • VFIR at 16 Mbit/s
  • RONJA (10 megabit/s full duplex)
  • Li-Fi ("1.6 Gbit/s" ?)

Would one of those work for you?

  • 1
    \$\begingroup\$ Thank you, a stellar answer! You're right, I have optical hardware which works but is a little quirky. I don't think pulse stretcher would work because the jitter is not that consistent (but I'll certainly try that). An IrDA encoder-decoder (endec) would probably work well, but I haven't been able to find any FIR/VFIR endec ICs. \$\endgroup\$ – Alex I Dec 29 '15 at 2:17

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.