Skip to content
master
Switch branches/tags
Go to file
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

RPI-WS2812-Server

This is a small program for driving the WS281x (a.k.a. NeoPixel) LEDs from a webserver, command line, text file, Python,... using the Raspberry Pi. It uses the rpi_ws281x PWM driver code from jgarff (https://github.com/jgarff/rpi_ws281x). The LEDs can be controlled by sending text commands to a tcp socket. These commands can be generated by a webserver script, android app,... It's also possible to control the leds directly from the command line or by loading text file containing some predefined color patterns. Since version 5.0 support for the SK9822 chips which use a clock and data (SPI like interface) was added.

read the change log to see what is new: CHANGES.md

Supported chips

You can use this with the WS2811, WS2812, SK6812, SK9822 chips.

Installation

On the raspberry you open a terminal window and type following commands:

sudo apt-get update
sudo apt-get install gcc make git libjpeg-dev libpng-dev
git clone https://github.com/tom-2015/rpi-ws2812-server.git
cd rpi-ws2812-server
make
sudo chmod +x ws2812svr

Newer versions require libjpeg-dev and libpng-dev for reading PNG and JPEG images. If you don't want to use JPEG or PNG you can disable this using:

make NO_JPEG=1 NO_PNG=1

On newer Raspbian (>=Jessie) operating system the audio output is activated by default, you need to disable this: You can do this by blacklisting the sound module:

echo "blacklist snd_bcm2835" | sudo tee /etc/modprobe.d/snd-blacklist.conf

Also in comment out the audio=on parameter in /boot/config.txt

sed "s/^dtparam=audio=on/#dtparam=audio=on/g" /boot/config.txt

Testing

Connect your LEDs to the PWM output of the Raspberry Pi and start the program:

sudo ./ws2812svr

Now first initialize the driver code from jgarff by typing 'setup'. On the following line you must replace 10 by the number of leds you have attached!.

setup 1,10
init

Now you can type commands to change the color of the leds. For example make them all red:

fill 1,FF0000
render

Available commands

Here is a list of commands you can type or send to the program. All commands have optional comma seperated parameters. The parameters must be in the correct order!

  • init command must be called everytime the program is started after the setup command, this will initialize resource on the Pi according to the setup command
init <frequency>,<dma>

# <frequency> Frequency to use for communication to the LEDs, default 800000
# <dma>       DMA channel number to use, default 10 be careful not to use any channels in use by the system as this may crash your SD card/OS
#             use cat /proc/device-tree/soc/dma@7e007000/brcm,dma-channel-mask to see which channels (bitmask) might be used by the OS
  • setup command must be called everytime the program is started:

Depending on the <led_type> the setup command takes different parameters.


# For <led_type> values 0-11 (WS2812 and SK6812 chips):

setup <channel>,<led_count>,<led_type>,<invert>,<global_brightness>,<gpionum>

# <channel>            Channel number
# <led_count>          Number of leds in channel
# <led_type>           Type of led (3 color or 4 color) default 0
# <invert>             Invert output, default 0
# <global_brightness>  Global brightness level for channel (0-255), default 255
# <gpionum>            GPIO output number, default 18 for more see 'GPIO usage' at this page: [https://github.com/jgarff/rpi_ws281x](https://github.com/jgarff/rpi_ws281x)


# For <led_type> values 12-17 (SK9822 chips):

setup <channel>,<led_count>,<led_type>,<invert>,<global_brightness>,<SPI_DEV>,<SPI_SPEED>,<ALT_SPI_PIN>

# <channel>            Channel number
# <led_count>          Number of leds in channel
# <led_type>           Type of led (3 color or 4 color) default 0
# <invert>             Invert SPI data pin (clock cannot be inverted)
# <global_brightness>  Global brightness level for channel (0-255), default 255
# <SPI_DEV>            The spi device file to use (default /dev/spidev0.0)
# <SPI_SPEED>,         The speed of the SPI bus (default 20Mhz)
# <ALT_SPI_PIN>        Alternative SPI MOSI output pin default 10, can be set to 38


# If using 2 SK9822 led strips at /dev/spidev0.0 and /dev/spidev0.1 you need to add some logic gates to direct MOSI and SPI CLOCK to the right led string when CE0 and CE1 pins are enabled.

Possible LED types:
 0 WS2811_STRIP_RGB
 1 WS2811_STRIP_RBG
 2 WS2811_STRIP_GRB
 3 WS2811_STRIP_GBR
 4 WS2811_STRIP_BRG
 5 WS2811_STRIP_BGR
 6 SK6812_STRIP_RGBW
 7 SK6812_STRIP_RBGW
 8 SK6812_STRIP_GRBW
 9 SK6812_STRIP_GBRW
10 SK6812_STRIP_BRGW
11 SK6812_STRIP_BGRW
12 SK9822_STRIP_RGB
13 SK9822_STRIP_RBG
14 SK9822_STRIP_GRB
15 SK9822_STRIP_GBR
16 SK9822_STRIP_BRG
17 SK9822_STRIP_BGR

Example: setup 1,10,0
  • render command sends the internal buffer to all leds
render <channel>,<start>,<RRGGBBRRGGBB...>

# <channel>         Send the internal color buffer to all the LEDS of <channel> default is 1
# <start>           Before render change the color of led(s) beginning at <start> (0=led 1)
# <RRGGBBRRGGBB...> Color to change the led at start Red+green+blue (no default)
  • rotate command moves all color values of 1 channel
rotate <channel>,<places>,<direction>,<RRGGBB>

# <channel>     Channel to rotate (default 1)
# <places>      Number of places to move each color value (default 1)
# <direction>   Direction (0 or 1) for forward and backwards rotating (default 0)
# <RRGGBB>      First led(s) get this color instead of the color of the last led
  • rainbow command creates rainbows or gradient fills
rainbow <channel>,<count>,<start_color>,<end_color>,<start>,<len>

# <channel>     Channel to fill with a gradient/rainbow (default 1)
# <count>       Number of times to repeat the rainbow in the channel (default 1)
# <start_color> Color to start with value from 0-255 where 0 is red and 255 pink (default is 0)
# <end_color>   Color to end with value from 0-255 where 0 is red and 255 pink (default 255)
# <start>       Start at this led position
# <len>         Number of leds to change
  • fill command fills number of leds with a color value
fill <channel>,<RRGGBB>,<start>,<len>,<OR|AND|XOR|NOT>

# <channel>        Channel to fill leds with color (default 1)
# <RRGGBB>         Color to fill (default FF0000)
# <start>          At which led should we start (default is 0)
# <len>            Number of leds to fill with the given color after start (default all leds)
# <OR,AND,XOR,NOT> Bitwise operator to execute on OLD and NEW color, default = copies new color to output
  • delay command waits for number of milliseconds
delay <milliseconds>

# <milliseconds>  Enter number of milliseconds to wait
  • brightness command changes the brightness of a single or multiple leds without changing the actual color value
brightness <channel>,<brightness>,<start>,<len>

# <channel>      Channel number to change brightness (default 1)
# <brightness>   Brightness to set (0-255, default 255)
# <start>        Start at this led number (default 0)
# <len>          Number of leds to change starting at start (default led count of channel)
  • fade command changes the brightness over time
fade <channel>,<start_brightness>,<end_brightness>,<delay ms><step>,<start_led>,<len>

# <channel>          Channel to fade
# <start_brightness> Start brightness (default 0)
# <end_brightness>   End brightness (default 255)
# <delay ms>         Delay in ms
# <step>             Step to increase / decrease brightness every delay untill end_brightness is reached
# <start_led>        Start led
# <len>              Number of leds to change starting at start (default is channel count)
  • gradient command makes a smooth change of color or brightness level in a channel
gradient <channel>,<RGBWL>,<start_level>,<end_level>,<start_led>,<len>

# <channel>      Channel number to change
# <RGBWL>        Which color component to change, R = red, G = green, B = blue, W = white and L = brightness level
# <start_level>  Start at color level (0-255) default is 0
# <end_level>    End at color level (0-255) default is 255
# <start_led>    Start at led number (default is 0)
# <len>          Number of leds to change (default is channel count)
  • random command can create a random color
random <channel>,<start>,<len>,<RGBWL>

# <channel>   Channel number to change
# <start>     Start at this led
# <len>       Number of leds to fill with a random color, default is channel count
# <RGBWL>     Color to use in random can be R = red, G = green, B = blue, W = White, L = brightness also combination is possible like RGBW or RL
  • readjpg command can read the pixels from a JPEG file and fill them into the LEDs of a channel
readjpg <channel>,<FILE>,<start>,<len>,<offset>,<OR|AND|XOR|NOT>,<delay>,<flip_rows>

# <channel>         Channel number to load pixels to
# <FILE>            File location of the JPG without any "" cannot contain a ,
# <start>           Start position, start loading at this LED in channel (default 0)
# <len>             Load this ammount of pixel/LEDs (default is channel count or led count)
# <offset>          Start at pixel offset in JPG file (default is 0)
# <OR|AND|XOR|NOT>  Operator to use, use NOT to reverse image (default is =)
# <delay>           Optional argument the delay between rendering next scan line in the jpg file, if 0 only first line is loaded in to memory and no render performed. default 0
# <flip_rows>       Optional argument to indicate to horizontally flip rows with odd index
  • readpng command can read the pixels from a PNG file and fill them into the LEDs of a channel
readpng <channel>,<FILE>,<BACKCOLOR>,<start>,<len>,<offset>,<OR|AND|XOR>,<delay>,<flip_rows>

# <channel>,        Channel number to load pixels to
# <FILE>,           File location of the PNG file without any "" cannot contain a ,
# <BACKCOLOR>,      The color to use for background in case of a transparent image (default is the PNG image backcolor = P), if BACKCOLOR = W the alpha channel will be used for the W in RGBW LED strips
# <start>,          Start position, start loading at this LED in channel (default 0)
# <len>,            Load this ammount of pixel/LEDs	(default is channel count or led count)
# <offset>,         Start at pixel offset in JPG file (default is 0)
# <OR AND XOR =>,   Operator to use, use NOT to reverse image (default is =)
# <delay>,          Optional argument the delay between rendering next scan line in the png file, if 0 only first line is loaded in to memory and no render performed. default 0
# <flip_rows>,      Optional argument to indicate to horizontally flip rows with odd index
  • blink command makes a group of leds blink between 2 given colors
blink <channel>,<color1>,<color2>,<delay>,<blink_count>,<startled>,<len>

# <channel>      Channel number to change
# <color1>       First color to use
# <color2>       Second color
# <delay>        Delay in ms between change from color1 to color2
# <blink_count>  Number of changes between color1 and color2
# <startled>     Start at this led position
# <len>          Number of LEDs to blink starting at startled
  • random_fade_in_out creates some kind of random blinking/fading leds effect
random_fade_in_out <channel>,<duration Sec>,<count>,<delay>,<step>,<inc_dec>,<brightness>,<start>,<len>,<color>

# <channel>      Channel number to use
# <duration_s>   Duration of effect in seconds
# <count>        Max number of leds that will fade in or out at same time
# <delay>        Delay between changes in brightness
# <step>         Ammount of brightness to increase/decrease between delays
# <inc_dec>      Inc_dec = if 1 brightness will start at <brightness> and decrease to initial brightness of the led, else it will start low and go up
# <brightness>   Brightness to start with when blinking starts
# <start>        Start position
# <len>          Number of leds
# <color>        Color to use for blinking leds

Example of a string with 300 LEDs:
fill 1,FFFFFF;
brightness 1,0;
random_fade_in_out 1,60,50,10,15,800;
  • color_change slowly change all leds from one color to another
color_change <channel>,<start_color>,<stop_color>,<duration>,<start>,<len>

# <channel>     Channel number to use
# <start_color> Color to start with value from 0-255 where 0 is red and 255 pink (default is 0)
# <stop_color>  Color to end with value from 0-255 where 0 is red and 254 pink (default is 255)
# <duration>    Total number of ms event should take, default is 10 seconds
# <start>       Start effect at this led position
# <len>         Number of leds to change starting at start
  • chaser makes a chaser light
chaser <channel>,<duration>,<color>,<direction>,<count>,<delay>,<start>,<len>,<brightness>,<loops>

# <channel>     Channel number to use
# <duration>    Max number of seconds the event may take in seconds (default 10) use 0 to make chaser run forever
# <color>       Color 000000-FFFFFF to use for chasing leds
# <direction>   Direction 1 or 0 to indicate forward/backwards direction of movement
# <count>       Number of LEDs in the chaser that will light up
# <delay>       Delay between moving one pixel (milliseconds) default is 10ms
# <start>       Start effect at this led position
# <len>         Number of leds the chaser will move before starting back start led
# <brightness>  Brightness value of chasing leds (0-255) default is 255
# <loops>       Max number of loops, use 0 to loop forever / duration time
  • fly_in fill entire string with given brightness level, moving leds from left/right untill all leds have brightness level or a given color
fly_in <channel>,<direction>,<delay>,<brightness>,<start>,<len>,<start_brightness>,<color>

# <channel>           Channel number to use
# <direction>         Direction where to start with fly in effect (default 1)
# <delay>             Delay between moving pixels in ms (default 10ms)
# <brightness>        Final brightness of all leds default 255 or full ON
# <start>             Start effect at this led position
# <len>               Number of leds to change starting at start
# <start_brightness>  At beginning give all leds this brightness value
# <color>             Final color of the leds default is to use the current color

# NOTICE: first fill entire strip with a color if leaving color argument default (use fill <channel>,<color>)
  • fly_out fill entire string with given brightness level, moving leds from left/right untill all leds have brightness level or a given color
fly_out <channel>,<direction>,<delay>,<brightness>,<start>,<len>,<end_brightness>,<color>

# <channel>          Channel number to use
# <direction>        Direction where to start with fly out effect (default 1)
# <delay>            Delay between moving pixels in ms (default 10ms)
# <brightness>       Brightness of led that is moving out default is 255
# <start>            Start effect at this led position
# <len>              Number of leds to change starting at start
# <end_brightness>   Brightness of all leds at end, default is 0 = OFF
# <color>            Final color of the leds default is to use the current color

#NOTICE: first fill entire strip with a color before calling this function (use fill <channel>,<color>)
  • progress generates a progress bar effect or sets the leds brightness to a given progress value
progress <channel>,<direction>,<delay>,<start>,<len>,<brightness_on>,<brightness_off>,<value>

# <channel>         Channel number to use
# <direction>       Direction of progress bar (default 1) start led = 0%, start + len = 100%
# <delay>           Delay between increments of progress (default 1s), set 0 to not automatically increment and render progress bar but use the value argument
# <start>           Start effect at this led position, default 0
# <len>             Number of leds to change starting at start, default length of strip
# <brightness_on>   Brightness of led that is on default 255
# <brightness_off>  Brightness of led that is off default 0
# <value>           Set progress to this value (delay must be 0, manual render needed)

# NOTICE: first fill entire strip with a color before calling this function (use fill <channel>,<color> or rainbow,...)
  • save_state saves current color and brightness values of a channel to a CSV file, format is: 8 character hex number for color + , + 2 character hex for brightness + new line: WWBBGGRR,FF the CSV file can be loaded with load_state command.
save_state <channel>,<filename>,<start>,<len>

# <channel>   Channel number to use
# <filename>  File where to save the data
# <start>     Start saving at led index (default is led 0)
# <len>       Save this number of leds (default is the entire led string)
  • load_state loads saved color and brightness values from CSV file. see save_state for format.
load_state <channel>,<filename>,<start>,<len>

# <channel>   Channel number to load to
# <filename>  The file where to load from
# <start>     Start loading at this LED index
# <len>       Load this number of LEDs from the file
  • It is possible to start threads, a thread will execute commands between thread_start and thread_stop in the background. Multiple threads can run at the same time by changing the parameter. <join_type> will determine the behavior next time you call thread_start with the value of a thread that is still running if join_type is 0 the thread will be aborted immediately, value of 1 it will wait until the thread completed all commands and then READY + CRLF is returned.
thread_start <index>,<join_type>
	do
		rotate 1,1,2
		render
		delay 200
	loop
thread_stop
  • set_thread_exit_type This will set if the thread should be aborted when the kill_thread or ini_thread command is executed for the <thread_id> parameter READY + newline (CR + LF) will be returned when the thread has exited.
set_thread_exit_type <thread_id>,<type>

# <thread_id>   The thread number  (1-63)
# <type>        Exit type: 0 - aborts current running thread and immediate execute next commands
                           1 - wait until all commands completed, then exit
  • wait_thread wait for a given thread to finish all commands (the exit type is ignored here)
wait_thread <thread_id>

# <thread_id>  The thread number (1-63)
  • kill_thread terminate the given thread_id
kill_thread <thread_id>,<type>

# <thread_id>    The thread number (1-63)
# <type> 		 Exit type: 0 - aborts current running thread
#                           1 - wait until all commands completed
  • wait_signal waits for a signal from another thread before executing the next command
wait_signal
  • signal_thread send a signal to the given thread_id to continue executing commands
signal_thread <thread_id>
# <thread_id>  The thread number (1-63)
  • reset reset all initialized led strings, ready for new setup commands
reset

Special keywords

You can add do ... loop [times] to repeat commands.

For example the commands between do and loop will be executed 10 times:

do
	<enter commands here to repeat>
loop 10

Endless loops can be made by removing the '10'. Inside a loop you can use {i} for the loop counter as function argument where i is the loop index (for loop inside loop)

For example {0} will be automatically replace by 0,1,2,3,4:

do
	fill 1,FF0000,{0},1
loop 5
render

is the same as the C-style code:

for (i=0; i<5; i++) {
	fill 1,FF0000,i,1
}

If you have nested loops you can increase the {0} to {1}, {2},...

do
	do
		fill 1,FF0000,{1},1
	loop 5
	render
loop

Also possible to add a step value for the loop index to fill every "even" led

do
	fill 1,FF0000,{0},1
loop 5,2

is the same as:

for (i=0; i<5; i+=2) {
	fill 1,FF0000,i,1
}

To create an alternating pattern of colors use rotate commands in a loop. For a 300 LED string this will create alternating RED-YELLOW-GREEN-BLUE-PINK colors:

do
	rotate 1,1,1,FF0000
	rotate 1,1,1,FFFF00
	rotate 1,1,1,00FF00
	rotate 1,1,1,0000FF
	rotate 1,1,1,FF00FF
loop 60

PHP example

First start the server program:

  • sudo ./ws2812svr -tcp

Then run the php code from the webserver (check out the internet how to setup a webserver PHP+APACHE or PHP+NGINX on your Pi):

// Create a rainbow for 10 leds on channel 1:

send_to_leds("setup 1,10;init;brightness 1,32;");

function send_to_leds ($data) {
	$sock = fsockopen("127.0.0.1", 9999);
	fwrite($sock, $data);
	fclose($sock);
}

Command line parameters

# Listens for clients to connect to port 9999 (default).
sudo ./ws2812svr -tcp 9999`

# Loads commands from a text file
sudo ./ws2812svr -f text_file.txt

# Creates a device called /dev/ws281x where you can write you commands to with any other programming language (do-loop not supported here).
sudo ./ws2812svr -p /dev/ws281x

# Initializes with command setup 1,4,5 and command init it
sudo ./ws2812svr -i "setup 1,4,5; init;"

# Loads with settings from a config file
sudo ./ws2812svr -c /etc/ws2812svr.conf

Running as a service

To run as service run make install after compilation and adjust the config file in /etc/ws2812svr.conf

make
sudo make install

After installing service it will run by default in TCP mode on port 9999, if you want to change this you must edit the config file:

sudo nano /etc/ws2812svr.conf

Change the mode to: tcp for TCP mode (change the port= setting) file for file mode (change the file= setting for location of file) pipe for named pipe mode (change the pipe= setting for the location of the named pipe) mode must be first setting in the conf file! init setting can be used to initialize the led count and type fill color,...

mode=tcp
port=9999
file=/home/pi/test.txt
pipe=/dev/leds
init=

Complex animations

If you need to create an complex animation, it is suggested to save color values (each LED 1 pixel) in a png/jpg image file and load this file with the readpng command. If you have a LED string of 300 LEDs best is to create an image file which is 300 pixels wide and X pixels high.