From 6ad76786b7238cc988d78a12b3b7166e900130a2 Mon Sep 17 00:00:00 2001 From: Skylten Date: Sun, 14 Jun 2020 20:34:31 +0200 Subject: [PATCH] Initial commit, long after the project actually started --- README.md | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ff0193 --- /dev/null +++ b/README.md @@ -0,0 +1,203 @@ +rpi_ws281x +========== + +Userspace Raspberry Pi library for controlling WS281X LEDs. +This includes WS2812 and SK6812RGB RGB LEDs +Preliminary support is now included for SK6812RGBW LEDs (yes, RGB + W) +The LEDs can be controlled by either the PWM (2 independent channels) +or PCM controller (1 channel) or the SPI interface (1 channel). + +### Bindings: + +Language-specific bindings for rpi_ws281x are available in: + +* Python - https://github.com/rpi-ws281x/rpi-ws281x-python +* Rust - https://github.com/rpi-ws281x/rpi-ws281x-rust +* Powershell - https://github.com/rpi-ws281x/rpi-ws281x-powershell +* Java - https://github.com/rpi-ws281x/rpi-ws281x-java +* CSharp - https://github.com/rpi-ws281x/rpi-ws281x-csharp +* Go - https://github.com/rpi-ws281x/rpi-ws281x-go + +### Background: + +The BCM2835 in the Raspberry Pi has both a PWM and a PCM module that +are well suited to driving individually controllable WS281X LEDs. +Using the DMA, PWM or PCM FIFO, and serial mode in the PWM, it's +possible to control almost any number of WS281X LEDs in a chain connected +to the appropriate output pin. +For SPI the Raspbian spidev driver is used (`/dev/spidev0.0`). +This library and test program set the clock rate to 3X the desired output +frequency and creates a bit pattern in RAM from an array of colors where +each bit is represented by 3 bits as follows. + + Bit 1 - 1 1 0 + Bit 0 - 1 0 0 + + +### GPIO Usage: + +The GPIOs that can be used are limited by the hardware of the Pi and will +vary based on the method used to drive them (PWM, PCM or SPI). +Beware that the GPIO numbers are not the same as the physical pin numbers +on the header. + +PWM: +``` + PWM0, which can be set to use GPIOs 12, 18, 40, and 52. + Only 12 (pin 32) and 18 (pin 12) are available on the B+/2B/3B + + PWM1 which can be set to use GPIOs 13, 19, 41, 45 and 53. + Only 13 is available on the B+/2B/PiZero/3B, on pin 33 +``` + +PCM: +``` + PCM_DOUT, which can be set to use GPIOs 21 and 31. + Only 21 is available on the B+/2B/PiZero/3B, on pin 40. +``` + +SPI: +``` + SPI0-MOSI is available on GPIOs 10 and 38. + Only GPIO 10 is available on all models. + See also note for RPi 3 below. +``` + + +### Power and voltage requirements + +WS281X LEDs are generally driven at 5V. Depending on your actual +LED model and data line length you might be able to successfully drive +the data input with 3.3V. However in the general case you probably +want to use a level shifter to convert from the Raspberry Pi GPIO/PWM to 5V. + +It is also possible to run the LEDs from a 3.3V - 3.6V power source, and +connect the GPIO directly at a cost of brightness, but this isn't +recommended. + +The test program is designed to drive a 8x8 grid of LEDs e.g.from +Adafruit (http://www.adafruit.com/products/1487) or Pimoroni +(https://shop.pimoroni.com/products/unicorn-hat). +Please see the Adafruit and Pimoroni websites for more information. + +Know what you're doing with the hardware and electricity. I take no +reponsibility for damage, harm, or mistakes. + +### Build: + +- Install Scons (on raspbian, `apt-get install scons`). +- Make sure to adjust the parameters in main.c to suit your hardware. + - Signal rate (400kHz to 800kHz). Default 800kHz. + - ledstring.invert=1 if using a inverting level shifter. + - Width and height of LED matrix (height=1 for LED string). +- Type `scons` from inside the source directory. + +### Running: + +- Type `sudo ./test` (default uses PWM channel 0). +- That's it. You should see a moving rainbow scroll across the + display. +- More options are available, `./test -h` should show them: +``` +./test version 1.1.0 +Usage: ./test +-h (--help) - this information +-s (--strip) - strip type - rgb, grb, gbr, rgbw +-x (--width) - matrix width (default 8) +-y (--height) - matrix height (default 8) +-d (--dma) - dma channel to use (default 10) +-g (--gpio) - GPIO to use + If omitted, default is 18 (PWM0) +-i (--invert) - invert pin output (pulse LOW) +-c (--clear) - clear matrix on exit. +-v (--version) - version information +``` + +### Important warning about DMA channels + +You must make sure that the DMA channel you choose to use for the LEDs is not [already in use](https://www.raspberrypi.org/forums/viewtopic.php?p=609380#p609380) by the operating system. + +For example, **using DMA channel 5 [will cause](https://github.com/jgarff/rpi_ws281x/issues/224) filesystem corruption** on the Raspberry Pi 3 Model B. + +The default DMA channel (10) should be safe for the Raspberry Pi 3 Model B, but this may change in future software releases. + +### Limitations: + +#### PWM + +Since this library and the onboard Raspberry Pi audio +both use the PWM, they cannot be used together. You will need to +blacklist the Broadcom audio kernel module by creating a file +`/etc/modprobe.d/snd-blacklist.conf` with + + blacklist snd_bcm2835 + +If the audio device is still loading after blacklisting, you may also +need to comment it out in the /etc/modules file. + +On headless systems you may also need to force audio through hdmi +Edit config.txt and add: + + hdmi_force_hotplug=1 + hdmi_force_edid_audio=1 + +A reboot is required for this change to take effect + +Some distributions use audio by default, even if nothing is being played. +If audio is needed, you can use a USB audio device instead. + +#### PCM + +When using PCM you cannot use digital audio devices which use I2S since I2S +uses the PCM hardware, but you can use analog audio. + +#### SPI + +When using SPI the ledstring is the only device which can be connected to +the SPI bus. Both digital (I2S/PCM) and analog (PWM) audio can be used. + +Many distributions have a maximum SPI transfer of 4096 bytes. This can be +changed in `/boot/cmdline.txt` by appending +``` + spidev.bufsiz=32768 +``` +On a RPi 3 you have to change the GPU core frequency to 250 MHz, otherwise +the SPI clock has the wrong frequency. +Do this by adding the following line to /boot/config.txt and reboot. +``` + core_freq=250 +``` + +SPI requires you to be in the `gpio` group if you wish to control your LEDs +without root. + +### Comparison PWM/PCM/SPI + +Both PWM and PCM use DMA transfer to output the control signal for the LEDs. +The max size of a DMA transfer is 65536 bytes. Since each LED needs 12 bytes +(4 colors, 8 symbols per color, 3 bits per symbol) this means you can +control approximately 5400 LEDs for a single strand in PCM and 2700 LEDs per string +for PWM (Only PWM can control 2 independent strings simultaneously) +SPI uses the SPI device driver in the kernel. For transfers larger than +96 bytes the kernel driver also uses DMA. +Of course there are practical limits on power and signal quality. These will +be more constraining in practice than the theoretical limits above. + +When controlling a LED string of 240 LEDs the CPU load on the original Pi 2 (BCM2836) are: + PWM 5% + PCM 5% + SPI 1% + +### Usage: + +The API is very simple. Make sure to create and initialize the `ws2811_t` +structure as seen in [`main.c`](main.c). From there it can be initialized +by calling `ws2811_init()`. LEDs are changed by modifying the color in +the `.led[index]` array and calling `ws2811_render()`. +The rest is handled by the library, which either creates the DMA memory and +starts the DMA for PWM and PCM or prepares the SPI transfer buffer and sends +it out on the MISO pin. + +Make sure to hook a signal handler for SIGKILL to do cleanup. From the +handler make sure to call `ws2811_fini()`. It'll make sure that the DMA +is finished before program execution stops and cleans up after itself.