Go Down

Topic: Controlling WS2801 addressable LED Strip with ProMini 5V ATmega328 (Read 2030 times) previous topic - next topic

GoZee

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.

UKHeliBob

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 ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

GoZee

Hi UKHeliBob, thanks for the reply.


Quote
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:
Code: [Select]
//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.


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


Quote
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.  :)


Quote
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.

GoZee


CrossRoads

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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

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.
Code: [Select]

#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?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up