APA102 led strip - only getting red

I watched this video on how to interface with the led strip and it all seems quite simple.

I have read the data sheet which also seems quite simple.

So I am in the process of writing my own library for this as well.

Mine works as the authors describes in the video, in that the LEDs light sequentially as you input bytes.

Except that I can only seem to get the LEDs to light up red - not sure what I am doing wrong.

Has anyone else played around with these?

APA102LEDStrip.cpp (1.86 KB)

APA102LEDStrip.h (1.26 KB)

Please, please post your code here instead of attaching it. It makes it so much easier to copy into an editor. As the files appear to be your library, how about an example program that shows the problem ?

Sketch

#include <digitalWriteFast.h>
#include <APA102LEDStrip.h>

CAPA102LEDStrip APA102LedStrip(11, 12, 144);

void setup()
{
	Serial.begin(115200);
	APA102LedStrip.begin();
}

int8_t parseInt(String &strCmd, uint8_t& nI)
{
	String strNum;
	int8_t nInt = -1;

	for (nI = nI; nI < strCmd.length(); nI++)
	{
		if ((strCmd[nI] >= '0') && (strCmd[nI] <= '9'))
		{
			strNum += strCmd[nI];
		}
		else
			break;
	}
                
	if (strNum.length() > 0)
		nInt = strNum.toInt();
	else
		nInt = -1;

	return nInt;
}

void getColors(String &strCmd, int8_t &nRed, int8_t &nGreen, int8_t &nBlue)
{
	bool bOK = false;
	uint8_t nI = 1;

	nRed = parseInt(strCmd, nI);
	if (nRed > -1)
	{
		if (strCmd[nI] == ',')
		{
			nGreen = parseInt(strCmd, nI);
			if (nGreen > -1)
			{
				if (strCmd[nI] == ',')
				{
					nBlue = parseInt(strCmd, nI);
					if (nBlue > -1)
					{
						bOK = true;
					}
				}
			}
		}
	}
	if (bOK)
		Serial.println("Invalid command format: cR,G,B where R, G and B are valid positive integers...");
}

void loop()
{
	if (Serial.available())
	{
		String strCmd = Serial.readString();
		int8_t nRed = 0, nGreen = 0, nBlue = 0;
		char cCmd = strCmd[0];

		switch (cCmd)
		{
			case 'b':
			case 'B': APA102LedStrip.sendLEDFrame(0, 0, 255); 
						Serial.println("Blue LED frame sent..."); 
						break;

			case 'g':
			case 'G': APA102LedStrip.sendLEDFrame(0, 255, 0); 
						Serial.println("Green LED frame sent..."); 
						break;

			case 'r':
			case 'R': APA102LedStrip.sendLEDFrame(255, 0, 0); 
						Serial.println("Red LED frame sent..."); 
						break;

			case 's':
			case 'S': APA102LedStrip.sendStartFrame(); 
						Serial.println("Start frame sent..."); 
						break;

			case 'e':
			case 'E': APA102LedStrip.sendEndFrame(); 
						Serial.println("End frame sent..."); 
						break;

			case 'c':
			case 'C': getColors(strCmd, nRed, nGreen, nBlue); 
						APA102LedStrip.sendLEDFrame(nRed, nGreen, nBlue); 
						Serial.print("LED frame sent - ");
						Serial.print("Red = ");
						Serial.print(nRed);
						Serial.print(", Green = ");
						Serial.print(nGreen);
						Serial.print(", Blue = ");
						Serial.print(nBlue);
						Serial.print("...");
						break;
		}
	}
}

Header

#ifndef __APA102LEDStrip_h__
#define __APA102LEDStrip_h__

#include <Arduino.h>

class CAPA102LEDStrip
{
	public:

		// Constructor
		CAPA102LEDStrip(const uint8_t nDataPin, const uint8_t nClockPin, const uint16_t nNumLEDs);

		// Destructor
		~CAPA102LEDStrip();

		// Inistalisation function - must be called in setup()
		void begin();

		// Initializes the I/O lines and sends a "Start Frame" signal to the LED strip.
		// The start frame simply consists of 4 bytes of 0.
		void sendStartFrame();

		// Sends an "End Frame"
		// The number of bytes in the end frame must be half the number of LEDs in the strip.
		void sendEndFrame();

		// Sends the specified color to the LED strip - successive calls to this will result successive LEDs
		// in the LED stip lighting up.
		void sendLEDFrame(const uint8_t nRed, const uint8_t nGreen, const uint8_t nBlue, const uint8_t nGlobalBrightnessSetting = 0x1F/* - fulle brightness*/);

	protected:

		// The clock and data pin numbers
		uint8_t m_nClockPin, m_nDataPin;
		uint16_t m_nNumLEDs;

};

#endif

Source

#include <digitalWriteFast.h>
#include "APA102LEDStrip.h"

// Constructor
CAPA102LEDStrip::CAPA102LEDStrip(const uint8_t nDataPin, const uint8_t nClockPin, const uint16_t nNumLEDs)
{
	m_nClockPin = nDataPin;
	m_nDataPin = nDataPin;
	m_nNumLEDs = nNumLEDs;
}

// Destructor
CAPA102LEDStrip::~CAPA102LEDStrip()
{
	m_nClockPin = 0;
	m_nDataPin = 0;
	m_nNumLEDs = 0;
}

// Inistalisation function - must be called in setup()
void CAPA102LEDStrip::begin()
{
	pinModeFast(m_nClockPin, OUTPUT);
	pinModeFast(m_nDataPin, OUTPUT);
}

// Initializes the I/O lines and sends a "Start Frame" signal to the LED strip.
// The start frame simply consists of 4 bytes of 0.
void CAPA102LEDStrip::sendStartFrame()
{
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, 0); 	
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, 0);	
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, 0);	
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, 0);	
}

// Sends an "End Frame"
// The number of bytes in the end frame must be half the number of LEDs in the strip.
void CAPA102LEDStrip::sendEndFrame()
{
	uint8_t nI = 0, nNumBits = round((float)m_nNumLEDs / 2);

	while (nI < nNumBits)
	{
		shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, 0);
		nI += 8;
	}
}

// Sends the specified color to the LED strip - successive calls to this will result successive LEDs
// in the LED stip lighting up.
void CAPA102LEDStrip::sendLEDFrame(const uint8_t nRed, const uint8_t nGreen, const uint8_t nBlue, const uint8_t nGlobalBrightnessSetting /*= 0x1F* - full brightness*/)
{
	// +---+---+---+---+---+---+---+---+
	// | 1 | 1 | 1 |0/1|0/1|0/1|0/1|0/1|
	// +---+---+---+---+---+---+---+---+
	// Global brightness is 5 bit: 0 - 31
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, nGlobalBrightnessSetting | 0b11100000);
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, nBlue);
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, nGreen);
	shiftOut(m_nDataPin, m_nClockPin, MSBFIRST, nRed);
}

Can you show us the serial debug output?

aarg:
Can you show us the serial debug output?

Start frame sent...
Blue LED frame sent...
Blue LED frame sent...
Blue LED frame sent...
Blue LED frame sent...
Blue LED frame sent...

That is all it outputs at present.

All that happens is this:

  1. You enter 's' to send a start frame to the LED strip as per the datasheet and youtube video
  2. You enter 'b' to send a LED frame with blue at full intensity (FFh, 00h, 00h) or
    You enter 'g' to send a LED frame with green at full intensity (00h, FFh, 00h)or
    You enter 'r' to send a LED frame with red at full intensity (00h, 00h, FFh)
  3. Then you enter 'e' to send an end frame, where it calculates the correct number of bits to send depending on the number of LEDs in the strip, as per the youtube video.

Do you want to see the bytes in hex as they are sent by shiftOut(...)?