Controlling WS2801 addressable LED Strip with ProMini 5V ATmega328

I bought 5 meter (32/m) WS2801 Addressable RGB LED strip and I want to control it with my ProMini 5V ATmega328. I searched from web and I've done some play with self running color and rainbow colors.

Next, I want to control it more with buttons like : 1st button trigger 5th to 15th Red LED to turn ON in once for 1000ms then OFF, 20th to 30th Green LED turn on in once for 500ms then OFF, 15th to 25th turn ON in once for 1000ms, and all LED turn on in once for 500ms then OFF again, an so on. It's more like a random, but it's not. so I want to decide which group of LED to turn ON for certain millisecond then OFF.

Please help me how to do it and I'm really appreciate for some simple sketch to make that LED shows.

Thank you.

How much do you already know ?

Can you read the state of an input pin and act on its value, for instance ?
Do you know how to turn on an individual LED in the strip with a colour of your choice ?
Do you understand how the BlinkWithoutDelay example works and why it does not use the delay() function ?

Hi UKHeliBob, thanks for the reply.

How much do you already know ?

well, It is my first time controlling the led strip with arduino. As far as I know it runs by clock and data with byte to set when and what color to turn ON.

this is what I've done so far:

//create arrays
int RED[60];
int GREEN[60];
int BLUE[60];
//
//pin map
int clockpin = 2;
int datapin = 3;
//
//setup code
void setup()
{
  pinMode(clockpin, OUTPUT);
  pinMode(datapin, OUTPUT);
  for (int i=0;i<60;i++)
  {
    BLUE[i]=0;
    RED[i]=0;
    GREEN[i]=0;
  }
}
//
void updatestring()
{
  for(int i=0;i<60;i++)
  {
    shiftOut(datapin, clockpin, MSBFIRST, BLUE[i]);
    shiftOut(datapin, clockpin, MSBFIRST, RED[i]);
    shiftOut(datapin, clockpin, MSBFIRST, GREEN[i]);
  }
}
//
void loop()
{
    for(int i=0;i<30;i++)
    {    
      BLUE[i]=0;
      RED[i]=255;
      GREEN[i]=0;
      updatestring();
      //BLUE[i]=0;
      //RED[i]=0;
      //GREEN[i]=0;
      delay(1);
    }

    for(int i=29;i>=0;i--)
    {
      BLUE[i]=0;
      RED[i]=0;
      GREEN[i]=0;
      updatestring();
      BLUE[i]=0;
      RED[i]=0;
      GREEN[i]=0;
      delay(1);
    }

    for(int i=59;i>=30;i--)
    {
      BLUE[i]=255;
      RED[i]=0;
      GREEN[i]=0;
      updatestring();
      //BLUE[i]=0;
      //RED[i]=0;
      //GREEN[i]=0;
      delay(1);
    }

    for(int i=30;i<60;i++)
    {
      BLUE[i]=0;
      RED[i]=0;
      GREEN[i]=0;
      updatestring();
      //BLUE[i]=0;
      //RED[i]=0;
      //GREEN[i]=0;
      delay(1);
    }
}

the result is the reds running forward and backward from 1st LED to 30th LED, then blues running forward and back ward from 30th LED to 60th LED.

next step, I tried to make those two reds and blues running in the same time. Also the other things, instead of running , I'd like to make it to turn reds ON together at once then OFF.

Can you read the state of an input pin and act on its value, for instance ?

No I can't. I don't know how to do it. Which input pin do you mean? from Arduino sides or the strip sides?

Do you know how to turn on an individual LED in the strip with a colour of your choice ?

I know how to set what colour I want, but to turn an individual LED in the strip, that's also my question. :slight_smile:

Do you understand how the BlinkWithoutDelay example works and why it does not use the delay() function ?

I use it a lot with my other projects, but I don't know how to use it here. In one state, I might use it.

I wish this post is not too much for anyone :slight_smile:

So there are 60 WS2801s in this strip?
You need to send 180 bytes (3 per WS2801) out with every update you make. If an LED is not changing, it is okay to send it the same data.
I would use an array of 180 bytes, manipulate that as needed, and then send all 180 bytes when it's time for an update.

That chip will support a 25MHz clock - Arduino can only do 8 MHZ, with SPI.transfer.
I would send the data like this, with the clock line coming from D13/SCK, and the data line coming from D11/MOSI.

#include <SPI.h> //at top of the sketch
byte ledArray[180]; // WS2801 #0 is the farthest from Arduino. WS2810 #179 is closest to Arduino
 // ledArray[0] is WS2801 #0 red, ledArray[1] is WS2801 #0 green, ledArray[2] is WS2801 #0 blue
:
:
 // ledArray[177] is WS2801 #59 red, ledArray[178] is WS2801 #59 green, ledArray[179] is WS2801 #59 blue

SPI.begin();  //in setup()
SPI.divisor(2); // in setup ()  (check the syntax on that)

in loop, after you're manipulated the ledArray data:
for (x=0; x<180; x=x+1){
SPI.transfer(ledArray[x]);
}

Make sense?