Page 1 of 1

PL9823 RGB led

Posted: Tue Feb 25, 2025 10:13 pm
by geologic
Hi all

Has anyone successfully put stm32 to work with PL9823 RGB leds?
I'm using Adafruit neopixel library without success, i can only see my led turning blue and nothing else.
Here's my code, it should blink blue, green, red

Code: Select all

#include <Adafruit_NeoPixel.h>

#define PIN       PA12
#define NUMPIXELS 1

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ400);		// also tried this, didn't work
#define DELAYVAL 1500

void setup() {
  Serial.begin(9600);
  Serial.println("RGB LED Test");
  pixels.begin();
  pixels.show();
  pixels.setBrightness(128);
}

void loop() {

  Serial.println("BLUE");
  pixels.clear();
  for(int i=0; i<NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));
    pixels.show();
    delay(DELAYVAL);
  }

  Serial.println("GREEN");
  pixels.clear();
  for(int i=0; i<NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 255, 0));
    pixels.show();
    delay(DELAYVAL);
  }

  Serial.println("RED");
  pixels.clear();
  for(int i=0; i<NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));         
    pixels.show();
    delay(DELAYVAL);
  }

}

Re: PL9823 RGB led

Posted: Wed Feb 26, 2025 5:16 am
by fpiSTM
I don't think the Adafruit Neopixel library is for this kind of RGB LED. It is for single-wire LED pixels (NeoPixel, WS2812, etc.)
I've made a dedicated library to drive a specific RGB LED but don't think it is compatible with the one you used as the LED is drived by dedicated component TLC59731:
https://github.com/stm32duino/Arduino_C ... D_TLC59731

Re: PL9823 RGB led

Posted: Wed Feb 26, 2025 1:18 pm
by ozcar
I see some suppliers of these LEDs claim that they are compatible with WS2812, which the Adafruit library does support. However from the datasheet I could find, the timing appears to be different - 588kHz. There is some tolerance in that, but 400kHz would be too low, and 800kHz too high. You could modify the library to change the frequency if necessary though.

The datasheet does not give any specification for the logic voltage levels. These sort of LEDs are typically run on 5V (the datasheet does go so far as to give range of 4.5V to 6V for supply voltage). For other similar LEDs, there can be problems when driving them from a 3.3V processor, without level conversion.

Finally I saw somebody posted a similar problem elsewhere (not using an STM32 processor), and it turned out that the supplier had sent non-pixel LEDS (ie ordinary RGB LEDs with one common pin, plus three pins for R G and B).

Re: PL9823 RGB led

Posted: Wed Feb 26, 2025 3:52 pm
by geologic
Thanks guys for your answers.

I had a 500ohm resistor in the data line, i remove it and using

Code: Select all

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ400)
it works but with erronious behavior. Issuing a red color it shows green, blue color does not show and green color shows as purple.
I guess it has to do with the timing @ozcar mentioned.

I tried a WS2812B led and it works but also with some problems. Red does not show if i use pixels.Color(255, 0, 0), i have to lower the value to pixels.Color(250, 0, 0) to show a red color.

After searching on the forum i saw some issues with WS2812B leds on STM32, so is there any addrressable led + stm32 library that works?

Re: PL9823 RGB led

Posted: Wed Feb 26, 2025 11:44 pm
by ozcar
Did you at least check that the "PL9823" that you got was not just an ordinary RGB LED. You might be able to do that with a meter, or with just a resistor and power supply.

Looking at this again today, I'm not convinced that the timing for the PL9823 really is different, despite what is in the datasheet that I found (which is at https://cdn.instructables.com/ORIG/FW0/ ... DUL683.pdf ).
That says "Internal frequency up to 800KHz" but I'm not sure how useful that is - what do they mean by "internal", and "up to" is a bit vague. In any event, the "Timing waveform" section shows the cycle time is 0.35μs + 1.36μs (or 1.36μs+ 0.35μs) for a total of 1.71μs which comes out near enough to 585kHz (I used a slightly wrong figure of 1.35μs in my calculation yesterday to come up with 588kHz). Not only is the overall speed different, but the 0 and 1 bit timing ratios are different too (1/5 and 4/5, rather than the 1/3 and 2/3 of the WS2812B).

According to this bloke the PL9823 (also called PD9823) is a WS2812 clone: https://cpldcpu.com/2014/06/16/timing-o ... es-pd9823/

Basically he says that the timing given in the "datasheet", (and he has a copy of it there), is rubbish. I'm inclined to believe him, as he did some interesting tests on pixel LEDs. Years ago I used his library but only on AVR ATMEGA. Last I saw he did have some support for STM32, but called that experimental.

I looked at the Adafruit library several years ago. The timing was a bit out from what they were trying to achieve, and that might or might not cause some trouble: viewtopic.php?p=3345&sid=0704a6342ff769 ... 257f#p3345

You could try tweaking the timing in Adafruit_NeoPixel.cpp, but that will be easier if you have some way of checking the actual timing you are getting. I did at one time think of getting another STM32 processor (or perhaps even the same processor that is driving the LEDs) to check the timing, but I never got around to doing that.

P.S.
You did not mention what voltage you are running the LEDs on.

Re: PL9823 RGB led

Posted: Fri Feb 28, 2025 12:06 am
by geologic
I put my multimeter on diode test position and checked every pin, always showing infinite value. The only moment i see some readings was with the negative probe on the 3rd pin (counting from the flat side) and the positive probe on the others. Apparently could be a RGB led, being the 3rd leg the common ground and the other legs each anode. I applied 5V trough a 500ohm resistor but nothing append. PL9823 Datasheet says that 3rd pin is VCC, so probably i was measuring some reverse protection circuit (?).
On the other hand, if i put a 500ohm resistor on the data line, i see diminish light, and that should not happen on a PL9823/WS2812 led.
Don't know what to say...

My original test were made with a 5V external source on the led and common ground between led and STM32. First i tried a custom STM32 board @ 3V3, but also tried with a nucleo64 @ 5V with the same results. Some blue light on start and wrong colors after.

I saw someone using PL9823 with adafruit library on a arduino but i don't have any arduino laying around to do more tests. I also tried Fastled library (that has support for PL9823) but does not compile on STM32.

I'm running out of ideas, maybe i'll go for a RGB led, but that will cost me PWM 3 pins...

Thank you guys for your help.

Re: PL9823 RGB led

Posted: Fri Feb 28, 2025 6:52 am
by ozcar
The diode test on my multimeter provides sufficient voltage to light up the any of the diodes in an ordinary RGB LED, but it only recognises the red one as a diode (due to lower forward-voltage for the red). Of course you'd have to try each way around as you can't be sure if it would be common-cathode or common-anode. But, from the sound of it, it is probably not an ordinary RGB LED - that was always going to be a long shot.

Unfortunately I don't think you have eliminated all the possibilities. For similar LEDs where the makers do provide full information, they often give the minimum logic level "1" voltage as 0.7 times the LED supply voltage, and 0.7 times 5 is 3.5V so straight away there you would be out of spec. You might get away with that, but maybe you won't. To be sure you'd have to do level conversion on the data line. You could try running the LED on 4.5V instead of 5V (so that the threshold to read the data as "1" is reduced), and see if that makes any difference. Going below 4.5V would be taking the supply voltage "out of spec" for the PL9823 and again you might get away with that, and you might not).

Did you add a decoupling capacitor on the LED supply as recommended?

If Fastled is known to work, maybe there is a problem with the timing too. I looked at Fastled, and for PL9823 they have used the exact values as specified in that datasheet that I found.

That is:
zero bit = 350ns high, followed by 1360ns low, and
one bit = 1360ns high, followed by 350ns low.

I tested Fastled on a 16MHz Arduino Nano, and they get pretty close to those values (376/1376 and 1376/350 respectively). Of course, I don't have one of those LEDs to see if it really works.

To properly add a new LED type to the Adafruit library would be quite a chore, but for a test you could just change the timing for say the existing 800kHz LEDs (and only for STM32, you don't have to do it for all the other processors/boards that they support). If you want to try that, look for this in Adafruit_NeoPixel.cpp:

Code: Select all

#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32)
  uint8_t *p = pixels, *end = p + numBytes, pix = *p++, mask = 0x80;
  uint32_t cyc;
  uint32_t saveLoad = SysTick->LOAD, saveVal = SysTick->VAL;
#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
  if (is800KHz) {
#endif
    uint32_t top = (F_CPU / 800000);       // 1.25µs
    uint32_t t0 = top - (F_CPU / 2500000); // 0.4µs
    uint32_t t1 = top - (F_CPU / 1250000); // 0.8µs
...
It is the last three lines there that need to change. The timing there is what they aim for obviously, the actual times they achieve can be a bit different, but hopefully are close enough for a start (I've done some tests on a few different STM32 processors).

What STM32 processor are you using?