How fast can an output pin be toggled?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
mpymike
Posts: 10
Joined: Mon May 26, 2014 5:48 am

How fast can an output pin be toggled?

Post by mpymike » Mon May 26, 2014 6:14 am

Just got my board a couple of days ago, awesome!

I'm now trying to find a way to use it to control a strip of WS2812 serial LEDs http://www.mikrocontroller.net/attachme ... minary.pdf
These need a stream of digital pulses to control the intensity of each of the RGB LEDs. With a pulse width varying from 0.4us for a 0, and 0.85us for a 1, and a period of 1.25us.
This is a struggle on most uC. I was wondering what is the best that the uPy board can do.

If I toggle the output in Python using

while 1:
pyb.Pin('X1').value(1)
pyb.Pin('X1').value(0)

I get a period of 25us. Is this the best that can be done in straight python?
Is it likely to improve in future releases?

I guess I should get down and dirty with the assembly code for any substantial speedup.

cheers

-mike

User avatar
dhylands
Posts: 3482
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: How fast can an output pin be toggled?

Post by dhylands » Mon May 26, 2014 4:15 pm

mpymike wrote:while 1:
pyb.Pin('X1').value(1)
pyb.Pin('X1').value(0)
I would try rewriting it as:

Code: Select all

pin = pyb.Pin('X1')
while 1:
    pin.value(1)
    pin.value(0)
Now, if we look at your requirements, pulses that are 0.4usec and 0.85 usec. 0.4 usec is only 67 clock cycles, given that the processor is running at 168 MHz.

I would be inclined to try and figure out how I could use the hardware to generate the pulses for me, rather than trying to "bit bang" them directly.

fma
Posts: 163
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: How fast can an output pin be toggled?

Post by fma » Mon May 26, 2014 4:21 pm

I would also love to control such leds! Here is the answers I got here for such project:

https://groups.google.com/forum/#!topic ... wVhsdV5vdU

To improve the speed, you could try the different code emitters:

https://www.kickstarter.com/projects/21 ... sts/664832
Frédéric

User avatar
dhylands
Posts: 3482
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: How fast can an output pin be toggled?

Post by dhylands » Mon May 26, 2014 4:54 pm

Looking at the datasheet, you could think of the data going to the LEDs as a serial data stream, where you send one of 2 possible bit sequences.

The total of the sequences needs to be 1.25 usecs. If we were to divide this into 8, then we would have "bit times" which are 0.15625 usecs long.

3 bit times = 0.46 usec and 5 bit times = 0.78. The spec says that the pulse widths are all +/- 150 nsecs or 0.15 usecs.

So you could setup the SPI to have a clock of 6.4 MHz, which gives a bit time of 0.15625 usecs.
You could then populate memory with an 8-bit value of 0b11100000 = 0xE0 for a zero or 0b11111000 = 0xF8 for a one, and use DMA to feed the values to the SPI.

This would give you a nice clean output (on the MOSI pin) with no jitter, and you wouldn't have delays caused by interrupts or garbage collection or anything else.

fma
Posts: 163
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: How fast can an output pin be toggled?

Post by fma » Mon May 26, 2014 5:08 pm

Hope someone will write a nice pyb.DMA object :mrgreen:
Frédéric

mpymike
Posts: 10
Joined: Mon May 26, 2014 5:48 am

Re: How fast can an output pin be toggled?

Post by mpymike » Mon May 26, 2014 7:13 pm

Thanks for the replies. It looks like the best solution is to use the SPI peripheral.
I agree bit banging is not very efficient. I was looking for an easier solution.

I didn't know about the 3 different code emitters. I tried the @micropython.native and @micropython.viper
decorators but did they did not work.

-mike

kobaan
Posts: 1
Joined: Mon May 26, 2014 9:28 pm

Re: How fast can an output pin be toggled?

Post by kobaan » Mon May 26, 2014 9:31 pm

There is an approach with DMA on the STM32 here, maybe this could lead to a native micropython library for the ws2812 ?

https://github.com/Torrentula/STM32F1-w ... ect/WS2812

User avatar
dhylands
Posts: 3482
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: How fast can an output pin be toggled?

Post by dhylands » Mon May 26, 2014 11:20 pm

Neat - that's basically using PWM (generated by a timer) and using DMA to change the duty cycle.

mpymike
Posts: 10
Joined: Mon May 26, 2014 5:48 am

Re: How fast can an output pin be toggled?

Post by mpymike » Tue May 27, 2014 3:54 am

With this design the DMA feeds the timer with a stream of pulse width values.
The size of the buffer holding these values is given by:

Code: Select all

 * The buffer size can be calculated as follows:
 * number of LEDs * 24 bytes + 42 bytes
This is a bit wasteful imo.

Using a bit banging assembler solution it can be done with only LEDs * 3 bytes.
This matters when you want to drive large numbers of LEDs
such as a billboard.

The other issue with this DMA solution is that it is blocking.
Once the DMA is started it waits until it completes before returning from
the WS2812_send function.

-mike

fma
Posts: 163
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: How fast can an output pin be toggled?

Post by fma » Tue May 27, 2014 5:10 am

Is it a DMA limitation, or only on the current implementation?
Frédéric

Post Reply