Converting code to work with WS2801 RGB LEDs

Hello,

I am attempting to use the code attached for strands of WS2801 LEDs and I’m not sure how to modify the code to work for my LED strand type. What modifications do I need to make to this code for it to be compatible with the WS2801 strands I have (2x WS2801 strands of 25)?

#include <Encoder.h>
#include <Adafruit_NeoPixel.h>

const int NUM_LEDS = 50; // number of leds in strip
const int LED_PIN = 5; // pin for led strip
const int BRIGHTNESS = 255; // brightness of all leds
const int WHEEL_SIZE = 256; // how many entries in the color wheel
const boolean MOVE_LIGHT = false; // move one light around or keep all lights on
const int ENCODER_PIN_1 = 2;
const int ENCODER_PIN_2 = 3;
const int ENCODER_BUTTON = 4;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_RGB + NEO_KHZ800);
Encoder encoder(ENCODER_PIN_1, ENCODER_PIN_2);
int mode = 0;
long lastPush = 0;
int autoPosition = 0;

void initializeToBlack() {
for (int i =0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 0);
}
}

void setup() {
Serial.begin(9600);
pinMode(ENCODER_BUTTON, INPUT);
digitalWrite(ENCODER_BUTTON, HIGH); //turn pullup resistor on

strip.begin();
initializeToBlack();
strip.show();
}

long normalize(long value, long radix) {
long rval = value % radix;
if (rval < 0) return radix + rval;
else return rval;
}

void loop() {
int button= digitalRead(ENCODER_BUTTON);
if (button == 0) {
if ((millis() - lastPush) > 250) {
lastPush = millis();
mode++;
if (mode > 4) mode = 0;
}
}
long knobValue = encoder.read() / 2;

long ledPosition = normalize(knobValue, NUM_LEDS);
long colorValue = normalize(knobValue * 5, WHEEL_SIZE);
long sleepValue = abs(knobValue) % 500;

switch(mode) {
// off
case 0: initializeToBlack();
break;
// knob moves led
case 1: initializeToBlack();
strip.setPixelColor(ledPosition, colorWheel(BRIGHTNESS, colorValue));
break;
// all on, knob makes rainbow
case 2: for (int i =0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, colorWheel(BRIGHTNESS, colorValue));
}
break;
// one auto moving light, knob adjusts speed
case 3:
delay(sleepValue);
initializeToBlack();

strip.setPixelColor(autoPosition, colorWheel(BRIGHTNESS, autoPosition * (WHEEL_SIZE / NUM_LEDS)));
autoPosition++;
if (autoPosition >= NUM_LEDS) {
autoPosition = 0;
}
break;
// slug of rainbow auto moving lights, knob adjusts speed
case 4:
const int SLUG_SIZE = 15;

delay(sleepValue);
initializeToBlack();

for (int i = 0; i < SLUG_SIZE; i++) {
strip.setPixelColor((i + autoPosition) % NUM_LEDS, colorWheel(BRIGHTNESS, i * (WHEEL_SIZE / SLUG_SIZE)));
}

autoPosition++;
if (autoPosition >= NUM_LEDS) {
autoPosition = 0;
}
break;
}
strip.show();
}

// given a wheel position in 0-255 range
// return a rainbow color adjusted by intensity 0 to 1.0
uint32_t colorWheel(float intensity, byte wheelPos)
{
const int WHEEL_THIRD = (WHEEL_SIZE - 1) / 3;

if (intensity < 0.0 ) intensity = 0.0;
if (intensity > 1.0) intensity = 1.0;

// as wheelPos progresses from 0 to 255 once, colorIndex should progress from 0 to 255 3 times
// find out position in current third of wheel then multiple by 3 to get full color value
byte colorIndex = (wheelPos % WHEEL_THIRD) * 3;

int fadeColor = (255 - colorIndex) * intensity; // color going down
int increaseColor = colorIndex * intensity; // color going up

switch (wheelPos / WHEEL_THIRD) {
case 0: // first third of the wheel, red fading, no green, blue increasing
return Adafruit_NeoPixel::Color(fadeColor, 0, increaseColor);
break;
case 1: // second third of the wheel no red, green increasing, blue fading
return Adafruit_NeoPixel::Color(0, increaseColor, fadeColor);
break;

case 2: // last third of the wheel, red increasing, green fading, no blue
return Adafruit_NeoPixel::Color(increaseColor, fadeColor, 0);
break;
}
}

NIGHT_LIGHT.ino (4.04 KB)

Please post your code.
In code tags.

Looks like you don't need to anything but

Confirm the library is compatible and this matches the LEDs you have:

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_RGB + NEO_KHZ800);

and wire the two 25 LED strips to make one strip of 50.

What happens if you run "your" code with one strip hooked up?

a7

BRIGHTNES is defined as 255. You ALWAYS send BRIGHNESS into colorWheel() where anything over 1 is set to 1. You may want to look into that.

-jim lee

When I upload the code as-is, connect the LEDs, and encoder… nothing happens

Perhaps you would share a link to where you found this code.

Also even a hand drawn schematic of how you have it all hooked up, unless you can assure us it is identical to one provided by the author of the code. That you followed.

Have you confirmed that the LED strip is functioning with an simple test program? Google is your friend, here, or look around at Adafruit for some small example code.

a7

Here is the link where I found the code: GitHub - greglarious/rotaryled.

And my wiring is as the instructions show but I'll run through it a few more times to confirm.

When I use the strand test the strips show to be working as expected.

I think you need to specify the ws2801 as a type, and it will need to know the clock pin as well. Does adafruit neopixel support 2801 ? Is the encoder library interrupt based ? if so, you will have reliability issues.

Post the strand test you succeed with.

A bit of googling suggests it uses a different library. If so you'll have to change the library you are using in your program and hope that the functionality of the two is similar if not cross your fingers one-to-one drop in exact.

a7

Does adafruit neopixel support 2801 ?

Let me answer my own question, i don't think it does, but FastLED does, and i think neopixelbus does as well, so yeah you need to switch libraries. Makuna Neopixelbus is more plug and play i think, since it also uses the same way of filling the buffer.

After some research, I’ve added the following code to the Adafruit_WS2801.cpp file:

uint32_t Adafruit_WS2801::Color(uint8_t r, uint8_t g, uint8_t b) {[color=#2e8b57][/color]
  return ((uint32_t)r << 16) | ((uint32_t)g <<  8) | b;[color=#2e8b57][/color]
}

Then, I added this code to the Adafruit_WS2801.h file:

uint32_t[color=#2e8b57][/color]
    Color(uint8_t r, uint8_t g, uint8_t b);

Now when I compile my project code I get the following error:
cannot call member function ‘uint32_t Adafruit_WS2801::Color(uint8_t, uint8_t, uint8_t)’ without object
Do I have to declare the method ‘static’ so it belongs to the Class and not an instance or would that defeat the goal of my intended functionality?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.