A simple IrDA SIR to USB-CDC adapter using a BluePill and an IrDA transceiver module.
The source (zip, tarball, etc.):
Download
The build (Intel HEX for flashing):
Current
TL;DR
Get a BluePill, an IrDA module, and a couple of passives. Easy wiring. Flash and go. The parts are so cheap you might as well just make two.
Overview
IrDA was popular wireless technology in the 1990's and early 2000's, but lost its market foothold to Bluetooth and WiFi. As such, manufacturers are not producing new products and one is relegated to the used market, e.g. eBay, etc. This is OK in principle, but they can be expensive. What's worse is that they do not have driver support for modern OS's.
This project attempts to help with that by realizing a USB-CDC (i.e. 'virtual serial port') to IrDA adapter using cheap parts and out-of-box drivers. This is called 'serial infra-red', or 'SIR'.
Scope
IrDA is a collection of protocol specifications designed in the layered networking tradition especially popular in the 1980's. As such, most of of the 'stack' is software, with the bottom layer(s) abstracting away the hardware specifics. In particular the first layer -- the physical layer.
IrDA has several physical layer options, but one of the most basic is 'serial infrared', or 'SIR'. This is scarcely more than half-duplex UART with no hardware flow control. It has a maximum bit rate of 115,200 bps. There are other with higher bit rates, such as 'fast infrared' ('FIR') but they use different modulation techniques and cannot be supported by the BluePill.
Above the physical layer are other protocols, such as IrLAP (similar to the 'link layer' in the OSI model). It handles things like discovery, access control, and bidirectional communications. This is the subject of a separate project and out of the scope of this one.
Details
Signalling
The venerable async protocol idles in the marking state, and indicates start of transmission with a one-bit-period spacing symbol. This is for historic reasons, but in more modern times of 'ttl serial', this electrically mean that the idle state is indicated by a logic 'high'.
IrDA is intended for low-power -- often battery -- operation, so logic 'high' is indicated by the absense of infrared signal. Logic 'low' is indicated by the presence. So a '0' is indicated by the detection of infrared, and and a '1' is indicated by the absence of infrared.
To save power further, the signal is not presented for the entire bit period, but rather as a pulse for 3/16 of the bit period.
The signal is not modulated on a carrier (e.g. as is with TV remote schemes), but is baseband. Aside from the 3/16 bit period aspect, it is scarcely more complicated that wiring an LED directly to the UART output as open-drain. It can easily bit bit-banged if you must. However uarts on microcontrollers often have an 'IrDA mode' which handles the pulsing aspect for you, on both the send and receive side. Additionally, infrared has huge crosstalk between the send and receive, and the uart will usually suppress reception whilst transmitting for you. So why not avail oneself to that feature?
Processor
The BluePill uses an STM32F103 microcontroller. It can still be had for about USD $3. The BluePill is scarcely more than a 'breakout board' for the microcontroller, with crystals, voltage regulator, and USB jack added.
Optoelectronics
Manufacturers of optoelectronics, such as Vishay, Lite-On, Sharp, etc., offer IrDA transceiver modules which integrate an emitter and detector along with support circuitry. These modules are not especially cheap (around $5 in unit quantities), possibly because the market no longer provides economies of scale. One can also find these modules on the surplus market as new-old-stock ('NOS') for about half the cost. You can build the equivalent circuit out of discrete parts if needed, though to me this seems more trouble than it's worth unless in a pinch. E.g.:
As opposed to using a module:
Simpler! Also, the modules typically have more sophisticated amplifiers than the one depicted in the 'discrete' circuit, above, with things like AGC and filtering.
For the most part the modules from different vendors work the same way:
- power and ground that you bypass externally
- an LED using an external series-dropping resistor you provide
- signals for transmit (TX) and receive (RX)
- a 'shutdown' control line to put the device in low power mode
The bypass capacitors are typically a 22 uF in parallel with a 0.1 uF, and the series dropping resistor is chosen based on supply voltage and current drain concerns. I usually select 10 ohms for a 3.3 V system (as is the case for the BluePill).
The shutdown is not needed in this application since it's not running off of battery, so it can be wired 'low' to ground. Then TX and RX are connected to the uart on the microcontroller. The naming convention is such that you connect the TX of the transceiver to the TX of the microcontroller, and the RX to the RX. (I.e., not cross-connected as you might when connecting to a device or an adapter.)
The trickiest thing is that these modules is that they are usually small surface mount devices. Not a surprise as they were intended for compact portable equipment, but less friendly to the casual maker. E.g.:
Constructing
Obtain a BluePill through any of they various vendors (e.g. AliExpress or eBay).
You can get still in-production IrDA transceivers, such as the Vishay TFBS4711, from vendors in unit quantities (e.g. Mouser, DigiKey, Newark), and if you shop around you can find out-of-production models from surplus vendors. I used a surplus module Sharp GP2W0004YP that I got for USD $2 each. These parts are a bit fragile so I try to always get two in case I break one. (Also, you probably will want to make two adapters, anyway.)
You'll need a few passives:
- 22 uF
- 0.1 uF
- 10 ohm
The values aren't that critical. The resistor current-limits the LED, so it should stay a small value.
Wire it up. Your choice. I used the point-to-point 'wire sculpture' technique (with no regards to aesthetics). You can then bring out four wires for power, ground, tx, rx, from the assembly. I found it easiest to work with a head magnifier. Put some flux on the part and create a small solder blob on each pad. Note that these devices are fragile and you don't want to spend too much time on a pad. If you're not happy with how it looks, let it cool down before attempting a touch-up. Once completed I brought out 4 wires with 24 AWG stranded. I then used some UV curable resin ("Bondic") to create some stress relief for the assembly. I terminated the wires by crimping Dupont connectors.
Now the easy part. Connect the adapter assembly to the BluePill:
- PB11 -- RX (of both adapter and BluePill)
- PB10 -- TX (of both adapter and BluePill)
- 3.3 V -- power to the module
- Gnd -- ground to the module
And that's it for the hardware part.
Flashing Firmware
If you have an ST-Link v2 (they're very cheap, like USD $2), you can program over the SWD connector at the end of the board. I use this technique because I develop the software so of course I have a programming adapter. But if you absolutely don't want to spend the $2 on the adapter, it is possible to use the on-chip programming firmware. It is a bit fiddly, and you're probably going to need another adapter, anyway, since it only works over serial -- not USB.
To do it without the ST-Link and using the on-chip DFU, you'll need to connect your serial port to the board's UART1 on PA9 and PA10 and put the BOOT0 jumper in the 'high' position when you power up. Then the chip will come up in programming (DFU) mode. You'll need some software that can understand how to do it. This is free; you can get it from STM "STM32CubeProg" via:
STM32CubeProg
Remember to restore the BOOT0 jumper when finished so that it runs the software instead of the firmware updater.
Using
Use is straightforward: plug it into your computer. The device will enumerate as a USB Communication Class Device ('USB CDC') and appear as a serial port. You can connect to this serial port with your application to send and receive data over the IR as with a regular wired serial port with some caveats:
- the communication is half-duplex -- you cannot send and receive at the same time. This is simply a consequence of the nature the IR communications. Often the uart or even the transceiver module will actively suppress reception when transmitting. The BluePill does this, for instance, so you don't need to worry about it.
- there is no hardware flow control. You have to implement that yourself (maybe xon/xoff, or simply judicious pacing of the transmissions).
- be prepared for junk data -- a lot. E.g. TV remote controls will generate plenty of junk data.
The USB CDC device does respond to 'set line coding' packets, so you can change the bit rate at any time. IrDA SIR supports 2,400 up to 115,200. You serial program doesn't need to do anything special -- the host OS's USB CDC driver will send the correct packets when the program configures the port like it would any other.
The range of IrDA is designed for about 1 m, so do not expect to control things across the room as you might with a media device remote control. Media device remote controls use a different scheme.
Once you have this working, you can use this for generic serial transfers, or you can layer other protocols on top of it. This second option is the subject of a separate project.