I need to send a string of bits to a chained set of RGB LEDs, each of which have their own controller IC. The datasheet for that IC, the WS2811, is here.
The protocol is quite simple: each bit, both 1 and 0, are sent as a high and a low, with different mark-space ratios, and are then strung together.
At 400kbps, the mark-space is as follows:
- Binary 1: 1.2us high followed by 1.3us low (each +/- 150ns)
- Binary 0: 0.5us high followed by 2.0us low (each +/- 150ns)
The data can either be sent at 400kbps or 800kbps. I'm not bothered which one I use, but I expect 400kbps will be easier to implement. (At 800kbps, the above times are halved.)
My question: How could this best be implemented? I'll probably be using a 20MHz (5MIPs) 8-bit PIC MCU to determine what data is to be sent, and I'm looking for the equivalent of a USART IC that the MCU could rely on to transmit data with the above encoding.
There are three ways I envisage sending that kind of data at that speed:
- Finding an IC / ASIC which is dedicated to this purpose.
- Using a second MCU dedicated to receiving data from the primary MCU, and converting it directly to the above PWM encoding.
- Building a dedicated transmitter out of TTL/CMOS logic ICs or similar.
For point 1, I can't find any IC that will do it. Do they exist?
For point 2, I have ideas for how it might work, but no solutions so far. One solution: Bit-banging would be very hard, having to be written in assembler given timing requirements. Another solution, although not capable of achieving the 100ns resolution for timing of the PWM signal to match the specs in the datasheet, could configure the USART on a PIC MCU to transmit synchronously - except each 4 bits transmitted would just be a hacky way of sending one PWM bit. So to send 400kbps PWM data, the USART would have to be capable of 400 x 4 = 1.6Mbps. Then, to send a PWM binary 1, the USART would send HHLL, and to send a PWM binary 0, the USART would send HLLL. This would only barely satisfy the +/-150ns timing requirements, a margin of 25ns. And I haven't found a PIC that can transmit that fast serially anyway.
So at the moment, option 3 is my only option: build dedicated hardware out of logic ICs. For example:
- Construct a 25-bit shift register to output the PWM, required for a single bit. Then circuitry which fills the register accordingly depending on whether a binary 1 or 0 is to be transmitted. And since this would still be very intensive on the MCU, I would add perhaps an 8-bit latch which the MCU could write to, and allow further circuitry to process the 8 bits one at a time, for each one encoding the bit into the 25 bit shift register as a PWM cycle.
- As above, but replace the 25 bit shift register with a monostable that outputs either a long or a short pulse, and another which loads a new bit every 2.5us.
- Using a memory IC which acts as a lookup table, so perhaps (with extra circuitry) could be given a byte to transmit from the MCU and return data that a circuit could translate into serial data as the PWM output.
In short, I can't find a good solution! It seems like an awful lot of work for such a simple problem. How would you do it?