|
Edited by DoubleHP at 2018-1-25 20:47
After days of hard work ...
I won't quote all my ressources; only how I fixed my issues.
NB: WS2811, WS2812, WS2812B are all WS281* chips, with various packaging. They are all driven the same way.
Last month, I easily got WS2812 (1 strip LED version) working with an Orange Pi PC, running Armbian_5.35_Orangepipcplus_Ubuntu_xenial_default_3.4.113 .
Since a few days, I am trying to port it to Orange Pi Zero (H2+), Armbian_5.35_Orangepizero_Ubuntu_xenial_next_4.13.16 .
Many people were saying it was possible; I could not. The very first thing to check is how many SPI devices you have, in hardware, and if they are enabled. armbian-config did not help. Don't ask me why, but the old kernel 3 provides SPIdev immediately after first boot, while kernel 4 does not ... with the same Armbian 5.35. After upgrading my opi PC to kernel 4, I also lost my spidev.
You may want to try to load kernel modules if you have them, but they did not help in my case (one of them may work; the other WILL fail):
- modprobe spi_sun7i
- modprobe spidev
Copy code
https://forum.armbian.com/topic/3772-how-to-enable-hardware-spi/
mentions this change should be done in /boot/armbianEnv.txt :
- overlay_prefix=sun8i-h3
- overlays=spi-spidev
- param_spidev_spi_bus=0
- param_spidev_max_freq=100000000
Copy code This may work on most Orange Pi; it does not for "legacy" "Orange Pi zero", because of the Flash SPI. The above section will help a bit:
- ls /dev/spi*
- # /dev/spidev0.0
Copy code but this is not what we want. After checking with various scripts and osciloscope, this node points to the FLASH. I have seen MOSI produce signals on the FLASH. So I tried this:
- overlay_prefix=sun8i-h3
- overlays=spi-spidev
- param_spidev_spi_bus=1
- param_spidev_max_freq=100000000
Copy code And I got something better:
- ls /dev/spi*
- # /dev/spidev1.0
Copy code But when running my LED script, the API complained about IOError: [Errno 2] No such file or directory. Does not matter, in my case, because I don't need the FLASH; so, let's hack /dev:
- cd /dev
- ln -s spidev1.0 spidev0.0
Copy code And now, my old script works. Of course, this is a dirty hack; it would be better to find the open() call, and fix it properly:
- # spi.open(0,0)
- spi.open(1,0)
Copy code
Now, install python-dev and git:
- aptitude install python-dev git
Copy code You may need some other deps. Now, install https://github.com/doceme/py-spidev.git and https://github.com/joosteto/ws2812-spi.git :
- # git clone https://github.com/doceme/py-spidev.git
- # cd py-spidev
- # make
- # make install
- # cd ..
- # git clone https://github.com/joosteto/ws2812-spi.git
- # cd ws2812-spi/
Copy code That project hardly works as is; according to https://github.com/joosteto/ws2812-spi/issues/2 you must edit ws2812.py , lines 55 and 63 (for me, now, with the actual version).
You can optionally install python-numpy; in my case, I do not like it because I generate my LED paterns from a bash script, and loading this lib takes 0.5s, while using the raw method without this script makes ws2812.py run in less than 120ms; but if you plan on doing your whole project in python, you will want to keep this lib: comment lines selecting this lib:
- #if NumpyImported:
- # write2812=write2812_numpy4
- #else:
- # write2812=write2812_pylist4
- write2812=write2812_pylist4
Copy code There are few interesting things to do with this script; but, here are some:
- # switch off 5 LEDs:
- ./ws2812-spi/ws2812.py -c "[[1,1,1]]" -n 5
- # switch on 3 LEDs:
- ./ws2812-spi/ws2812.py -c "[[99,99,99]]" -n 3
- # do some blink:
- # switch off 5 LEDs:
- while true ; do for i in "[[0,0,0]]" "[[254,254,254]]" "[[254,0,0]]" "[[0,254,0]]" "[[0,0,254]]" ; do ./ws2812-spi/ws2812.py -c "$i" -n 16 ; done ; done
Copy code
and this should be enough for today.
On the hardware side: many people mentino that WS2811 (WS281*) familly are designed to receive input signal between 0.3*Vdd and 0.7*Vdd; so most LEDs won't accept 3.3V provided by pis. In short, if you see any "bidirectionnal voltage converter" ( http://husstechlabs.com/support/ ... onal-level-shifter/ , https://www.adafruit.com/product/757 ), you can forget it: these I2C things can not stand the high frequencies required for WS2811.
Some LEDs accept 3.3V directly, but not all. Even for LEDs that accept 3.3V, you may want to build a signal adapter to boost your signal, and protect your pi from glitches. Due to some shacking hand, I have send 12V in my MOSI and burnt a brand new rPiv2 stupidely.
http://www.electrobob.com/ws2812-level-translator/
proposes several simple solutions:
- reduce input voltage of first LED with a diode, and let the diode reshape the signal for the next one (see WS2811 PDF specification: each LED reshapes the signal before sending it to the next one; meaning, they will progressively amplify the signal correctly) (first image of link above)
- introduce a shift between Vss of the Pi and first LED with a diode http://tinyurl.com/y7b2svea
- connect the pi MOSI to the LED with a diode and a pullup resistor to 5V http://tinyurl.com/ybordkjl
Here is the circuit I recommend: http://tinyurl.com/yazxvvfu / http://goo.gl/4Eu13k
you can tune all components:
- the input resistor should be between 33 and 100R (33 is the min recommended value to avoid burning the port; above 100R the gate will not rise fast enough)
- the output 33R is recommended by manufacturer of WS2811
- pullup 1K can be reduced down to 600R (be carefull of current flowing through the transistor). Too low, it can burn the transistor; too high, it won't pull the signal up.
- I am using two BS170
- capacitors should not be soldered; they are here only to simulate the capacity of the grid of BS170, and they help tuning the source pullup during simulation
- the source pullup is the most difficult component to adjust. Value should be between 100R and 1KR, but it must be precisely adjusted depending on your transistors (see specs of your transistor). For BS170, I have used 560R.
- The frequency of signal for the WS2811 is either 400 or 800kbps (depending on your choice, and the API), but the precision of signal is critical: the bandwidth required for the voltage converter is 5MHz. The LEDs use PWM; the source pullup has an impact on falling and rise time ... and it can kill the signal if not adjusted correctly. I have not been able to tune the circuit for 5MHz; but it seem to work fine below 3MHz ... and with this tuning, my circuit works fine (LEDs accept the signal and work fine). A low value may kill the transistor, or pevent the second gate from reaching Vss; a high value increases the rise time of the second gate (and breaks the balance between fall and rise time ... what kills the PWM).
A simpler method I was given on IRC (freenode, #electronics): http://tinyurl.com/ycanxy2n / http://goo.gl/NTa4PG
It's simple, but can not be modified for 12V data (note that most 12V stripes expect and use 5V data), and it lacks protection: if the output touches 12V or higher voltage, I fear that some current may flow via the transistor and burn the pin of Pi.
A more complex method; this shows that a BJT reacts in current, immediately, with an infinitely fast response, while MOS have a delay due to the time required to fill the capacity of grid.
http://tinyurl.com/y99zxrw8 / http://goo.gl/M146hJ
References:
Increasing reliability of the WS2811 on pis:
https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=200793
https://youtu.be/OLTufsrQZc0ls
https://wp.josh.com/2014/05/13/w ... u-get-to-know-them/
https://tutorials-raspberrypi.co ... 812-rgb-led-strips/
https://www.fabriqueurs.com/rasp ... ative-de-pollution/
|
|