Driving WS2812 LED's with PSoC3

A catchall for PSoC3 discussions not captured by the other forums.

Moderator: ericb

Driving WS2812 LED's with PSoC3

Postby Corporate666 » Sat Aug 24, 2013 3:51 pm

So for anyone unfamiliar with these LED's, they are World Semi 2812B LED's which incorporate a constant current driver chip (bare die) inside the LED package itself. The LED has 4 pins... power, ground, data in, data out. The LED accepts a data stream at 800kbps where it reads 24 bits corresponding to 8 bit values for red, green and blue, then after it's sucked up it's 24 bits, it outputs all subsequent bits to the data out line. So you can cascade long strings of these LED's and drive them with a single data pin.

Driving them is the problem though. With a 48Mhz clock, an 800kbps data rate leaves only 60 clock cycles per bit. And the way the WS2812 reads a one or a zero is based on the high time vs. low time on the signal.

The datasheet is here

http://www.mikrocontroller.net/attachme ... minary.pdf

These chips are notoriously picky about timings, too.

I am trying to write a program that drives these suckers, but I don't want to use up all the chip's CPU power to do it (like with bit banging) because I want to be able to do other stuff - like respond to button presses. I am hoping someone can help me formulate a plan for driving these.

My first though was that it would simple to use two 8-bit PWM's, with one being set up with a clock, period and compare value to create the '1' signal, and the other to create the '0' signal, and both set to run in single-shot mode with hardware enable. The PWM that makes the 1 signal would be set for "trigger on rising edge", the other would be set for "trigger on falling edge". Then I would connect the trigger line to a status register, and I could update that register at 800kbps with a DMA. Never used DMA before though, so not sure if that is feasible. But that would take most of the load off the CPU, I think.

Any feedback on the proposed method? Or anyone have an easier idea?

In theory, it's a pretty simple task - just output either a short high/long low or long high/short low depending on a 1 or 0 input. It seems there is probably an easy way to go this with Verilog, which I do not know at all. So I am all ears if anyone has an ingenious solution!

Then I could connect the
Corporate666
Cheese Cube
Cheese Cube
 
Posts: 28
Joined: Tue Aug 17, 2010 10:51 am

Re: Driving WS2812 LED's with PSoC3

Postby bobmarlowe » Sun Aug 25, 2013 2:40 am

The most elegant solution would be to connect a shift-register to a self-made component using VeriLog. An intermediate solution would take ia LUT to count, generate the shift clock and the data by counting to four and setting the output depending on the shifted bit out.
Updating the shift-register at the right time could even be done with DMA, so you do only need a very few CPU cycles intervention to handle the update to the LED-array.


Happy coding
Bob
User avatar
bobmarlowe
The Big Cheese
The Big Cheese
 
Posts: 1490
Joined: Thu Oct 06, 2011 2:03 am
Location: Germany

Re: Driving WS2812 LED's with PSoC3

Postby danadak » Sun Aug 25, 2013 3:00 pm

Datasheet lacking, especially on timing.

You might be able to bit bang the data input if it has a DC limit on
operation. Maybe even use spi module for that purpose.

Regards, Dana.
Field Application Engineer
KB1RHB Mostly listen :)
Semi Retired
User avatar
danadak
The Big Cheese
The Big Cheese
 
Posts: 2008
Joined: Thu Dec 27, 2007 8:42 am
Location: New Hampshire

Re: Driving WS2812 LED's with PSoC3

Postby Corporate666 » Mon Aug 26, 2013 4:38 pm

Bob,

Unfortunately I know absolutely nothing about Verilog, so I think it would be a bit out of my league. I wonder how big a job it is and if there are any "Verilog custom PSoC component" consultants here? If so, please get in touch :)

As for the LUT idea, I am having a hard time visualizing what you are suggesting. How would a LUT generate the correct length high/low ratio for a 1 or 0 output?


Dana,

Yes, the datasheet is pretty crap. The total timing for either a zero or one should be 1.25us, 0.4 high and 0.85 low for zero, and 0.8 high and 0.45 low for one. There is supposed to be 150ns of wiggle room on those timings but the WS2812 chips are notoriously picky about timing so the more accurate the better.

I'm hoping to avoid bit banging because I have quite a lot of other stuff I need to do in the chip, and it would be a nightmare to get the timing perfect when I start adding other interrupts and such, plus from a technical standpoint, I know this shouldn't be too hard to accomplish, it's just my skills that are the (extreme) bottleneck :)
Corporate666
Cheese Cube
Cheese Cube
 
Posts: 28
Joined: Tue Aug 17, 2010 10:51 am

Re: Driving WS2812 LED's with PSoC3

Postby bobmarlowe » Mon Aug 26, 2013 10:30 pm

LUTs, especial the registered version, can easily be used to build state machines. In your case with 3 states (needing a count of 2 bits)
When looking at the given timings you can break the output up to 1 state hi and 2 states lo for a 0 bit and 2 states hi and 1 state lo for a 1 bit.

Given a total time of 1.25µs the clock frequency should be 24MHz which we can archive luckily without any problems.
Use a registered LUT with 3 Inputs (2 actual states and 1 signal-in) and 4 outputs (2 states, 1 generated signal out, 1 clock for the shift register)
Wire the state-outputs to the state inputs and build your truth-table.

Do not hesitate to ask for further help.
Bob
User avatar
bobmarlowe
The Big Cheese
The Big Cheese
 
Posts: 1490
Joined: Thu Oct 06, 2011 2:03 am
Location: Germany

Re: Driving WS2812 LED's with PSoC3

Postby bobmarlowe » Mon Aug 26, 2013 11:54 pm

Normally we do not supply solutions for problems here, but I found the matter to be interesting, so i started a bit (or rather: Byte).
Have a look at the attached project.
Here is the Logic analyzer output:
LEDCtrl.jpg


Bob
Attachments
LED_Controller.cywrk.Archive02.zip
(31.8 KiB) Downloaded 351 times
User avatar
bobmarlowe
The Big Cheese
The Big Cheese
 
Posts: 1490
Joined: Thu Oct 06, 2011 2:03 am
Location: Germany

Re: Driving WS2812 LED's with PSoC3

Postby bobmarlowe » Mon Aug 26, 2013 11:58 pm

I forgot to mention:
I reduced the clock (the LA is a bit slow)
I used a PSoC5 device, so you'll have to change it to your required PSoC3

Bob
User avatar
bobmarlowe
The Big Cheese
The Big Cheese
 
Posts: 1490
Joined: Thu Oct 06, 2011 2:03 am
Location: Germany

Re: Driving WS2812 LED's with PSoC3

Postby danadak » Wed Aug 28, 2013 5:13 am

Keep in mind if interface clks to DC then ISR effects minimal, you would
just keep a flag that indicates routine either has more to do or is finished,
and flags for clking state.

Or turn off ISR activity until burst complete.

In case you run out of HW resources in the design, eg. bit bang solution replacement.

Many ways to skin a cat.... :mrgreen:

Regards, Dana.
Field Application Engineer
KB1RHB Mostly listen :)
Semi Retired
User avatar
danadak
The Big Cheese
The Big Cheese
 
Posts: 2008
Joined: Thu Dec 27, 2007 8:42 am
Location: New Hampshire

Re: Driving WS2812 LED's with PSoC3

Postby Corporate666 » Wed Aug 28, 2013 11:24 pm

Thanks for the replies.

Bob, you are clearly much more advanced in PSoC knowledge than me :) It took me a while to try to figure out what you were doing in your posted project. Thank you for posting it! I understand what you did, but it's never something I would have been able to do myself (or even based on an explanation of what to do).

It always helps me in learning if I can figure stuff out in my own way - so for the purposes of learning to walk before I run... would the following also work?

Two PWM's with their clock frequency, counter and period values set such that one generates the 1.2us "0" pulse and the other generates the "1" pulse. Each PWM set up in single shot mode, hardware trigger on rising edge. Then a LUT with one input and two outputs set such that 1 or 0 on the input triggers the appropriate output which triggers the PWM.

These LED's cascade so the output of one goes to the input of the next - and hundreds can be driven in a single chain. So if I am driving, say, a chain of 300 of them... I could set up a 900 byte frame buffer in memory (3 bytes per for R/G/B) and set up a DMA to incrementally read the frame buffer and transfer it to a control register connected to the input of the LUT at 800kHz.

Would that, or rather, should that work? It seems that would also use few CPU resources to achieve?

I realize I have already gotten a working solution for this, but just trying to see if my idea would also work.







Dana, thank you for the reply. I was thinking about this last night as I was going to sleep (doesn't everyone think about PSoC at bed time?) and it occured to me that the driver chips inside each LED are latching. Duh. I don't know why I didn't realize that earlier. For some reason I thought they needed a constant refreshing signal of 800kHz which would gobble up almost all CPU time. But you are right - even with big banging, I am still only doing that when I need to update the display. Only thing is I have the idea to run 100+ in a chain with some preprogrammed patterns that would reside in memory, many of those programs would be cyclical... so if I could have the data being pushed out from a frame buffer to the chips largely in the background, it would be really really nice.

Not to mention stage 2 would be to be able to drive multiple strings of LED's at the same time. If I can do most of the work in hardware, I could do that much more easily than if I was trying to bit-bang it.

But I may end up using brute force to get a demo going. Is there a no operation command in C (maybe people use nop's for timing on these chips)? I haven't touched assembler in about 25 years, and never for anything other than x86! Or maybe Creator supports inline ASM commands, I bet?
Corporate666
Cheese Cube
Cheese Cube
 
Posts: 28
Joined: Tue Aug 17, 2010 10:51 am

Re: Driving WS2812 LED's with PSoC3

Postby bobmarlowe » Thu Aug 29, 2013 12:03 am

Delays can be made with some pre-defined functions, have a look into "Sytem Reference Guide" to be found under Help -> Documentation->System Reference.

Your approach with the two PWMs and a Multiplexer (a LUT can be programmed to be one) may work as well, Get hands on a logic analyzer and check your signals, a pure "go - no go" may take years to get a result.
Sounds as if you'd like to build a huge color-tv, that will consume a lot of LEDs!! Happy soldering :mrgreen:

DMA will work when properly set up, though this takes some try-and-error, too.

You still need some logic for the "reset" signal which additionally should stop (or reset) the clocks and could be used to reset / start over the DMA

Very interesting project, keep on going
Bob
User avatar
bobmarlowe
The Big Cheese
The Big Cheese
 
Posts: 1490
Joined: Thu Oct 06, 2011 2:03 am
Location: Germany

Re: Driving WS2812 LED's with PSoC3

Postby matt79 » Thu Mar 13, 2014 3:09 am

Rather than jump in the deep end and expecting everything to work immediately, I suggest that you start with the basics.

Get one LED working before getting all of them to work.

If using 5V to power the WS2812B - Make sure the VDD power for the PSoC is set to 5V.

If using 4.3 to power the WS2812B - Set the VDD power for the PSoC to 3.3V.

To use the WS2812B component download the example code from Project #100. I know this works with PSoC Creator 3.0.
User avatar
matt79
Newbie
Newbie
 
Posts: 1
Joined: Wed Mar 12, 2014 7:42 pm
Location: Germany

Re: Driving WS2812 LED's with PSoC3

Postby bobmarlowe » Thu Mar 13, 2014 10:19 am

Matt,
this tread is more than six months old, probably everything is solved already or the initial poster gave up. :mrgreen:

Bob
User avatar
bobmarlowe
The Big Cheese
The Big Cheese
 
Posts: 1490
Joined: Thu Oct 06, 2011 2:03 am
Location: Germany


Return to “%s” PSoC3 General

Who is online

Users browsing this forum: No registered users and 1 guest

cron