Go Down

Topic: questions about chaining RGB LED+servo modules using WS2801 chips.. control? (Read 4 times) previous topic - next topic


hello to all !

i'm new to all this so please excuse my ignorance..:)

i'm constructing a fixture that requires me to build a whole bunch of modules, chain them all together, and have them all controlled by a single computer using the ART-NET protocol.

each module will have 1 RGB LED connected to a WS2801 chip, and 1 servo motor also connected to a WS2801 chip.

Servo info: http://www.aliexpress.com/product-fm/497600351-Freeshipping-DC-5V-Stepper-Motor-Geared-for-Arduino-PIC-MCU-DIY-28BYJ-48-5v-28BYJ-48-wholesalers.html
LED info: http://www.aliexpress.com/product-fm/463271409-8mm-Round-LED-Common-Anode-Diffused-RGB-Color-wholesalers.html
WS2801 info: http://www.adafruit.com/datasheets/WS2801.pdf

all the modules will be chained together in a row, finally plugged into an Arduino Mega 2560 + Ethernet Shield + Xbee wireless Shield. The Arduino will communicate with the computer using the ART-NET protocol, threw the Ethernet cable or via Wi-Fi.

Basically, my questions are:
1. Is the WS2801 the right chip to use (i heard it can also drive a servo motor)?
2. What are the 5 wires on the servo motor? how do connect it to a WS2801 chip?
3. Are there any other cheap chainable driver chips that have 5-6 channels (i could then connect both the RGB LED and the servo motor to a single driver chip, instead of using 2 WS2801 chips in each module)?
4. Is there a limit of how many modules i can chain together? After how many modules would i need to inject more power to the module chain?
5. How difficult is it to get the Arduino to function using the ART-NET protocol threw the Ethernet Shield or using the Wi-Fi Shield.
6. How does the Arduino know exactly how many modules are connected?
7.. Is this at all POSSIBLE ???

I posted a diagram bellow:

Thanks !


The WS2801 only has three channels.  That servo has five.  See a problem there?  I'm not sure where you're trying to go with the WS2801 since it's an LED driver, not a servo driver.


the specific type of servo is less of an issue, i can also use a regular RC mini servo that has 3 wires, all i need is for the motor to turn forward and reverse.

the reason i mention the WS2801 chips is because they can be chained together for use with 3 channel LEDs, can it also be used to drive a small servo forward and reverse?

is there any other chainable chip that can drive LED's and a servo (maybe 6 channel)?



You need to figure out (a) how much current the servo needs, (b) how many legs it needs, and (c) whether it works with PWM ... at the very least.

WS2801 (3 channels) produces a PWM signal to drive the LEDs, and you can drive it in either constant current (up to 50mA) or constant voltage (up to 100mA).  You have to figure out which works for whatever servo you decide to use.

As for more channels, there is the WS2803 which has 18 channels.  That one only provides constant current up to 30mA.

I have no clue if either will work for driving a servo.  You're on your own there.  Both of those provide a PWM signal.


let's say the servos manage to work with the WS2801 chips, what about the arduino?

Is there a limit of how many modules i can chain together? After how many modules would i need to inject more power to the module chain?
How difficult is it to get the Arduino to function using the ART-NET protocol threw the Ethernet Shield or using the Wi-Fi Shield.
How does the Arduino know exactly how many modules are connected?
Will this all work stably? what should i look out for?

Thanks for the help KirAsh4!


How are you getting on with this?

I'm doing something similar (without the servos, though I am going to try using ws2801s to drive solenoids)

WS2801 control - http://www.bliptronics.com/arduinocode/blip_leds_spi_2801.zip works for me

And artnet - get an ethernet shield (or the cheaper alternative - http://www.sparkfun.com/products/9473  Connected as follows -

J1-1 (MOSI) to D11,
J1-2 (MISO) to D12,
J2-1 (3.3) to 3.3v,
J2-3 (SCLK) to D13,
J2-4 (/SCS) to D10,
J2-9 (GND) to Ground,
J2-2 (/RESET) to Reset

Then download the zip file here http://vvvv.org/contribution/art-net-set-for-arduino and use the sketch 'art-net receiver.pde'

You may need to change 'the condition from ==taille_chaine_artnet to >25'  See this thread - http://vvvv.org/forum/karistouf-reartnet-set#comment-78276

Now we're got here we run into a problem which is both the ws2801 chips and the ethernet controller are using the spi bus.  I'm currently trying to figure out how to combine both. I think there's a way do use spi on arbitrary pins but I'm not sure. It should actually be possible to share clock between both and use mosi for the ws2801 and miso for the ethernet controller, as we dont need bi directional communication (unless you need servo feedback)

Where are you based?


This library from adafruit will let you use any pins for mosi and clock output to the ws2801 https://github.com/adafruit/WS2801-Library

But it's apparently quite *slow*. Someone has made a faster version but it uses the hardware spi pins so clashes with the ethernet controller

Can anyone advise what the fastest method would be to communicate with the ws2801 without using the hardware spi pins (10,11,12,13)

edit - https://www.adafruit.com/forums/viewtopic.php?f=47&p=125746 here is a version with direct port manipulation, or hardware spi, and estimates of the numbers of leds that can be controlled at what fps.


Thanks for the replys !

So what's the verdict mrboni? (heheh.. i sound like a judge)

Can a bunch of WS2801 modules run WITH an ethernet shield?
What if i skip the whole ethernet option and just use a WiFi shield? Will that clash too?

I need this system to show 'semi-decent' video on the RGB pixels so bassicly, Is there any limit on how many WS2801 pixels/servos can Arduino handle without beeing too slow? Wich Arduino is best for the job?

Im also interested to know how you wired your solonieds, Can you share a pic or diagram?
How do i wire a regular 3 wire servo to the WS2801 chip?

Thanks for tha' help !


Hi mrboni

I'm also interested by you result in combining ws2801 leds via SPI + artnet ability via ethernet shield using the same... SPI

Thanks ;-)


Are you using ws2801 or ws2803?

If so, you're in luck. It's all working. Though only working reliably with a Mega2560.

Think this is working code. Let me know if you have any questions.

Needs this lib -https://github.com/adafruit/Adafruit-WS2801-Library

Code: [Select]

#include "Adafruit_WS2801.h"

int dataPin  = 6;    // WS2801 Data
int clockPin = 7;    // WS2801 Clock
Adafruit_WS2801 strip = Adafruit_WS2801(16, dataPin, clockPin); //Configure WS2801 as follows: (number of ws2801, dataPin, clockPin)

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#define short_get_high_byte(x) ((HIGH_BYTE & x) >> 8)
#define short_get_low_byte(x)  (LOW_BYTE & x)
#define bytes_to_short(h,l) ( ((h << 8) & 0xff00) | (l & 0x00FF) );
#define UDP_PACKET_MAX_SIZE 2048

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x03, 0x65 };
IPAddress ip(2,0,0,101);

unsigned int localPort = 6454;      // local port to listen on

//customisation: edit this if you want for example read and copy only 4 or 6 channels from channel 12 or 48 or whatever.
const int number_of_channels=512; //512 for 512 channels
const int channel_position=1; // 1 if you want to read from channel 1

// buffers for receiving and sending data
char packetBuffer[UDP_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
byte buffer_dmx[number_of_channels+channel_position]; //buffer to store filetered DMX data

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

// art net parameters
const int art_net_header_size=17;
const int max_packet_size=576;
char ArtNetHead[8]="Art-Net";
char OpHbyteReceive=0;
char OpLbyteReceive=0;
short is_artnet_version_1=0;
short is_artnet_version_2=0;
short seq_artnet=0;
short artnet_physical=0;
short incoming_universe=0;
boolean is_opcode_is_dmx=0;
boolean is_opcode_is_artpoll=0;
boolean match_artnet=1;
short Opcode=0;

void setup() {
  strip.begin(); //Initialize WS2801 'strip' (WS2801 chips in a chain)
  strip.show(); // Update LED contents, to start they are all 'off'
// start the Ethernet and UDP:

//  pinMode(6, OUTPUT); // setup pin 6 as output to test an artnet channel with an led

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
    //debug(packetSize); // uncomment this line to show packet info in serial monitor
  //read header
  match_artnet=1;//valeur de stockage
  for (int i=0;i<7;i++)
      {match_artnet=0;break;}//if not corresponding, this is not an artnet packet, so we stop reading
     if (match_artnet==1)//if its an artnet header
       /*artnet protocole revision, not really needed
       /*sequence of data, to avoid lost packets on routeurs
       /*physical port of  dmx N°
       //operator code enables to know wich type of message Art-Net it is
       if(Opcode==0x5000)//if opcode is DMX type
       else if(Opcode==0x2000)//if opcode is artpoll
         //( we should normally reply to it, giving ip adress of the device)
       if(  is_opcode_is_dmx=1)//if its DMX data we will read it now
         //if you need to filter DMX universes, uncomment next line to have the universe rceived
         //incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14])
         //getting data from a channel position, on a precise amount of channels, this to avoid to much operation if you need only 4 channels for example
         for(int i=channel_position-1;i< number_of_channels;i++)//channel position
           buffer_dmx[i]= byte(packetBuffer[i+18]);
           //note that channels are zero based, ie the first channel is buffer_dmx[0]
    for(int i=0;i<512;i++)//channel position
//analogWrite(6,buffer_dmx[0]);  // test channel 0 with an led on pin 6
}//end MAIN LOOP

//debug method
int debug(int packetSize)
  Serial.print("Received packet of size ");
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++)
      Serial.print(remote[i], DEC);
      if (i < 3)
    Serial.print(", port ");


Thank you very much for your reply.

I have been playing with the adafruit library already (in fact I am while typing this).

From what I understand with a quick look in your code (I'm no expert), you are using the "soft spi" way this library is offering.
This allows the spi bus to stay free but the "soft spi way" is of course slower than the "hardware spi" way,

My question is :

Did you try this solution yourself and did you come accross speed / framerate issues with this solution ?

Thank you again for your advice.


That's because the hardware spi is used by the ethernet shield.  soft spi seems to work fine. I can't remember what the clock speed is but it's possible you'd notice it affect the update speed if you had loads of led chained but I doubt it.

  How many do you plan to use?


from http://forums.adafruit.com/viewtopic.php?f=47&t=24256

These figures are strictly I/O time and don't include any overhead for calculating the pixel image. Thus your actual speed will be somewhat less, depending on the complexity of the rendering code involved.

Original library using digitalWrite:
1000 + 470 microseconds per LED
(For 150 LEDs, about 14 frames/second)

Revised library with direct PORT writes:
1000 + 130 uS/LED
(~ 50 FPS)

Revised library using hardware SPI:
1000 + 17 uS/LED
(~280 FPS)

the one in bold is for soft spi. so given that artnet will limit you to 512 leds you should be ok!


Thanks a lot for your valuable help.

I don't plan to use more than 512 / 3 = > 170 leds per arduino so I should be ok, you are right.

I ran some strobe tests and it IS fast !!

I'll keep this post updated when I receive my ethernet shield.

Thaks again.



No worries. Note that I'm using an arduino Mega.  I know some people have had success with the UNO and artnet, but not me.

Go Up