RGB lightsaber

What are you developing?
racemaniac
Posts: 432
Joined: Sat Nov 07, 2015 9:09 am

Re: RGB lightsaber

Post by racemaniac » Sat Jun 10, 2017 10:23 am

RogerClark wrote:Thanks

I've modified the maple port of the Adafruit lib,and it now works OK.

I have also now tried to use SPI, but I'm having problems with the first pixel :-(
i've also had problems with the first pixel, sometimes just adding a pulldown resistor to the pin fixed it. I'd have to check my most recent code, but i think i just added a few bytes with 0's to "flush" the neopixel signal line and that also fixed it.

If you have a logic analyser, have a look at the signal. Ideally when done transmitting, the dataline stays low (as the neopixels require), but it sometimes takes a bit of tinkering to get the spi port to actually do that. If not, you're starting a new byte, and then your first pixel will be getting that junk extra byte

User avatar
RogerClark
Posts: 6719
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: RGB lightsaber

Post by RogerClark » Sat Jun 10, 2017 10:42 am

Thanks

I think I'm doing the same thing you did

Set SPI for DIV 32

then write 100 for a 0 and 110 for a high

So you end up with a buffer which is 9 x larger than the number of pixels, as it takes 3 bits per colour bit.

Strangely its just the Red channel that has problems (i.e the middle channel)

I originally tried a port of the Adafruit lib, which bit bangs the data, but it kept doing very strange things, and when I looked with my logic analyser I found the timing was beyond or at the limit of the spec.
So I re-wrote some of it to use asm "nop"s as delays and improved the code that used BSSR port.

This now works OK, but using SPI and DMA looked like a better solution, so I've written an SPI implementation, and it almost works, but not quite.

The red channel of the first pixel, seems to be shifted so that if I write 0x01 into red I get 0x80 in Green
But only in the first pixel.

I do have a Saleae analyser clone, so I'm now trying to compare the bit banged version, which works with the SPI one that doesn't

racemaniac
Posts: 432
Joined: Sat Nov 07, 2015 9:09 am

Re: RGB lightsaber

Post by racemaniac » Sat Jun 10, 2017 10:44 am

To this post i've attached the code i use to drive neopixels via HAL.
In this code, i've encoded 1 neopixel bit to 4 bits in the spi (3 bits is also possible, but requires a bit more work to convert, and on an stm32f4 i've got enough RAM to not bother).
It means i made a lookup table that converts a byte to an int32 which contains the neopixel signal for that byte :). i think the SPI port is set at ~2Mhz to get it to work.
And in this code you can also see i add an extra 4 bytes containing zeros to flush and to not have the first pixel issue.

I hope this helps you a bit further :)
Attachments
neopixel.c
(3.96 KiB) Downloaded 5 times
neopixel.h
(371 Bytes) Downloaded 4 times

User avatar
RogerClark
Posts: 6719
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: RGB lightsaber

Post by RogerClark » Sat Jun 10, 2017 10:58 am

BTW.

I'm slightly confused about the protocol

Reading the data sheet https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf

The the MS bit is sent first (bit 24 ) then and the bit colour order is Green, Red, Blue so the first bit is the MS it of green

The strange thing is that it looks like each pixel reads in its own data and does not pass that data out, but waits until its data has been locked and then passes all subsequent data to the next pixel (and so on)

So the first pixel that is sent, is the data for the end of the strip where the data is initially input.


The other odd thing that I'm seeing using SPI.dmaSend() is some garbage at the beginning, which doesnt look like my data at all, so I don't know where its coming from.

racemaniac
Posts: 432
Joined: Sat Nov 07, 2015 9:09 am

Re: RGB lightsaber

Post by racemaniac » Sat Jun 10, 2017 11:03 am

RogerClark wrote:BTW.

I'm slightly confused about the protocol

Reading the data sheet https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf

The the MS bit is sent first (bit 24 ) then and the bit colour order is Green, Red, Blue so the first bit is the MS it of green

The strange thing is that it looks like each pixel reads in its own data and does not pass that data out, but waits until its data has been locked and then passes all subsequent data to the next pixel (and so on)

So the first pixel that is sent, is the data for the end of the strip where the data is initially input.


The other odd thing that I'm seeing using SPI.dmaSend() is some garbage at the beginning, which doesnt look like my data at all, so I don't know where its coming from.
hmm, indeed, it should then be the last pixel that's garbled, not the first one. (unless after a pause the first one thinks it's getting a new signal).
and if you have junk with the dmaSend, are you sure your pointer is correct etc... what you're describing vagely reminds me of something, but i don't remember what >_<

User avatar
RogerClark
Posts: 6719
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: RGB lightsaber

Post by RogerClark » Sat Jun 10, 2017 11:46 am

I'm now just sending 1 pixel, of zeros and these are the two traced


This one is the Bit Banged version which works, and the first LED is off
bit_banged.png
bit_banged.png (7.5 KiB) Viewed 133 times

This one is my SPI DMA version, and the first LED is bright green.
SPI_DMA.png
SPI_DMA.png (9.36 KiB) Viewed 133 times
Which implies that the first bit is being read as a 1 not a zero

Looking closely at the timings, the first bit is High for 0.49uS and low for 0.89 us, where are all the subsequent bits are high for 0.44 (or 0.45 uS) and low for 0.88 or 0.89uS.

Even if the first High pulse is 0.49uS this is within the spec for the WS2812B, as the pulse is supposed to be 0.4uS and 0.8uS
(plus or minus 0.15uS) so it would allow up to 0.55uS for the High pulse or as low as 0.25uS

I checked the LEDs on the strip to confirm the are WS2812B not the older type, and they only have 4 pads and have WS2812B written next to them, so they appear to be the newer type
http://rgb-123.com/files/WS2812B_VS_WS2812.pdf

Perhaps I need to do what you suggested and have 1 bye of zeros at the start of the transfer

User avatar
RogerClark
Posts: 6719
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: RGB lightsaber

Post by RogerClark » Sat Jun 10, 2017 11:54 am

Update.

Fixed it.

Made the whole DMA buffer 1 byte longer, and made sure the first byte is zero.

Then adjusted the code so that everything offsets 1 byte after the start of the buffer apart from the dmaSend

Edit.

I'm not sure its completely fixed, as it looks a bit different from the bit banged version, so I'll need to run some more tests, but at least I don't get the huge problem with the first pixel

racemaniac
Posts: 432
Joined: Sat Nov 07, 2015 9:09 am

Re: RGB lightsaber

Post by racemaniac » Sat Jun 10, 2017 12:07 pm

btw, this remains the best reference guide for neopixels for me: https://wp.josh.com/2014/05/13/ws2812-n ... know-them/
it very well explains how they work and which timings are needed :)

User avatar
RogerClark
Posts: 6719
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: RGB lightsaber

Post by RogerClark » Sat Jun 10, 2017 12:18 pm

Thanks.

I think something is still wrong with the green channel, but Hopefully I can fix it.

BTW.
Did you use SPI DMA for your version?

racemaniac
Posts: 432
Joined: Sat Nov 07, 2015 9:09 am

Re: RGB lightsaber

Post by racemaniac » Sat Jun 10, 2017 12:40 pm

RogerClark wrote:Thanks.

I think something is still wrong with the green channel, but Hopefully I can fix it.

BTW.
Did you use SPI DMA for your version?
yup, i'm using spi dma for my lightsaber projects. and i still think it's data at the end of the transmission that corrupts it (probably the first led that gets some garbage that it thinks is part of a new communication attempt, and the garbage data is short enough not to get to the second led)
if it was at the beginning of your signal, you'd need amazing luck to always have it perfectly aligned to 24 bits so it doesn't shift the data of the entire chain.
everything except the sound is running under dma (the sound is running under regular interrupts)

Post Reply