WS2811 - Only 9 LEDs on, help with debugging

Hi All,

I have just purchased my arduino, breadboard, cables and WS2811 with the wonderful dream of setting up an ambilight for my desktop. Unfortunately I have run into some issues with controlling the LEDs.

I have copied the code from here: Adalight-FastLED/LEDstream_FastLED.ino at master · dmadison/Adalight-FastLED · GitHub

I have edited the "Num_Leds" and "LED_TYPE", uploaded to the arduino and launched AmbiBox.

The first 9 LEDs are turning on, but the remainder of the strip do not light up.

I have hooked up the strip to the 12V power supply on my PC, and using a multimeter I have checked that I am getting 12V at both ends of the strip (yes, even where the LEDs are turned off)

I have attached a screenshot of the circuit diagram for which I have mostly stuck too, the only real differences being that the ground to the strips is attached to the same end as the power and data, I'm using the D6 pin, and also the fact that I am using 12V supply instead because I am using the WS2811.

I have also attached a photo of the issue - you can't see a whole lot from the photo but it might help. I was wondering if a single broken chip could cause the whole strip to fail, but that would seem strange given that the power is still reaching the other end of the strip.

Any and all ideas are welcome, feel free to ask any questions, thanks in advance!

Ambilight_comp.jpg

circuit.PNG

OK, now let's see your code.

According to the instructions of course.

Here's the code that I've uploaded to the Arduino:

/* LEDstream_FastLED
 * 
 * Modified version of Adalight that uses the FastLED
 * library (http://fastled.io) for driving led strips.
 * 
 * http://github.com/dmadison/Adalight-FastLED
 *
 * --------------------------------------------------------------------
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * --------------------------------------------------------------------
 */

// --- General Settings
static const uint16_t 
	Num_Leds   =  114;        // strip length
static const uint8_t
	Led_Pin    =  6,         // Arduino data output pin
	Brightness =  255;       // maximum brightness

// --- FastLED Setings
#define LED_TYPE     WS2811 // led strip type for FastLED
#define COLOR_ORDER  GBR     // color order for bitbang

// --- Serial Settings
static const unsigned long
	SerialSpeed    = 115200; // serial port speed
static const uint16_t
	SerialTimeout  = 60;     // time before LEDs are shut off if no data (in seconds), 0 to disable

// --- Optional Settings (uncomment to add)
#define SERIAL_FLUSH         // Serial buffer cleared on LED latch
//#define CLEAR_ON_START     // LEDs are cleared on reset
//#define GROUND_PIN 10      // additional grounding pin (optional)
//#define CALIBRATE          // sets all LEDs to the color of the first

// --- Debug Settings (uncomment to add)
//#define DEBUG_LED 13       // toggles the Arduino's built-in LED on header match
//#define DEBUG_FPS 8        // enables a pulse on LED latch

// --------------------------------------------------------------------

#include <FastLED.h>

CRGB leds[Num_Leds];
uint8_t * ledsRaw = (uint8_t *)leds;

// A 'magic word' (along with LED count & checksum) precedes each block
// of LED data; this assists the microcontroller in syncing up with the
// host-side software and properly issuing the latch (host I/O is
// likely buffered, making usleep() unreliable for latch). You may see
// an initial glitchy frame or two until the two come into alignment.
// The magic word can be whatever sequence you like, but each character
// should be unique, and frequent pixel values like 0 and 255 are
// avoided -- fewer false positives. The host software will need to
// generate a compatible header: immediately following the magic word
// are three bytes: a 16-bit count of the number of LEDs (high byte
// first) followed by a simple checksum value (high byte XOR low byte
// XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B,
// where 0 = off and 255 = max brightness.

static const uint8_t magic[] = {
	'A','d','a'};
#define MAGICSIZE  sizeof(magic)

// Check values are header byte # - 1, as they are indexed from 0
#define HICHECK    (MAGICSIZE)
#define LOCHECK    (MAGICSIZE + 1)
#define CHECKSUM   (MAGICSIZE + 2)

enum processModes_t {Header, Data} mode = Header;

static int16_t
	c;
static uint16_t
	outPos;
static uint32_t
	bytesRemaining;
static unsigned long
	t,
	lastByteTime,
	lastAckTime;

// Debug macros initialized
#ifdef DEBUG_LED
	#define ON  1
	#define OFF 0

	#define D_LED(x) do {digitalWrite(DEBUG_LED, x);} while(0)
#else
	#define D_LED(x)
#endif

#ifdef DEBUG_FPS
	#define D_FPS do {digitalWrite(DEBUG_FPS, HIGH); digitalWrite(DEBUG_FPS, LOW);} while (0)
#else
	#define D_FPS
#endif

void setup(){
	#ifdef GROUND_PIN
		pinMode(GROUND_PIN, OUTPUT);
		digitalWrite(GROUND_PIN, LOW);
	#endif

	#ifdef DEBUG_LED
		pinMode(DEBUG_LED, OUTPUT);
		digitalWrite(DEBUG_LED, LOW);
	#endif

	#ifdef DEBUG_FPS
		pinMode(DEBUG_FPS, OUTPUT);
	#endif

	FastLED.addLeds<LED_TYPE, Led_Pin, COLOR_ORDER>(leds, Num_Leds);
	FastLED.setBrightness(Brightness);

	#ifdef CLEAR_ON_START
		FastLED.show();
	#endif

	Serial.begin(SerialSpeed);
	Serial.print("Ada\n"); // Send ACK string to host

	lastByteTime = lastAckTime = millis(); // Set initial counters
}

void loop(){
	adalight();
}

void adalight(){ 
	t = millis(); // Save current time

	// If there is new serial data
	if((c = Serial.read()) >= 0){
		lastByteTime = lastAckTime = t; // Reset timeout counters

		switch(mode) {
			case Header:
				headerMode();
				break;
			case Data:
				dataMode();
				break;
		}
	}
	else {
		// No new data
		timeouts();
	}
}

void headerMode(){
	static uint8_t
		headPos,
		hi, lo, chk;

	if(headPos < MAGICSIZE){
		// Check if magic word matches
		if(c == magic[headPos]) {headPos++;}
		else {headPos = 0;}
	}
	else{
		// Magic word matches! Now verify checksum
		switch(headPos){
			case HICHECK:
				hi = c;
				headPos++;
				break;
			case LOCHECK:
				lo = c;
				headPos++;
				break;
			case CHECKSUM:
				chk = c;
				if(chk == (hi ^ lo ^ 0x55)) {
					// Checksum looks valid. Get 16-bit LED count, add 1
					// (# LEDs is always > 0) and multiply by 3 for R,G,B.
					D_LED(ON);
					bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
					outPos = 0;
					memset(leds, 0, Num_Leds * sizeof(struct CRGB));
					mode = Data; // Proceed to latch wait mode
				}
				headPos = 0; // Reset header position regardless of checksum result
				break;
		}
	}
}

void dataMode(){
	// If LED data is not full
	if (outPos < sizeof(leds)){
		dataSet();
	}
	bytesRemaining--;
 
	if(bytesRemaining == 0) {
		// End of data -- issue latch:
		mode = Header; // Begin next header search
		FastLED.show();
		D_FPS;
		D_LED(OFF);
		#ifdef SERIAL_FLUSH
			serialFlush();
		#endif
	}
}

void dataSet(){
	#ifdef CALIBRATE
		if(outPos < 3)
			ledsRaw[outPos++] = c;
		else{
			ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color
			outPos++;
		}
	#else
		ledsRaw[outPos++] = c; // Issue next byte
	#endif
}

void timeouts(){
	// No data received. If this persists, send an ACK packet
	// to host once every second to alert it to our presence.
	if((t - lastAckTime) >= 1000) {
		Serial.print("Ada\n"); // Send ACK string to host
		lastAckTime = t; // Reset counter

		// If no data received for an extended time, turn off all LEDs.
		if(SerialTimeout != 0 && (t - lastByteTime) >= (uint32_t) SerialTimeout * 1000) {
			memset(leds, 0, Num_Leds * sizeof(struct CRGB)); //filling Led array by zeroes
			FastLED.show();
			mode = Header;
			lastByteTime = t; // Reset counter
		}
	}
}

void serialFlush(){
	while(Serial.available() > 0) {
		byte r = Serial.read();
	}
}

That code will only set the LEDs when it receives a frame of data from serial/usb. Are you sending any data from the pc? If not, those 9 LEDs could just be a random startup pattern.

Try running some of the fastLED example sketches (under file->examples->FastLED in the IDE).

You should have a resistor between the Arduino pin and the strip, value is not critical, 220R to 470R ok. Also a large cap, 470uF or 1000uF, across the power lines, close to the start of the strip.

Post a link to the description of the strip you purchased. Not all ws2811 strips are 12V. If this is a 5V strip, you may have damaged it by connecting 12V. However, looking closely at the strip in your picture I can see one chip for every 3 LEDs, which tells me it is a 12V strip. Did you know that this means you cannot control each led individually, but only groups of 3 LEDs?

Very interesting, I'll try adding some capacitors and see if that helps!

I forgot to mention, ambibox has a few settings, one of which is based on the screen colour, and one of them allows you to send a static colour to the strip. In not too sure however how ambibox really works so I'll see if I can get something working with some of the example sketches.

I got the strips from Amazon, it was these:

So I have tried using one of the default sketches (DemoReel100) and I see the same behaviour of only the first 9 LEDs being illuminated

I just thought of one other thing that might be useful to know, I'm using an Arduino Nano with a CH430 chip, and when I upload sketches I have to make sure to select "ATmega328P (Old Bootloader)". I didn't want to start messing around with bootloaders, but it's probably worth a mention in case it could be affecting anything.

But you see different colours and animations on those 9 LEDs? And you set the pin, strip type and length correctly in the example sketch?

If so, you may be correct about a fault in the strip. The 3rd or 4th chip may be faulty, which means no data flows to the other chips, even though power is available.

If you decide not to return the strip to the seller, and you have soldering iron, wire & solder, then you could cut the strip after the 9th led (where indicated on the strip). Then solder new wires to the remaining strip and test that. If that does not light at all, cut another 3 led section off and test again. The fault could be that the 3rd chip is lighting it's own 3 LEDs but not sending data to the 4th chip. But more likely is that the 4th chip is dead.

Reverate:
I just thought of one other thing that might be useful to know, I'm using an Arduino Nano with a CH430 chip, and when I upload sketches I have to make sure to select "ATmega328P (Old Bootloader)". I didn't want to start messing around with bootloaders, but it's probably worth a mention in case it could be affecting anything.

My Nano are the same, it's not a problem.

PaulRB:
But you see different colours and animations on those 9 LEDs? And you set the pin, strip type and length correctly in the example sketch?

If so, you may be correct about a fault in the strip. The 3rd or 4th chip may be faulty, which means no data flows to the other chips, even though power is available.

If you decide not to return the strip to the seller, and you have soldering iron, wire & solder, then you could cut the strip after the 9th led (where indicated on the strip). Then solder new wires to the remaining strip and test that. If that does not light at all, cut another 3 led section off and test again. The fault could be that the 3rd chip is lighting it's own 3 LEDs but not sending data to the 4th chip. But more likely is that the 4th chip is dead.

Yep, animations are working great on the first 9! Pin, strip type, and length are all set correctly as well.

I was hoping to avoid cutting the strip unless I really needed to but I think at this point it's the only thing I can do. I'll cut it at the 9 LED mark and then see what happens, either the next 9 will turn on (which would be really, really annoying), or what I'm hoping is that all/none of them turn on which would indicate a faulty chip

Will get back to you with an update once it's done!

Num_Leds = 114;

If this is a 12volt strip with 144 LEDs (three LEDs between the cut lines), then you must change this to

Num_Leds = 48;

Because it's not the number of LEDs that counts, but the number of LED driver chips on the strip.
See the last line of post#3.
Leo..

So I am back with good news! I tried cutting of the first 9 LEDs and powering the rest of them and nothing came on, so then I cut of the next 3 and everything lit up beautifully. Must have been a bad chip on that strip.

As for the fact that 1 chip controls all 3 LEDs to be the same colour, I feel like now that I've been told it's going to drive me crazy, but I will be powering through anyway!

Thanks for all the information and suggestions

What you can try now is attaching the remaining LEDs to the end of the first working 9 LEDs. Hopefully the entire chain will then light. If not, that would indicate a fault with chip 3 also, but I expect its probably ok.

Also don't forget that resistor and cap I mentioned. It might be working ok without them now, but for long life and stability, they are a good idea.

Also, you may notice that when the strip is set for every led to be bright white, the LEDs at the far end of the strip are not quite the same colour, with a pink or yellow tint. This is due to voltage drop in the strip itself. It can be cured by running another pair of power wires (good quality thick wire) from the psu to the far end of the strip.

Chip 3 was indeed working correctly, which was good to see.

The white colouring seems to be fairly consistent throughout, there's not a huuuge number of LEDs on there (it's only a 24" monitor) but thanks for the heads up, I'll definitely bear that in mind if i notice some discolouration.

Yeah, I haven't got them in at the moment but I'll pick some up from the hardware store soon - thanks for the reminder! (I think I will be popping down there later today to get some white lining paper to sit behind the screen as the wall is painted blue, and my taped together pieces of A3 could look better)

Reverate:
I'll pick some up from the hardware store ... get some white lining paper

You have a store that sells resistors, capacitors and lining paper? In the UK? What store is that? Since the demise of Maplin, I can't think of any store selling electronic components, except maybe the trade counter of RS components (and in my experience they don't like members of the public wandering in asking for 1 resistor and 1 capacitor...)

So I had assumed B & Q would sell them, but apparently not... I did get hold of some lovely white lining paper though