how to driver HD108 LEDs

Hi everyone, Newstar has a new chip with the same footprint as the APA102/APA107/HD107s. The special thing about it is: it can do 16 bit per channel! It is also superior to the (already pretty great) APA102 in two other ways: it has 27KHz PWM and it undestands 3.0V as logic level “HIGH”, so you could drive it at 5V and have 3.3V logic voltage without any tricks.

16bit is probably a major change to FastLED, but I think it would be amazing to support this chip.

A datasheet can be obtained here:
http://newstar-ledstrip.com/product/20220705143016452.pdf (look for NS108/HD108)

The protocol is very straightforward and looks very much like the APA102-style protocols with the only change being the amount of bits sent:

  • overall: 128bits 0 are the start frame
  • 64 bits per LED:
    • 1 bit 1
    • 15 bits gain adjustment (5 bit per channel, table in the datasheet)
    • 16 bits green
    • 16 bits red
    • 16 bits blue
  • overall: 1bit 1 per led to end the frame (i.e.: 300 leds connected? send 300 bits)

what’s the benefit of 16bits? are the extra colors obvious?

  • Say you run your leds at a global brightness 32 . That means with the current 8 bit leds you only have 32 brightness steps per color left. (without temporal flickering erh dithering). Going to 16 bit would give you 32*256 = 8192 steps.

To see the benefits of higher then 8 bit control, see the product: https://www.lumiflow.nl/lumiflow-flower-video/, you can’t make subtle fade outs on lower brightness. For disco/blink like effects it doesn’t matter and 8 bit is fine, but for smooth and slow changes 16bit is needed.

Here’s code that I got running with bare SPI transactions on an arduino — it demonstrates all of the fields of the SPI transactions and how they’re packed.

#include <SPI.h>
// Clock and data pins are whatever are SPI defaults for your board (SCK, MOSI)
// Arduino Mega 2560, Clock 52, Data 51
void setup() {
  SPI.begin();
}
void loop() {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
  // Start frame
  for (int i = 0; i <= 4; i++) {SPI.transfer16(0);}
  // LEDs
  for (int i = 0; i <= 72 * 5; i++) {
    // LED frame
    SPI.transfer(0xFF);  // Start of LED Frame & Brightness
    SPI.transfer(0xFF);  // as (1)(5bit)(5bit)(5bit) brightnesses
    SPI.transfer16(i);  // RED (16-bit)
    SPI.transfer16(i);  // GREEN (16-bit)
    SPI.transfer16(i);  // BLUE (16-bit)
  }
  // End Frame
  for (int i = 0; i <= 4; i++) {SPI.transfer16(0xFFFF);}
  SPI.endTransaction();

  delay(100);
}

Share this post