I want to drive several units (boxes) filled with LPD6803 LED Modules (8-14 Led modules per box). Each unit is connected with a 70cm, unshielded and non twisted cable. I used those modules in the past without problems in my PixelInvaders project, however there are no long cables involved.
My new project looks like this:
1 | [UNIT#1]---[UNIT#2]---[UNIT#3]---[UNIT#4]---[UNIT#5]---[UNIT#6]---[UNIT#7]---[UNIT#8] |
Total cable length: 50cm internal cable per unit (4m), the connecting cable measures 2m and 7 connecting cables à 70cm makes a total of approximately 11m.
In the beginning I was using the bit banging LPD6803 firmware. That worked quite ok, but the update times were not very fast and there were some visible glitches (white flashing aka. ringing). Fading all Leds from black to white was not working at all, very much noise (random color) was visible!
So I start using the new SPI LPD6803 firmware which should update the LED Modules much faster (only MOSI and SCLK pins are used). The first unit is working very fast and clean, however between unit#2 and unit#7 I just see flicker… looks like the cables or connectors make some trouble here.
According to the LPD6803 datasheet the chip provides “Adopt self-add token-ring technology dual shift line, shift clock can reach 24MHz” and “Data clock signal is drived strongly to next chip to enhance level after built-in phaselock circuit“.
I use a LPD6803 based Led Module which looks like this:

I assume the 3 components on the left (1 kOhm resistor, NPN transistor and capacitor (30pF?)) is used as voltage regulation, the 3 resistors on the bottom (150 Ohm, 180 Ohm and 330 Ohm) are used to control the Led diodes (different values due different eye sensitivity for different colors?) and the two 51 Ohm resistor on the right are SPI (SCK and MOSI lines) “terminators” to prevent signal echo (Fail Safe Termination?).
This assumption would match the scheme from the lpd6803 datasheet:
Now let’s take a look at the SPI “Standard”.
The serial peripheral interface (SPI) bus is an unbalanced or single-ended serial interface designed for short-distance communication between integrated circuits.
…aha, guess 70cm of unshielded cable does not really match “short-distance communication between integrated circuits”. Anyway I searched some common issues with SPI communication:
- Noise on the DC level
- Impedance of the SPI lines.
- Reflexion of the SPI signal due missing or wrong termination resistor, the RS-422 standard suggests a 100 Ohm resistor.
- Use twisted-pair cable, because the conductors of twisted-pair cable are closely electrically coupled, external noise induced equally into both conductors appears as common-mode noise at the receiver input. You can use each SPI line sent in a twisted pair (SCLK/GND, MOSI/GND)
- Cable length is too long compared to the SPI frequency
Back to my modules, compare the common issues with my situation:
Noise on the DC level:
A possible issue, the capacitor on the LED module is just used to prevent a AC less voltage on the LPD6803 IC. According to the scheme, the 12V is applied directly to the LED diodes.
Impedance of the SPI lines:
I do have some issues here. I first added a 50Ohm and 220Ohm resistor between SCLK and ground, the result was bad (no more animation), I guess the resistor was too low, thus the CLK signal vanished. Then I added a 1 kOhm resistor, the animation was working fine! So I started to add a 1 kOhm resistor on the other units. The Leds were working, however the more units I connected the more flicker was visible…
Reflexion of the SPI signal/Missing terminator:
As the output of the Led module contains two 51Ohm resistors I guess this issue can be ignored.
Use twisted-pair cable:
I want to avoid this point, as I already soldered the cables and connectors.
Cable length:
Assuming a typical signal velocity of 5ns/m, a 11m cable will cause a propagation delay of 55ns. The full wavelength of a 1Mhz singal is 300m, for 8Mhz it’s 37.5m and for 16Mhz it’s 18.75m. So if I choose an SPI frequency of 1 or 2Mhz the wavelength can be ignored.
Conclusion:
The problem still exists and I need more experimenting until this issue gets resolved. I test the installation with different SPI speed settings and need to test further.
Concrete next steps would be:
- Experiment with different “impedance” resistors.
- add capacitor on each unit to clean DC (what capacity should be used? Elkos? Ceramic ones?)
- Add termination resistor?
I asked some clever people on Reddit and on Dangerous Prototypes, here are some promising answers:
- flinxsl/reddit: At only 1MHz you can get away with a lot of approximation. It is a push-pull interface unlike I2C, so no termination pull up/pull down resistors are required.
As others have mentioned, you should try looking at the signals with a scope, but be warned a probe can cause ringing that wouldn’t be there otherwise. - Brian/dangerousprototypes: I know you say you want to avoid it but a good transmission line is needed for a long distance at a high speed.
Even your single wires are transmission lines they are just to a ground very far away. They are very inductive this way and that means very very slow.
The wavelength is shorter than you state, as your wavelength is assuming a impedance of free space and not of the transmission line you have. 100 Ohm is typical for twisted pair. 75 or 50 for coax. This means longer wavelengths as frequency does not change but the velocity is less.
Terminating a poorly defined non-transmission line with any impedance is does make a lot of sense to me. (If they aren’t twisted as the loop size changes the impedance will change).
Even without adding ground returns some progress can be made by twisting the 4 wires you have. I would twist the CLK line around GND and the data line around Vdd. Both GND and VDD are DC so from a transmission line viewpoint they are ground. If you have enough capacitance at each end it might be okay.
For reference, if you want long transmission the best thing would be differential buffers on each end, failing that single ended with ground returns for each line. Like a ribbon (IDE) cable or a CAT5 cable. - Bertho/dangerousprototypes: …The capacity is normally what limits the clock frequency. Rule of thumb says you have 100nF per km of cable (may be worse or better; see cable docs). It takes a lot of energy to drive capacitive loads. You also have signal degradation due to cable resistance. If you get to higher frequencies, you will encounter coaxial properties of the cabling and then you must ensure that the driving impedance matches the loading impedance and the terminating impedance (all must be equal)…
The capacitance you need to add at the local tap’s power depends on the load current variations and the cable resistance. The impedance of the power supply lines increases as you add more cable and that means you need to decrease the impedance locally with a polarized capacitor (order of 10..1000uF). The ESR of the capacitor should be low. How low depends on the load current changes. A second capacitor is a ceramic of ~100nF to short the high frequencies.You may also want to add a ferrite bead at each tap’s power outtake. The effect of the inductance is that the rush-currents are damped and will not feed back as much. It also reduces the capacitance requirements at the local taps
- jwhat/reddit: So first piece of advice: if you have access to an oscilloscope, take a look at the data lines. Are they ringing? Are the signal levels too low?
Appendix:
The Arduino supports different SPI Speed:
1 2 3 4 5 6 7 8 | Mode SPI Clock (Arduino Clock runns per default on 16Mhz): SPI_CLOCK_DIV2 8 MHz SPI_CLOCK_DIV4 4 MHz SPI_CLOCK_DIV8 2 MHz SPI_CLOCK_DIV16 1 MHz SPI_CLOCK_DIV32 500 kHz SPI_CLOCK_DIV64 250 kHz SPI_CLOCK_DIV128 125 kHz |
A quote from the LPD6803 Datasheet:
“Terminal is designed to push-pull strong drive circuit, after testing, it can drive 6meters length signal line when clock is 2M, to prevent signal echo, normally, pls serial a 50Ω resistance at DOUT and DCLKO, then output to next step.”. As you can see on the image, those resistors exists
Various other quotes:
With long lines and steep slopes, one has to use impedance matching at the ends of the lines. Without properly terminated lines there can be ringing, which is particulatly bad on the clk line. Once using terminated lines and resonable drivers there is not much need for repeaters in between, unless you really go over 100s of meters. [src]
Add series or parallel termination ONLY to SPI clock signal to ensure clean edges. SPI clock edges must be clean, but SPI data does not have to be clean. Reduce SPI clock frequency to allow SPI data signals to settle, meet setup time to SPI clock edges. Use a 33-ohm series term resistor only on SPI clock (SCLK) signal to ensure clean signal edges, and possibly reduce SPI clock frequency (if necessary) so that SPI data (in either direction) meet data -> clock setup timing. [src]
Used references:
- http://www.nerdkits.com/videos/multipanel_spi_ledarray/
- http://wiki.electronics-irc.net/Long_Distance_SPI
- http://www.ti.com/lit/an/slyt441/slyt441.pdf (Extending the SPI bus for long-distance communication)
- http://www.ti.com/lit/an/slla142/slla142.pdf
(Extending SPI and McBSP With DIfferential Interface Products) - http://www.csgnetwork.com/freqwavelengthcalc.html
- http://www.ledstyles.de/ftopic18880.html
- Serial Protocols Compared
Signal Transmission
Two common modes of transmission:
- symmetrical / Differential signaling (RS422, USB, Ethernet…) harder to implement, more wires (2n) but resistance to electromagnetic interference.
- asymmetrical / single-ended signaling / unbalanced (RS232, I2C, SPI…), easy to implement, only n+1 wires but susceptible to interference.
Cable Types
Twisted pair cables canceling out electromagnetic interference (EMI) from external sources. You can couple a AC with a DC signal (asymmetrical use case, for example V+ with Data and GND with Clock) or a AC with an AC signal (symmetrical use case, for example Data+ and Data-).
*** Edit 20.3.2012 ***
I created some reference shot with my DSO Quad, I used a Arduino UNO as board and my SPI firmware.
SPI 1MHz, Arduino SPI Output, Clock only:

SPI 1MHz, Arduino SPI Output, Clock and Data (Strip.update):

SPI 1MHz, End of a 20 LED module strand, Clock only:

SPI 1MHz, End of a 20 LED module strand, Clock and Data (Strip.update):

The signal at the end of 20 LED Modules does not look very clean, however the signal is NOT terminated.
Here is the simple code I used to measure:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <TimerOne.h> #include <SPI.h> #include "Neophob_LPD6803.h" #define LED_MODULES 200 Neophob_LPD6803 strip = Neophob_LPD6803(LED_MODULES); void setup() { strip.setCPUmax(60); strip.begin(); for (int i=0; i < strip.numPixels(); i++) { strip.setPixelColor(i, 0x7fff03); //White } strip.show(); } void loop() { //strip.show(); //enable this line to send data } |
Description of the LPD6803 timing sequence:





[...] a previous blog post I wrote about my issues with a LPD6803 based installation and long cables. After some [...]
[...] cable (11 meter) and the SPI signal. You can read more about this on a previous Blog post here and [...]