Problems with WS2812B and Atmega32U4

Hey,
I have big problems with a NeoPixel on my PCB. The µC is an Atmega32U4 and the NeoPixel is an WS2812B. The pixel seems to work fine and the circuit should be good, but when I use the function to select a color in an if-function the color of the pixel is more green. This itself is not the problem, but when I want to turn it off, all colors are gone but green stays. If I do the same in e.g. the setup or the loop it is working.
The Values for R G B are sent from a mobilephone via usb in serial connection and this is working. I´m also getting R == 0, G == 0, B==0 but like I said the pixel stays green...

I hope you can help me..
I need this for a schoolproject and I only have time till thursday...

Greetings from bavaria !!

#include <Adafruit_NeoPixel.h>

#include <IRremote.h>

//IR
IRsend irsend;
int number = 0;
const int sendingPin = 3;

//LEDs
int LEDs[8]{ 15,14,13,12,11,10,9,8 };

//Neopixel 
#define PIN 17
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);


//Serial
byte buffer[4] = {0,0,0,0};
int starttime = 0;

//Temperature
const long interval = 1000;           //interval of the temperaturechecks
const int checkingNumber = 5;         //number of checks
const int ntc = A5;                   //analogRead-pin
const int ntcNominal = 15000;         //resistance at e.g 25°C
const int tempNominal = 25;           //nominaltemperature (e.g. 25°C)
const int bCoefficient = 3528;        //Beta Coefficient(B25 from the datasheet of the NTC)
const int serialResistor = 10000;     //value of the serial resistor
									  
int checks[checkingNumber];           //array variable for averaging the temperatur
float averageValue = 0;               //variable for averaging the temperature
float temp;                           //variable for calculation (Steinhart)
float lastTemp;
unsigned long lastTempCheck = 0;      //saves time of last temperaturemeasurement
int lastTempUpdate = 0;

void setup()
{
	Serial.begin(9600);

 //LEDs
	for (int i = 0; i < 8; i++) {
		pinMode(LEDs[i], OUTPUT);
	}

 //NTC
	pinMode(ntc, INPUT); 
           
 //Neopixel
	strip.begin();
	strip.show();	
}

void loop()
{
	temperature();
	serialInterface();
}

void serialInterface() {
	if (Serial.available() > 0) {
		while (Serial.available() < 4 && ((millis() - starttime) < 1000)) {}

		for (int n = 0; n < 4; n++) { buffer[n] = Serial.read(); }

		//send temperature to FP
		int timeNow = millis();
		if (timeNow - lastTempUpdate > 2000) {
			Serial.println((int)temp);
			lastTempUpdate = millis();
		}
		
		switch (buffer[0]) {
		case 1:
			IRremote();
			break;
			//LED-Light
		case 2:
			lightLED();
			break;
			//RGB
		case 3:
			neoPixel();	
			break;
		}
	}
}

//lights up the 8 LEDs attached to the GPIOs
void lightLED() {
	for (int i = 0; i <= 7; i++) {
		digitalWrite(LEDs[i], bitRead(buffer[1], i));
	}
}

//lights up the Neopixel 
void neoPixel() {
	strip.setPixelColor(0, buffer[1], buffer[2], buffer[3]);
	strip.show();
	delay(10);
}

//sends signal via IR-LED
void IRremote() {
	//sending selected hex-code
	switch (buffer[1]) {
	// ON
	case 1:
		irsend.sendNEC(0xFFB04F, 32);
		break;
	// OFF
	case 2:
		irsend.sendNEC(0xFFF807, 32);
		break;
	// RED
	case 3:
		irsend.sendNEC(0xFF9867, 32);
		break;
	// GREEN
	case 4:
		irsend.sendNEC(0xFFD827, 32);
		break;
	// BLUE
	case 5:
		irsend.sendNEC(0xFF8877, 32);
		break;
	}
}

//checking the NTC and sending temperature to the FP
void temperature() {
	int timeNow = millis();
	if (timeNow - lastTempCheck > 100) {
		//N readouts with a short delay
		for (int i = 0; i < checkingNumber; i++)
		{
			checks[i] = analogRead(ntc);
			delay(10);
		}

//averaging of the measured values
		averageValue = 0;
		for (int i = 0; i < checkingNumber; i++)
		{
			averageValue += checks[i];
		}
		averageValue /= checkingNumber;

//transform measured value (voltage) into resistance
		averageValue = 1023 / averageValue - 1;
		averageValue = serialResistor / averageValue;

//convert measured results 
		temp = averageValue / ntcNominal;     // (R/Ro)
		temp = log(temp);                     // ln(R/Ro)
		temp /= bCoefficient;                 // 1/B * ln(R/Ro)
		temp += 1.0 / (tempNominal + 273.15); // + (1/To)
		temp = 1.0 / temp;                    // invert
		temp -= 273.15;
		lastTempCheck = timeNow;
		lastTemp = temp;
	}
}

First off well done for posting your code correctly on your first post.

The problem is that you have such a lot going on here that there are many things that could be wrong. You need to do some debugging to narrow down the area of error.

If this were me I would do the following.
First write or run a sketch that just changed the Neopixels so you can rule out any hardware issue.

Next use some Serial.print statements to look at the values you are giving to the Neopixels and check that they are what you expect. Then given that information you can track down where about in the chain of things happening things start to go wrong.

If you get stuck post your code again, with the debug prints and results.

Good luck

Thanks for your reply!!

The pixel is working nice and I also can turn it off e.g.in the setup...
I did allready a lot off debugging ...
The RGB-values are also extracted correctly from the argb-value (printed on serial monitor)...

void loop()
{
	//temperature();
	serialInterface();
	//sendTemp();
	//control();
	if (buffer[0] == 0) {
		return;
	}
	//IRremote
	if (buffer[0] == 1) {
		//IRremote();
		return;
	}
	//LEDs
	if (buffer[0] == 2) {
		//lightLED();
		return;
	}
	if (buffer[0] == 3 && (buffer[1] > 0 || buffer[2] > 0 || buffer[3] > 0)) {
		uint8_t r = buffer[1];
		uint8_t g = buffer[2];
		uint8_t b = buffer[3];
		strip.setPixelColor(PIXEL, r, g, b);
		delay(10);
		strip.show();
		return;
	}
	
	strip.setPixelColor(0, 0, 0, 0);
	delay(10);
	strip.show();
	
}

In this version the off works but in normal use of the ws2812b i also have the green allways on..

It really seems that the if is causing the problem...
Could it be that the pin i´m using is the problem ?
I´m using D17 or physical pin 8 on the atmega which is also called ss..

Could it be that the pin i´m using is the problem ?

No.

The RGB-values are also extracted correctly from the argb-value (printed on serial monitor)...

Can’t see any serial printing in that code?

I did the serial printing ..
Values are correct ..
I die also a debug oft the APP and also there I tot good values..

I managed to do the method without a if around the neopixel-control and this killed the problem..
Still crazy but working.. :slight_smile:

Thanks for your help !!
Have a nice weekend !!