We've launched our new site at www.openlighting.org. This wiki will remain and be updated with more technical information.
Difference between revisions of "OLA LED Pixels"
From wiki.openlighting.org
(46 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{PageMigrated|url=https://www.openlighting.org/ola/tutorials/ola-led-pixels/}} | ||
[[Image:Lpd8806.jpeg|300px|right]] | [[Image:Lpd8806.jpeg|300px|right]] | ||
− | Since March 2013, [[OLA]] contains an SPI plugin, which allows you to drive strings of LEDs pixels provided your | + | Since March 2013, [[OLA]] contains an [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI] plugin, which allows you to drive strings of LEDs pixels provided your platform has an SPI interface. Using embedded Linux platforms like the [[OLA_Raspberry_Pi | Raspberry Pi]], this allows one to build Pixel strings controllable via any of the [[OLA#Supported_Protocols|supported protocols]] ([[ArtNet]], [[E1.31]], [[OSC]] & more) for less than $100. |
− | Alternatively if you don't want network control, you can send [[DMX512]] to the LEDs using the Python, C++ or Java client library. | + | Alternatively if you don't want network control, you can send [[DMX512]] to the LEDs using the Python, C++ or Java client library running on the host itself. |
− | + | This page is focused on the Raspberry Pi, but may be applicable to other hardware such as the BeagleBone. If you're using a Raspberry Pi you can save yourself a lot of time by using the pre-built images, see [[OLA_Raspberry_Pi| OLA on the Raspberry Pi]] for details. | |
− | + | == Host Hardware == | |
− | + | The Raspberry Pi contains three SPI interfaces, but only one of these is wired to the 26-pin connector. The interface comes with 3 chip-enable (CE) lines but again only two are connected (pins 24 & 26). With the default mode, pin 24 is pulled low when the /dev/spi0.0 device is used and pin 26 is pulled low when /dev/spi0.1 is used. | |
− | |||
− | |||
− | + | The Pi uses 3.3V logic. You can usually get away with connecting the pins directly to the pixel hardware which uses 5V for testing, but for reliable operation it's best to use a driver circuit to convert the voltage levels from 3.3v to 5v especially if you have a cable run between the Pi and the Pixel string. There is a [https://github.com/hackerspaceshop/RaspberryPI_WS2801_Bridge schematic] available or you can buy a [http://www.hackerspaceshop.com/raspberrypi-ws2801.html kit]. | |
+ | Here are some timings stats collected from the Pi: | ||
+ | |||
+ | {| border=1 cellspacing="0" | ||
+ | ! SPI Speed !! Number of bytes || time taken for write() !! Time on the wire | ||
+ | |- | ||
+ | || 1MHz || 75 || 13.5ms || 11.1ms | ||
+ | |- | ||
+ | || 2MHz || 75 || 8.1ms || 5.6ms | ||
+ | |- | ||
+ | || 4MHz || 75 || 4.7 ms || 3.0 ms | ||
+ | |- | ||
+ | || 8MHz || 75 || 3.7ms || 1.4ms | ||
+ | |- | ||
+ | || 12MHz || 75 || 3.2ms || 0.75 ms | ||
+ | |- | ||
+ | || 1MHz || 516 || 78.5 ms || 76.15 ms | ||
+ | |- | ||
+ | || 2MHz || 516 || 40.2 ms || 38.2ms | ||
+ | |- | ||
+ | || 4MHz || 516 || 21.5 ms || 19.1 ms | ||
+ | |- | ||
+ | || 8MHz || 516 || 12.2ms || 9.6ms | ||
+ | |- | ||
+ | || 12MHz || 516 || 7.4ms || 4.83 ms | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | It also takes somewhere between 3.6 and 4.6 ms to toggle a GPIO pin using the /sys/class/gpio interface. The importance of these numbers will be clear in a minute. | ||
+ | |||
+ | |||
+ | Beyond the Pi, any SPI hardware supported by the Linux kernel should work modulo the timing restrictions. By default OLA looks for devices that match the /dev/spi* . | ||
+ | |||
+ | == Pixel Hardware == | ||
+ | |||
+ | On the pixel side the following is supported: | ||
+ | * LPD8806, e.g. https://www.adafruit.com/products/306. since 0.8.27 | ||
+ | * WS2801, e.g. https://www.adafruit.com/products/738, since 0.8.28 | ||
+ | |||
+ | Each of these uses 3 DMX slots per pixel, so you can drive up to 170 pixels from a universe of DMX data. | ||
== Hardware Setup == | == Hardware Setup == | ||
− | + | The simplest setup is to connect SCLK (pin 23) to the pixel string's clock line and MOSI (pin 19) to the pixel string's DATA line. You'll need a separate power supply for the pixel string, check the pixel specifications but 1A per m is a good rule of thumb. Don't forget to connect the ground on the power supply to a ground pin (e.g. 25) on the Pi.Do not connect the 5V rail of the pixel power supply to the Pi. | |
+ | |||
+ | === Multiplexer === | ||
+ | |||
+ | If you want to drive more than one string in parallel you'll need to use a de-multiplexer. For a two-line multiplexer one can use the CE0 and CE1 lines to select the output string. To run more than 2 strings you'll need to use some of the GPIO pins as chip-enables. However these pins are slow (~4ms) which limits the update rate. | ||
+ | |||
+ | There is a 8 way demultiplexer schematic [https://drive.google.com/file/d/0B7Z8oqKsoX5HWE1qV2hCeDNNOU0/view?usp=sharing&resourcekey=0-8yDZLnlQ-8FlPaSRPqrIgQ here]. | ||
+ | |||
+ | == OLA SPI Plugin == | ||
+ | |||
+ | The [[OLA]] SPI plugin is pretty flexible, the primary limitation is how long it takes to write the data out the SPI interface, and this limits the overall refresh rate. Each SPI interface (/dev/spi*) is represented as an OLA Device. Devices can have multiple 'ports' since each port can consume at most one universe of DMX512 data (170 RGB pixels). Each port can be configured (via RDM) with a start address and personality (pixel type). This allows a combination of various strings lengths & pixel hardware types. | ||
+ | |||
+ | Each SPI device uses a backend to write the SPI data. Right now there are two types backends available: a software backend which merges the SPI data from one or more ports, and a hardware backend which uses the GPIO pins to control a hardware demultiplexer. | ||
+ | |||
+ | === Timing === | ||
+ | |||
+ | It all comes down to timing. Consider the following example: | ||
+ | |||
+ | * 170 LPD8806 pixels per string (results in 516 bytes written) | ||
+ | * Two strings using the built in CE lines to drive a hardware demultipliexer. | ||
+ | * SPI speed of 2Mhz | ||
+ | |||
+ | Using timing table above, we can see this will take 40.2 ms x 2 = 80ms to update all pixels. That means you'll only be able to do 12 updates per second. Most DMX systems run at 40 updates per second so we'll end up dropping updates. | ||
+ | |||
+ | If we tried to use GPIO pins rather than the CE ones it gets worse. Consider a second example: | ||
+ | |||
+ | * 32 WS2801 pixels per string (results in 75 bytes written) | ||
+ | * Four strings using two GPIO lines to drive a hardware demultipliexer. | ||
+ | * SPI speed of 2Mhz | ||
+ | |||
+ | Now each write requires setting GPIO pins. Worse case both pins will need to change which adds 8ms. The write itself takes 8.1 ms, so that's 16.1 ms per string or 64.4 ms to update all strings. That gives you an update rate of 15 updates per second. Still not close to DMX's 40 updates per second. | ||
== Software Setup == | == Software Setup == | ||
+ | You'll need a suitable [[OLA_Device_Specific_Configuration#SPI|udev config]], so that OLA has permission to talk to your SPI port. There is also some Raspberry Pi specific config (enabling a kernel module) on the same page. | ||
− | Once you have OLA running it's a matter of patching an SPI Output port to a universe and then patching the desired input port. | + | If you're using the GPIO pins to drive an hardware demultiplexer, you'll need to run the following as root prior to starting olad. |
+ | |||
+ | <pre> | ||
+ | for pin in 17 21; do | ||
+ | echo $pin > /sys/class/gpio/export; | ||
+ | chmod a+w /sys/class/gpio/gpio${pin}/value; | ||
+ | chmod a+w /sys/class/gpio/gpio${pin}/direction; | ||
+ | done | ||
+ | </pre> | ||
+ | |||
+ | Once you have OLA running it's a matter of patching an SPI Output port to a universe and then patching the desired input port. This can be done from the OLA web UI or by using ola_patch | ||
+ | . | ||
+ | [[Image:Ola-spi-artnet.png| thumb|center |200px|Example of an ArtNet controlled LED String]] | ||
== Configuration == | == Configuration == | ||
The type of LED drivers, operating mode and DMX Start Address are configurable via [[RDM]]. Click on the RDM tab and you'll see the options. | The type of LED drivers, operating mode and DMX Start Address are configurable via [[RDM]]. Click on the RDM tab and you'll see the options. | ||
+ | |||
+ | [[Image:Ola-spi-rdm.png| thumb|center |200px|Using RDM to set the hardware type and DMX start address]] | ||
+ | |||
The number of LEDs and SPI speed is set using the ola-spi.conf file. | The number of LEDs and SPI speed is set using the ola-spi.conf file. | ||
+ | |||
+ | <pre> | ||
+ | base_uid = 7a70:00000100 | ||
+ | device_prefix = spidev | ||
+ | enabled = true | ||
+ | spidev0.0-dmx-address = 1 | ||
+ | spidev0.0-personality = 1 | ||
+ | spidev0.0-pixel-count = 25 | ||
+ | spidev0.0-spi-speed = 100000 | ||
+ | spidev0.1-dmx-address = 1 | ||
+ | spidev0.1-personality = 2 | ||
+ | spidev0.1-pixel-count = 25 | ||
+ | spidev0.1-spi-speed = 1000000 | ||
+ | </pre> | ||
+ | |||
+ | == Example Configs == | ||
+ | |||
+ | === Single Pixel String === | ||
+ | |||
+ | For a simple single-string output we can use the software backend and ignore the CE lines. This config is for 25 WS2801 pixels running at 1Mhz on /dev/spi0.0. From the timing information above this should support about 75 updates / second. | ||
+ | |||
+ | <pre> | ||
+ | base_uid = 7a70:00000100 | ||
+ | device_prefix = spidev | ||
+ | enabled = true | ||
+ | spidev0.0-0-dmx-address = 1 | ||
+ | spidev0.0-0-pixel-count = 25 | ||
+ | spidev0.0-0-personality = 1 | ||
+ | spidev0.0-backend = software | ||
+ | spidev0.0-ports = 1 | ||
+ | spidev0.0-spi-speed = 1000000 | ||
+ | </pre> | ||
+ | |||
+ | === Two Pixel Strings, using the CE lines === | ||
+ | |||
+ | This example is for 25 WS2801 pixels and 32 LPD8806 pixels. Both strings run at 2Mhz and are connected to the spi bus, and we're using the CE chips to de-multiplex. We want to CE lines to be active-high. | ||
+ | |||
+ | <pre> | ||
+ | base_uid = 7a70:00000100 | ||
+ | device_prefix = spidev | ||
+ | enabled = true | ||
+ | spidev0.0-0-dmx-address = 1 | ||
+ | spidev0.0-0-personality = 1 | ||
+ | spidev0.0-0-pixel-count = 25 | ||
+ | spidev0.0-backend = software | ||
+ | spidev0.0-ports = 1 | ||
+ | spidev0.0-spi-ce-high = true | ||
+ | spidev0.0-spi-speed = 200000 | ||
+ | spidev0.1-0-dmx-address = 1 | ||
+ | spidev0.1-0-personality = 1 | ||
+ | spidev0.1-0-pixel-count = 25 | ||
+ | spidev0.1-backend = software | ||
+ | spidev0.1-ports = 1 | ||
+ | spidev0.1-spi-ce-high = true | ||
+ | spidev0.1-spi-speed = 2000000 | ||
+ | </pre> | ||
+ | |||
+ | === Two Pixel Strings, using a single output === | ||
+ | |||
+ | This example is a string of 300 WS2801 pixels. Since this is more than one universe of data, we need to use multiple ports. | ||
+ | |||
+ | <pre> | ||
+ | base_uid = 7a70:00000100 | ||
+ | device_prefix = spidev | ||
+ | enabled = true | ||
+ | spidev0.0-0-dmx-address = 1 | ||
+ | spidev0.0-0-personality = 1 | ||
+ | spidev0.0-0-pixel-count = 150 | ||
+ | spidev0.0-1-dmx-address = 1 | ||
+ | spidev0.0-1-personality = 1 | ||
+ | spidev0.0-1-pixel-count = 150 | ||
+ | spidev0.0-backend = software | ||
+ | spidev0.0-ports = 2 | ||
+ | spidev0.0-spi-speed = 1000000 | ||
+ | spidev0.0-sync-port = -2 | ||
+ | </pre> | ||
+ | |||
+ | SPI data is written when data arrives on the second port (sync-port = -2). See the plugin description for more info. | ||
+ | |||
+ | == Exported Variables == | ||
+ | |||
+ | The SPI plugin exports a number of useful variables. These can be found at http://<ip>:9090/debug. Each is indexed by the device name e.g. /dev/spi0.0 . | ||
+ | |||
+ | ;spi-writes | ||
+ | : Number of writes to each SPI device | ||
+ | ; spi-write-errors | ||
+ | : Number of writes that resulted in an error | ||
+ | ; spi-drops | ||
+ | : Number of DMX updates that were skipped. The happens if DMX data is arriving faster than it can be written to the SPI bus. | ||
+ | |||
+ | == Related Links == | ||
+ | |||
+ | http://www.solderlab.de/index.php/software/glediator (Pixel Control Software that outputs ArtNet) |
Latest revision as of 13:04, 25 December 2021
This page has migrated to our new site, please see https://www.openlighting.org/ola/tutorials/ola-led-pixels/.
This content will not be updated and is just left here for reference and will be removed at some point in the future, see the link above for the most up-to-date version.
Since March 2013, OLA contains an SPI plugin, which allows you to drive strings of LEDs pixels provided your platform has an SPI interface. Using embedded Linux platforms like the Raspberry Pi, this allows one to build Pixel strings controllable via any of the supported protocols (ArtNet, E1.31, OSC & more) for less than $100.
Alternatively if you don't want network control, you can send DMX512 to the LEDs using the Python, C++ or Java client library running on the host itself.
This page is focused on the Raspberry Pi, but may be applicable to other hardware such as the BeagleBone. If you're using a Raspberry Pi you can save yourself a lot of time by using the pre-built images, see OLA on the Raspberry Pi for details.
Contents
Host Hardware
The Raspberry Pi contains three SPI interfaces, but only one of these is wired to the 26-pin connector. The interface comes with 3 chip-enable (CE) lines but again only two are connected (pins 24 & 26). With the default mode, pin 24 is pulled low when the /dev/spi0.0 device is used and pin 26 is pulled low when /dev/spi0.1 is used.
The Pi uses 3.3V logic. You can usually get away with connecting the pins directly to the pixel hardware which uses 5V for testing, but for reliable operation it's best to use a driver circuit to convert the voltage levels from 3.3v to 5v especially if you have a cable run between the Pi and the Pixel string. There is a schematic available or you can buy a kit.
Here are some timings stats collected from the Pi:
SPI Speed | Number of bytes | time taken for write() | Time on the wire |
---|---|---|---|
1MHz | 75 | 13.5ms | 11.1ms |
2MHz | 75 | 8.1ms | 5.6ms |
4MHz | 75 | 4.7 ms | 3.0 ms |
8MHz | 75 | 3.7ms | 1.4ms |
12MHz | 75 | 3.2ms | 0.75 ms |
1MHz | 516 | 78.5 ms | 76.15 ms |
2MHz | 516 | 40.2 ms | 38.2ms |
4MHz | 516 | 21.5 ms | 19.1 ms |
8MHz | 516 | 12.2ms | 9.6ms |
12MHz | 516 | 7.4ms | 4.83 ms |
It also takes somewhere between 3.6 and 4.6 ms to toggle a GPIO pin using the /sys/class/gpio interface. The importance of these numbers will be clear in a minute.
Beyond the Pi, any SPI hardware supported by the Linux kernel should work modulo the timing restrictions. By default OLA looks for devices that match the /dev/spi* .
Pixel Hardware
On the pixel side the following is supported:
- LPD8806, e.g. https://www.adafruit.com/products/306. since 0.8.27
- WS2801, e.g. https://www.adafruit.com/products/738, since 0.8.28
Each of these uses 3 DMX slots per pixel, so you can drive up to 170 pixels from a universe of DMX data.
Hardware Setup
The simplest setup is to connect SCLK (pin 23) to the pixel string's clock line and MOSI (pin 19) to the pixel string's DATA line. You'll need a separate power supply for the pixel string, check the pixel specifications but 1A per m is a good rule of thumb. Don't forget to connect the ground on the power supply to a ground pin (e.g. 25) on the Pi.Do not connect the 5V rail of the pixel power supply to the Pi.
Multiplexer
If you want to drive more than one string in parallel you'll need to use a de-multiplexer. For a two-line multiplexer one can use the CE0 and CE1 lines to select the output string. To run more than 2 strings you'll need to use some of the GPIO pins as chip-enables. However these pins are slow (~4ms) which limits the update rate.
There is a 8 way demultiplexer schematic here.
OLA SPI Plugin
The OLA SPI plugin is pretty flexible, the primary limitation is how long it takes to write the data out the SPI interface, and this limits the overall refresh rate. Each SPI interface (/dev/spi*) is represented as an OLA Device. Devices can have multiple 'ports' since each port can consume at most one universe of DMX512 data (170 RGB pixels). Each port can be configured (via RDM) with a start address and personality (pixel type). This allows a combination of various strings lengths & pixel hardware types.
Each SPI device uses a backend to write the SPI data. Right now there are two types backends available: a software backend which merges the SPI data from one or more ports, and a hardware backend which uses the GPIO pins to control a hardware demultiplexer.
Timing
It all comes down to timing. Consider the following example:
- 170 LPD8806 pixels per string (results in 516 bytes written)
- Two strings using the built in CE lines to drive a hardware demultipliexer.
- SPI speed of 2Mhz
Using timing table above, we can see this will take 40.2 ms x 2 = 80ms to update all pixels. That means you'll only be able to do 12 updates per second. Most DMX systems run at 40 updates per second so we'll end up dropping updates.
If we tried to use GPIO pins rather than the CE ones it gets worse. Consider a second example:
- 32 WS2801 pixels per string (results in 75 bytes written)
- Four strings using two GPIO lines to drive a hardware demultipliexer.
- SPI speed of 2Mhz
Now each write requires setting GPIO pins. Worse case both pins will need to change which adds 8ms. The write itself takes 8.1 ms, so that's 16.1 ms per string or 64.4 ms to update all strings. That gives you an update rate of 15 updates per second. Still not close to DMX's 40 updates per second.
Software Setup
You'll need a suitable udev config, so that OLA has permission to talk to your SPI port. There is also some Raspberry Pi specific config (enabling a kernel module) on the same page.
If you're using the GPIO pins to drive an hardware demultiplexer, you'll need to run the following as root prior to starting olad.
for pin in 17 21; do echo $pin > /sys/class/gpio/export; chmod a+w /sys/class/gpio/gpio${pin}/value; chmod a+w /sys/class/gpio/gpio${pin}/direction; done
Once you have OLA running it's a matter of patching an SPI Output port to a universe and then patching the desired input port. This can be done from the OLA web UI or by using ola_patch .
Configuration
The type of LED drivers, operating mode and DMX Start Address are configurable via RDM. Click on the RDM tab and you'll see the options.
The number of LEDs and SPI speed is set using the ola-spi.conf file.
base_uid = 7a70:00000100 device_prefix = spidev enabled = true spidev0.0-dmx-address = 1 spidev0.0-personality = 1 spidev0.0-pixel-count = 25 spidev0.0-spi-speed = 100000 spidev0.1-dmx-address = 1 spidev0.1-personality = 2 spidev0.1-pixel-count = 25 spidev0.1-spi-speed = 1000000
Example Configs
Single Pixel String
For a simple single-string output we can use the software backend and ignore the CE lines. This config is for 25 WS2801 pixels running at 1Mhz on /dev/spi0.0. From the timing information above this should support about 75 updates / second.
base_uid = 7a70:00000100 device_prefix = spidev enabled = true spidev0.0-0-dmx-address = 1 spidev0.0-0-pixel-count = 25 spidev0.0-0-personality = 1 spidev0.0-backend = software spidev0.0-ports = 1 spidev0.0-spi-speed = 1000000
Two Pixel Strings, using the CE lines
This example is for 25 WS2801 pixels and 32 LPD8806 pixels. Both strings run at 2Mhz and are connected to the spi bus, and we're using the CE chips to de-multiplex. We want to CE lines to be active-high.
base_uid = 7a70:00000100 device_prefix = spidev enabled = true spidev0.0-0-dmx-address = 1 spidev0.0-0-personality = 1 spidev0.0-0-pixel-count = 25 spidev0.0-backend = software spidev0.0-ports = 1 spidev0.0-spi-ce-high = true spidev0.0-spi-speed = 200000 spidev0.1-0-dmx-address = 1 spidev0.1-0-personality = 1 spidev0.1-0-pixel-count = 25 spidev0.1-backend = software spidev0.1-ports = 1 spidev0.1-spi-ce-high = true spidev0.1-spi-speed = 2000000
Two Pixel Strings, using a single output
This example is a string of 300 WS2801 pixels. Since this is more than one universe of data, we need to use multiple ports.
base_uid = 7a70:00000100 device_prefix = spidev enabled = true spidev0.0-0-dmx-address = 1 spidev0.0-0-personality = 1 spidev0.0-0-pixel-count = 150 spidev0.0-1-dmx-address = 1 spidev0.0-1-personality = 1 spidev0.0-1-pixel-count = 150 spidev0.0-backend = software spidev0.0-ports = 2 spidev0.0-spi-speed = 1000000 spidev0.0-sync-port = -2
SPI data is written when data arrives on the second port (sync-port = -2). See the plugin description for more info.
Exported Variables
The SPI plugin exports a number of useful variables. These can be found at http://<ip>:9090/debug. Each is indexed by the device name e.g. /dev/spi0.0 .
- spi-writes
- Number of writes to each SPI device
- spi-write-errors
- Number of writes that resulted in an error
- spi-drops
- Number of DMX updates that were skipped. The happens if DMX data is arriving faster than it can be written to the SPI bus.
Related Links
http://www.solderlab.de/index.php/software/glediator (Pixel Control Software that outputs ArtNet)