Dotstar (aka APA102) library

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
User avatar
mattyt
Posts: 190
Joined: Mon Jan 23, 2017 6:39 am

Dotstar (aka APA102) library

Post by mattyt » Sun Jan 13, 2019 1:01 am

I've just published the MicroPython DotStar library.

It's a straightforward port of Adafruit's CircuitPython DotStar library. Which was originally a port of a MicroPython Neopixel library - it's come full circle!

Previously APA102 control was only supported via a port-specific module on the ESP8266. This library ought to work on all ports.

The only real change was to strip out the SPI comms from within the CircuitPython driver. Now an SPI object is required to create a DotStar object. (This is a better design anyway IMO)

Code: Select all

spi = SPI(sck=Pin(12), mosi=Pin(13), miso=Pin(18)) # Configure SPI - note: miso is unused
dotstar = DotStar(spi, 1) # Juse one DotStar
dotstar[0] = (128, 0, 0) # Red
Currently the software SPI driver requires all of sck, mosi and miso to be supplied, hence the configuration of miso (Pin 18 is unused). We could - should? - make those parameters optional as there are many SPI devices that only employ one-way comms. Note that hardware SPI may not need all parameters to be set (on the ESP32 with HW SPI you can drop miso).

This hasn't had a lot of testing - I only have DotStar 'strips' of length=1 ;) - so I'd appreciate any feedback!

The pins selected match those used in the TinyPICO in case you're wondering. :)

bill-e
Posts: 4
Joined: Tue Jan 15, 2019 1:38 am

Re: Dotstar (aka APA102) library

Post by bill-e » Tue Jan 15, 2019 1:52 am

I just tried it with 4 APA102 LED's and it appears to be working. Thanks for writing this. It's weird because I just started looking this morning, and it looks like you finished it on Saturday. Good timing! I'll try it with a string of 140 LED's next. I'm using a Huzzah32 board.

Thanks,

bill-e
Posts: 4
Joined: Tue Jan 15, 2019 1:38 am

Re: Dotstar (aka APA102) library

Post by bill-e » Wed Jan 16, 2019 2:45 am

I tried this with a strip of 136 LEDS and it works well. Any tips for making the LED's update more quickly? It takes about 5 seconds for all the LED's to change color in the 136 LED strip.

User avatar
mattyt
Posts: 190
Joined: Mon Jan 23, 2017 6:39 am

Re: Dotstar (aka APA102) library

Post by mattyt » Wed Jan 16, 2019 6:27 am

Thanks for testing this out! Really appreciate it.

First thing to try would be to use hardware SPI if you're not already. I'll need to check the Huzzah32 pinout but some ESP32 pins can support much higher SPI transfer rates; APA102's should be capable of 10's of MHz (the ESP32 can transfer SPI at a max of 40MHz with HW support).

That said the bottleneck may be elsewhere - configuring the buffer with the colour data for example. If this is the case we'll need to implement more of the module in C...

I'm at work at the moment so will need to look into this at a later stage but hopefully that gives you some clues!

OutoftheBOTS_
Posts: 516
Joined: Mon Nov 20, 2017 10:18 am

Re: Dotstar (aka APA102) library

Post by OutoftheBOTS_ » Wed Jan 16, 2019 7:43 am

mattyt wrote:
Wed Jan 16, 2019 6:27 am
Thanks for testing this out! Really appreciate it.

First thing to try would be to use hardware SPI if you're not already. I'll need to check the Huzzah32 pinout but some ESP32 pins can support much higher SPI transfer rates; APA102's should be capable of 10's of MHz (the ESP32 can transfer SPI at a max of 40MHz with HW support).

That said the bottleneck may be elsewhere - configuring the buffer with the colour data for example. If this is the case we'll need to implement more of the module in C...

I'm at work at the moment so will need to look into this at a later stage but hopefully that gives you some clues!
I did originally write an APA102 library for the RPi using SPI all written in Python. I found that I could go as fast as 64Mhz before the LEDs didn't respond anymore. Theatricality you should be able to update strips very fast.

Also do be aware that most of the places that are selling APA102 are in fact not APA102 but the Chinese clone sk9822 which don't perform as well for both updates and saturation in colour. I have compared them side by side and the APA102 r far Superior here's a blog someone wrote about it https://cpldcpu.wordpress.com/2016/12/1 ... he-apa102/

bill-e
Posts: 4
Joined: Tue Jan 15, 2019 1:38 am

Re: Dotstar (aka APA102) library

Post by bill-e » Sun Jan 20, 2019 4:32 am

mattyt wrote:
Wed Jan 16, 2019 6:27 am
Thanks for testing this out! Really appreciate it.

First thing to try would be to use hardware SPI if you're not already. I'll need to check the Huzzah32 pinout but some ESP32 pins can support much higher SPI transfer rates; APA102's should be capable of 10's of MHz (the ESP32 can transfer SPI at a max of 40MHz with HW support).

That said the bottleneck may be elsewhere - configuring the buffer with the colour data for example. If this is the case we'll need to implement more of the module in C...

I'm at work at the moment so will need to look into this at a later stage but hopefully that gives you some clues!
I think I'm using the correct hardware supported pins.

# On-board DotStar for the ESP32
spi = SPI(baudrate=40000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))

You can see the slowness even if you have a small number of LED's by setting the number of LED's to a higher amount like this,

dots = dotstar.DotStar(spi, 136, brightness=.1)

On my board the LED only changes color every few seconds with this many LED's.

User avatar
mattyt
Posts: 190
Joined: Mon Jan 23, 2017 6:39 am

Re: Dotstar (aka APA102) library

Post by mattyt » Sun Jan 20, 2019 4:50 am

Hi Bill,

Thanks for testing that out.

It may be that there is a performance issue in the Python code however I believe that you're still using Software SPI:

Code: Select all

>>> spi = SPI(baudrate=40000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
>>> type(spi)
<class 'SoftSPI'>
If you could please try adding an id:

Code: Select all

>>> spi = SPI(2, baudrate=40000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
>>> type(spi)
<class 'SPI'>
And try again I'd much appreciate it!

Coincidentally I've only just started to document some of the ESP32 SPI interface today...there are a few quirks! Like I said, it may well still be a performance issue in the code but lets rule out SPI first...

bill-e
Posts: 4
Joined: Tue Jan 15, 2019 1:38 am

Re: Dotstar (aka APA102) library

Post by bill-e » Sun Jan 20, 2019 9:59 pm

mattyt wrote:
Sun Jan 20, 2019 4:50 am
Hi Bill,

Thanks for testing that out.

It may be that there is a performance issue in the Python code however I believe that you're still using Software SPI:

Code: Select all

>>> spi = SPI(baudrate=40000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
>>> type(spi)
<class 'SoftSPI'>
If you could please try adding an id:

Code: Select all

>>> spi = SPI(2, baudrate=40000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
>>> type(spi)
<class 'SPI'>
And try again I'd much appreciate it!

Coincidentally I've only just started to document some of the ESP32 SPI interface today...there are a few quirks! Like I said, it may well still be a performance issue in the code but lets rule out SPI first...
Adding the '2' worked! Without specifying the ID of 2 the clock rate was 1.29MHz. This must be the bit banged rate. After specifying an ID of 2 the Baudrate equals what it's programmed to. I verified it at 40MHz and 80MHz using a scope. At 80MHz it takes approximately 1 second to program 3000 LED's. This is a lot faster than what I was seeing before. It would be interesting to see if it could be made to work even faster, but it works well for me.

Thanks,

User avatar
mattyt
Posts: 190
Joined: Mon Jan 23, 2017 6:39 am

Re: Dotstar (aka APA102) library

Post by mattyt » Tue Jan 22, 2019 11:47 pm

bill-e wrote:
Sun Jan 20, 2019 9:59 pm
Adding the '2' worked!
That's great to hear! Glad you got it working.
bill-e wrote:
Sun Jan 20, 2019 9:59 pm
At 80MHz it takes approximately 1 second to program 3000 LED's. This is a lot faster than what I was seeing before. It would be interesting to see if it could be made to work even faster, but it works well for me.
We could record some performance measurements and determine where the time is spent during that update; if it's dominated by modifying the colour buffer then improvements could be made by shifting some functionality into the C world. If it's dominated by SPI comms then I believe there'll be little benefit. Would be interesting to investigate.

Note that Adafruit have started a pixelbuf implementation to improve the performance of their NeoPixel and DotStar implementations on CircuitPython. Details can be found at Neopixel updates are slow and (Large numbers of) Neopixel and Dotstar are slow. It's possible we could leverage some of their good work...

But I'm really happy to hear it's working well enough for you now.

Post Reply