Makuna / NeoPixelBus

An Arduino NeoPixel support library supporting a large variety of individually addressable LEDs. Please refer to the Wiki for more details. Please use the GitHub Discussions to ask questions as the GitHub Issues feature is used for bug tracking.
GNU Lesser General Public License v3.0
1.18k stars 264 forks source link

Using both UART0 and UART1 in parallel on ESP8266 #211

Closed igorkofman closed 5 years ago

igorkofman commented 6 years ago

This is half feature request and half question about feasibility. If it's a reasonable idea, I'm happy to take a pass at implementing, but wanted to sanity check before digging in too much. Would it be worthwhile/possible to use both of the UART modules on the ESP8266 to output in parallel? I am trying to achieve a 30FPS+ framerate writing to 1500 WS2812s.

It seems like it should be possible but I don't know whether this would leave enough time for the WIFI stack to run. Any insights?

(using uart+dma could be an option thought I currently have a bunch of Huzzah boards so dma is out)

Makuna commented 6 years ago

questions are best asked on the gitter channel, not as an issue.

A) It will still have only one pin to select from DMA => Pin 3 Uart1 => Pin 2 Uart0 => Pin 1

B) You will loose all debug capability as the Serial will not be usable with it

C) You will still have to manage the two seperate busses to split your data across. I have played with how to do this, but nothing has ever been shared; but its not hard to manage yourself.

It seems like it should work. I glanced at the files, it will take a bit of refactoring to get it right. If you glance at the "NeoEsp32I2sMethodBase.h" file you will see how the NeoEsp32I2sBusZero and NeoEsp32I2sBusOne are handled and how they get exposed as NeoEsp32I2s0*Method and NeoEsp32I2s1*Method methods. This is the model to follow to refactor the code.

Makuna commented 6 years ago

If you want to just hack it (swap the UART1 stuff with UART0 locally) and confirm it works for you, I can later refactor to support both.

igorkofman commented 6 years ago

Figured since it's an feature request :). Thanks for the pointer, I didn't know about the gitter.

A) Not sure I follow. I'd be able to use Pin1 and Pin2 for this right? B) Yeah, I suspect I'll mostly run without it why developing and only turn it on "in production". I also have a handy UDP based tracing setup that I've been using. Paired with OTA it's pretty magical. C) Thanks for the pointers - I'll take a look!

Makuna commented 6 years ago

My little graph of the pins should be interpreted to mean, each of the methods can only use the single pin assigned to that functionality. If you use two different methods, then you have two pins, but only the ones assigned to the method. The hardware on the Esp8266 is limited on pin assignments.

igorkofman commented 6 years ago

Apologies for the delay. Finally had a chance to come back to this aspect of the project. I can confirm that I got neopixels working smoothly using UART0 on the Adafruit Huzzah breakout!

Makuna commented 6 years ago

Using Pin1? This is great news.

igorkofman commented 6 years ago

Yep pin1 - the TX pin on the breakout.

igorkofman commented 6 years ago

typo fixed ^

igorkofman commented 6 years ago

I'll await a patch to try out, but if you don't think you'll get to it in the next couple of weeks lmk and I'll give it a try myself! Seems like the trickiest part is probably the interrupt handler since it's shared between the two.

igorkofman commented 6 years ago

Any idea if/when you will have time to take a look? Excited to try this!

On Monday, July 23, 2018, Michael Miller notifications@github.com wrote:

Using Pin1? This is great news.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Makuna/NeoPixelBus/issues/211#issuecomment-407279043, or mute the thread https://github.com/notifications/unsubscribe-auth/AAcrQrC4B2HGVuD_VCHAvXghC_35-ZI3ks5uJqVrgaJpZM4U-XMW .

Makuna commented 6 years ago

Maybe in a few weeks

igorkofman commented 6 years ago

https://github.com/igorkofman/NeoPixelBus/commit/027572e7b5512cd5e1bfdf83f26d2c75d630384e

Seems to work! There's a few things that still need touching up for them to be used at the same time, but almost there I think. What is the reason for:

if (READ_PERI_REG(UART_INT_ST(UART0)))
{
    // TODO: gdbstub uses the interrupt of UART0, but there is no way to call its
    // interrupt handler gdbstub_uart_hdlr since it's static.
    WRITE_PERI_REG(UART_INT_CLR(UART0), 0xffff);
}
igorkofman commented 6 years ago

(Specifically, after a glance at the docs, I'm not clear on the behavior when registering multiple UART interrupt handlers and why it's important to clear the status for other UART here.)

igorkofman commented 6 years ago

Can there only be a single handler registered and it is responsible for handling both channel? Or can you have two?

igorkofman commented 6 years ago

Update: parallel output is working with a shared interrupt handler and seemingly stable wifi (though I haven't left it for very long yet or taxed it with lots of data).

Stats:

igorkofman commented 6 years ago

A little refactoring (not branching on the uartNo so often) took me down to 132ms/s to write to 1440pixels in parallel. I pushed the updated patch (including a cheesy hack for gathering telemetry). Will work on cleaning it up but lmk if you have any thoughts on how you want to see it structured (or feel free to take over).

Makuna commented 6 years ago

I am on holiday for another few days, I will check it out when I return. Thanks for the work.

Benik3 commented 5 years ago

Hello. How it looks with using UART0 and UART1 at the same time? I would like to try to use esp8266 for Adalight (Ambilight) to get WS2812 LEDs showing without interrupting the data on the serial line. Thank you

Makuna commented 5 years ago

@Benik3 You can do this now, but note that you need to manage the two separate Buses, as there is currently no common interface to make them act like one strip.
It shouldn't be to much work to use two busses, first half of data to one, second half of the data to the other. Then call Show on both. I am still investigating how to handle multi-bus in a general way so other platforms can use it.

Benik3 commented 5 years ago

I don't know if we understood properly. I want to use UART0 just for receiving (and sanding) data from PC and UART1 just for lighting one strip. EDIT: Now I see that original question was meant to use 2 parallel strips on both UARTs.

Makuna commented 5 years ago

@Benik3 Use Gitter for general questions, I can provide answers there. The issues area is about problems found and tracking those issues. See https://gitter.im/Makuna/NeoPixelBus

Makuna commented 5 years ago

https://github.com/Makuna/NeoPixelBus/pull/239 Now supports both uart1 and uart0 both sync and async. Both can be used at the same time as long as both are either sync or async (can't mix them). If Async is used, then neither serial nor serial1 can be used due to ISR conflict (maybe next release after required changes in esp8266 board support core is supported)

Makuna commented 5 years ago

now released in 2.4.0 and wiki has been updated