questions about chaining RGB LED+servo modules using WS2801 chips.. control?

hello to all !

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

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 !
-Mickey

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)?

thanks!
-Mickey

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.

OK
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 - WIZnet W5100 Network Module with Mag Jack - WIZ811MJ - DEV-09473 - SparkFun Electronics 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 art-net set for arduino | vvvv and use the sketch 'art-net receiver.pde'

You may need to change 'the condition from ==taille_chaine_artnet to >25' See this thread - @karistouf re:artnet set - question - Forum

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 - Updated WS2801 Arduino Library - adafruit industries 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 :wink:

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 -GitHub - adafruit/Adafruit-WS2801-Library: Arduino library for controlling strips/pixels using WS2801 driver chips

//----WS2801
#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)


//----Artnet
#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;





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

  Serial.begin(57600);
  
//  pinMode(6, OUTPUT); // setup pin 6 as output to test an artnet channel with an led
}




//MAIN LOOP
//----Artnet 
void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    //debug(packetSize); // uncomment this line to show packet info in serial monitor
  Udp.read(packetBuffer,UDP_PACKET_MAX_SIZE);
  //read header
  match_artnet=1;//valeur de stockage
  for (int i=0;i<7;i++)
     {
      if(char(packetBuffer[i])!=ArtNetHead[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
       is_artnet_version_1=packetBuffer[10]; 
       is_artnet_version_2=packetBuffer[11];*/
   
       /*sequence of data, to avoid lost packets on routeurs
       seq_artnet=packetBuffer[12];*/
        
       /*physical port of  dmx N°
       //artnet_physical=packetBuffer[13];*/
        
       //operator code enables to know wich type of message Art-Net it is
       Opcode=bytes_to_short(packetBuffer[9],packetBuffer[8]);
       
       if(Opcode==0x5000)//if opcode is DMX type
       {
         is_opcode_is_dmx=1;is_opcode_is_artpoll=0;
       }   
         
       else if(Opcode==0x2000)//if opcode is artpoll 
       {
         is_opcode_is_artpoll=1;is_opcode_is_dmx=0;
         //( 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]
         }
       }
     }
  }
  
  
  
//----WS2801
    for(int i=0;i<512;i++)//channel position
      {
          strip.setPixelColor(i,buffer_dmx[i*3],buffer_dmx[i*3+1],buffer_dmx[i*3+2]);
      }
      
      
     strip.show();
     
  
//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.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());
    delay(10);
}

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 Updated WS2801 Arduino Library - adafruit industries

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.

Thanks mrboni,
After hours of failures to run the Artnet code snippet with "Arduino Uno+Ethernet shield, using Arduino 1.0 and 1.0.1". seems like a serious UDP problem in Arduino.

When I took the code of Artnet example from:
http://vvvv.org/contribution/artnet-arduino-set-v2
and ran it on Arduino Uno+Ethernet shield, using Arduino 0.23,
things started working. Although it still seems that the arduino Uno hang after a minute or two.

I will try both versions of the code, on Arduino Mega.
Thanks!

BTW, to test ArtNet DMX, I am sending ArtNet data using the free windows utility "ENTTEC node management utility (NMU)"

Hi. I had the same problem. Seems the UNO can't handle the volume of data. The Mega works fine though

The symptoms of having the WS2801 strip stop responding after few seconds seems very similar to post

As for now, I have managed to send ArtNet to Uno+Ethernet: built on Arduino 1.0.1
I have it running here for hours on 50 LEDs (which is 150 channels)
tested with "DMX-Workshop", "Node Managment Utility" and "MADRIX"

The major code changes I made are related to memory consumptions.
either decrease the udp packet size
#define UDP_PACKET_MAX_SIZE 512 // originally was 2048
or decrease the channels number
const int number_of_channels=512; //512 for 512 channels

I also moved the strip.setPixelColor line inside the If "if its an artnet header"
this will make sure that the strip.setPixelColor is not running for every UDP packet arrives.
I will post the whole code once I am sure it is running stable.

My challenge is to send ArtNet DMX data to 1250 WS2801 leds using Arduino+Ethernet shield.
Looking at the current numbers of memory, and having the fact that the Uno could not handle the program once I increased the UDP_PACKET_MAX_SIZE it seems like I must use this program on arduino Mega.