Electronics projects and kits Stuff I design and build and take apart


LivingColors / LivingWhites adapter starter set part 2 : adapter


The LivingWhites adapter doesn't really have many surprises. The only two notable things are that the entire high voltage side is from ST parts (VIPER16 , 2 x 14NM65NST1S10 ) and the other surprise is the other LED not in the manual.

The non surprising part is the CC2530 IEEE802.15.4 chip .





Baking Impees


hue lamp teardown

Kasper pointed me to this teardown of the hue led lamp.

The entire lamp is potted, other than that there a no surprises. A CC2530, like any Gen2 / SmartLink / LivingWhites, and some power stuff.

Thanks Kasper !


LivingColors / LivingWhites adapter starter set part 1 : remote

Here is what is inside the LivingAmbiance / SmartLink / LivingWhites (they should really use less of these trademarks) remote


LivingWhites remote pcb

LivingWhites remote pcb


On the left : a TI CC2530 a "Second Generation System-on-Chip Solution for 2.4 GHz IEEE 802.15.4 / RF4CE / ZigBee"

On the right :  a Cypress CY8C2044624 a CapSense controller.

The CC2530 has the 2.4 GHz transmitter and reciever and a microcontroller for the wireless protocol. The Cypress chip handles the buttons and probably the LED's and speaker (the big square on the right). The UX logic can be in any two of the chips.

The PCB has some capsense buttons that are not on the faceplate. I assume the same PCB is used for both the LivingWhites and LivingColors remotes.


Driving multiple SPI RGB LED strips

Red Green Blue, Light Emitting Diode, per pixel controllable strips.

Adafruit and various other vendors sell RGB LED strips with one LPD8806 chip per 2 RGB LED modules. The chips shift in 1 byte per led color (3 per led module) and use 7 bits of the byte to drive the intensity of the LED via PWM. On the other side the chips shift out the bits 6 bytes delayed. 1 meter of these strips has 32 LED's and 16 chips, forming a 384 byte long shift register. One (or more) zero bytes latch the pattern in the strip, eliminating the need to constantly refresh the strip. The chip could use a blog post on it's own.


The single strip examples.

Adafruit have some excellent examples driving one led strip with the arduino SPI. You can scale this solution by daisy chaining strips but there are come complications with this approach. One is that all the power for all strips (1 Ampere per meter or more) will flow through the first strip. The other is that if you want to run strips in parallel you'll need one Arduino per strand. The last problem is that the Arduino is too small and slow to handle large bitmaps by itself and a bit cumbersome as an IO extender.


The teensy solution.

Paul Stoffregen's (of Teensy fame) post on the teensy as a USB byte pump ( http://forums.adafruit.com/viewtopic.php?f=47&t=25854&p=143049#p143049 and http://www.adafruit.com/forums/viewtopic.php?f=47&t=27898&start=0#p143649) showed me the right direction.

In this solution a Teensy is used to drive 8 strips simultaneously. One of the 8 bit ports is used to drive the data pin on 8 led strips, one pin on one other port is used to drive all clock pins. This reduces the number of boards per strand.

Paul's code worked right away (a classic example of loop unrolling, trading code size for execution speed). The only challenge now was to hook it all up and write a example program that creates an image and serializes  it to the teensy.


Teensy and USB

Below is an image of the first USB frame in the led strip image. The time the teensy needs for pushing out one USB frame is 58 us. There are 64 bytes in this frame, driving a little more than 2 columns with 8 leds each.

The byte clock in a frame is about 800 ns. (1.16 MHz), One 64 byte frame takes 56 us. The pause between the frames is 2.8 us. A complete image of 13 (64 byte) usb frames takes about 1 ms.

You can just see the "H", "E" and "L" in the pattern driving the LED strips.

One image in the LED strip

Above is one complete LED strip image, the last block (right) only contains o's and  latches the pattern in the strip. The pauses between the USB frames are caused by the combination of the Teensy USB, the OS USB stack and the Processing application. USB hubs and main board chipsets can  cause additional artifacts.


Pictures and movies

Brightness and dynamic range

The LPD8806 have 7 bits of PWM resolution allowing for 221  (about 2 million) colors. Seems like plenty. The problem is that the LED strips are pretty bright, when the the LED are driven full brightness my eyes and the camera are pretty much blinded. So for indoor use I'm using it at about 10%, effectively killing off 3 of the 7 bits. That explains the posterising you can see in movies below.  The competing chip, the WS2801, has 8 bits PWM resolution and may suffer less from posterising,

Problems, complications and stuff to fix later.

The led strip driver combines 4 parts, each with their own complications and limitations. Theses are :

Java :

Java has different primitive integer types but does ALL operations on those types as if they are ints. As we are working with bytes here (serial stream is a byte stream and the teensy moves bytes from the USB buffer to the port) well need to do a lot of "v & 0xFF" to mask out the unneeded bits and "(byte) x" to cast to a byte.

Also, in Java the byte is signed. For the operations we are doing this doesn't really matter (with one exception below) but the bytes are presented in the debugger and print as signed integers. 0xFF will appear as -1.
Logical bit shifts are of course also done on 32 bit integers. Because the max shift is 32 bits, Java only looks at the lowest 5 bits of the shift amount by masking out the other bits with 0x1F. This also means shifting with negative amounts is not possible.

Finally, because the shift operation is done on an integer and the the integer is signed, we do not want sign extension on the right shift. Use the true binary ">>>" instead of the numerical ">>". In other words, ">>>" shifts the real bits, ">>" keeps the sign as it was.


The maximum packet size USB serial device is 64 bytes. The teensy code is built to only handle complete 64 byte packets. Shorter packets will have to be padded to multiples of 64 bytes.

Teensy :

The teensy waits for a full buffer and the dumps the bytes to a port. The frame timing is determined by the teensy clock frequency and by "nop" instuctions. The timing between the frames is complicated by the USB stack on the host and device, the OS and USB hubs.

The LED strips with LPD8806 :

There is no English datasheet for the LPD8806, some of the documentation is from Adafruit and some information can be figured out from the source code. One of the undocumented issues is the latch pattern, this post says something about it : http://www.adafruit.com/forums/viewtopic.php?f=47&t=27898&start=0#p143649

Better Tag Cloud