hideakitai / ArduinoOSC

OSC subscriber / publisher for Arduino
MIT License
207 stars 20 forks source link

Event-driven approach to receiving OSC data rather than polling? #24

Closed VonHirsch closed 3 years ago

VonHirsch commented 3 years ago

This is more of a feature request. Would it be possible to implement a more event-driven approach to receiving OSC data rather than polling parse()? I'm implementing freertos tasks which trigger FastLED, so avoiding creation of a periodic polling task would waste less cpu time.

Here's a similar discussion: https://github.com/espressif/arduino-esp32/issues/1995

p.s. no pressure on this one, just a feature request. I'll let you know how it goes with polling.

hideakitai commented 3 years ago

@VonHirsch Thank you for the feedback!

I think you can call parse() in a FreeRTOS task that runs in the background. Isn't that the problem? AsyncUDP also polls the UDP packet as a FreeRTOS task, and a callback is called when data comes in.

avoiding creation of a periodic polling task would waste less cpu time

Sorry, I couldn't understand this line. Are you running FastLED in Core 1? And do you want to parse in Core 0?

VonHirsch commented 3 years ago

@hideakitai no problem, good conversation.

To reply to your comments:

  1. Yes, I am calling parse in a FreeRTOS task on a periodic basis (polling) and it’s working. This feature request is about how an event-driven software interrupt could be used instead of polling.
  2. My comment about “cpu time” is a general observation about polling vs. interrupts and is not specific to this request, however yes I will be scheduling tasks on multiple cores.

About Interrupt or "event-driven" approach, have a look at AsyncUPD, line 132:

if(xQueueReceive(_udp_queue, &e, portMAX_DELAY) == pdTRUE)

^^ this will block the task until data arrives on the queue. This mechanism is documented in the FreeRTOS pdf:

image

This is what I mean when I say "event-driven" or "interrupt driven" that the FreeRTOS task will block until UDP data arrives. So parse() will only take cpu time when there are packets to process.

hideakitai commented 3 years ago

@VonHirsch Ah ok, you want to call parse() only when the packet has come.

ArduinoOSC is designed based on the Arduino's Server class. You know, the Arduino's Server class is a polling-based design, so ArduinoOSC is also a polling-based design. So I won't support AsyncUDP because its APIs are different from it. Also it is not common for other platforms other than esp32 now.

If you really don't want to waste cpu time, you can use OSCDecoder and make your own parse function inside of the callback of AsyncUDP like this.

https://github.com/hideakitai/ArduinoOSC/blob/a3aeac313e53e2fc215cbfefeb94a746e4ff758c/ArduinoOSC/OSCServer.h#L207-L231

VonHirsch commented 3 years ago

@hideakitai Cool thanks I'll try that out, thanks for your help!