21 ms·
Introducing multitasking to Arduino
- ge96 4y agoSounds good. I was working on a project where I could not receive websocket info until I was done running servo commands. I know you can have multiple boards but yeah.
- HeyLaughingBoy 4y agoNice, but pointless addition to an old processor. ESP32's are cheap and readily accessible and they come with FreeRTOS running already. If I absolutely need to multitask on a Mega328 Arduino, I use the protothreads library. But really, for anything heavy, I'll turn to an ESP32 or an STM32. Use the right tool for the job!
- sophacles 4y agoIn 2022 Arduino has several baords, many of which are NOT using atmega 328. Some of them have multi-core Arm chips, some of them have risc-v (not sure if they have any of those as multi-core though). There are already people running FreeRTOS on those. Not sure why you would dismiss multitasking on those as "useless".
- kevin_thibedeau 4y agoEven on an AVR, you can implement lightweight cooperative scheduling with low resource consumption. That gives you many of the benefits of an RTOS with less risk of creating heisenbugs. Arduino should have broken free of its main-loop architecture long ago.
- francisduvivier 4y agoDon't forget that a lot of people are using Arduino framework code on ESP32, it works pretty well. So this development is also relevant for those other boards, maybe even more so.
- HeyLaughingBoy 4y agoYup, and it's running FreeRTOS out of the box.
- atoav 4y agoYeah, the art students with miniscule coding experience who just want to get stuff done are probably going to be thrilled to work with FreeRTOS. The truth is, that Arduino always has put in a lot of work to do things that could already be done only to make them more accessible, easier to use and thus more widely available. If you think this is pointless you should consider this might say more about how far you have come in your own journey than about the usefulness of that new feature.
- seabird 4y agoThe art students with minimal coding experience would take FreeRTOS ten times out of ten over trying to figure out what a compare match timer is, what an interrupt is, how bitwise operations work, etc. The OP was dead-on and I'd bet money that the downvotes are from people that have never had somebody's eyes glaze over when they told them that they "just need to calculate their prescaler values, mask the appropriate bits into the config register, set the number of counts in the compare register, enable the timer interrupt, and register an interrupt vector to handle it".
- deepspace 4y ago> the art students with miniscule coding experience That is a minuscule part of the Arduino audience. For the rest of us, FreeRTOS works fine.
- xkcd-sucks 4y agoI'm crappy at embedded development but isn't it pretty normal to handle "multitasking" with interrupts instead of using an event loop?
- sophacles 4y agoEmbedded can be a tiny little msp430 with RAM measured in bytes, or it can be the latest and greatest intel flagship - it's a description of how the chip is used more than the chip type. As CPUs get more powerful in general, so too do the little development boards. I can spend $10 on a board with multiple cores and megabytes of ram to drive my blinky lights and do wifi - that's enough power to run a full unix.
- baremetal 4y agowhere? where can i get one?
- balefrost 4y agoThe Raspberry Pi foundation recently (about a 18 months ago) released their own dual-core ARM chip - the RP2040 - and a corresponding dev board - the Pi Pico. The Pico dev board runs about $4 plus shipping from authorized resellers. Within the past few weeks, they introduced a wireless version - the Pi Pico W. It's about $6 from authorized resellers, though stock is hard to find at the moment. https://www.raspberrypi.com/documentation/microcontrollers/ https://www.raspberrypi.com/documentation/microcontrollers/ https://www.raspberrypi.com/news/raspberry-pi-pico-w-your-6-iot-platform/ https://www.raspberrypi.com/news/raspberry-pi-pico-w-your-6-...
- dvh 4y agoEsp32 boards has 2 cores and cost $5, works fine in Arduino. Try AliExpress.
- fermuch 4y agoAnd can use up to 8mb of psram and 16mb of flash
- primitivesuave 4y agoA couple years ago, I managed a summer/afterschool program that introduced thousands of kids (age 8-18) to the Arduino. When we would set up a software abstraction to simplify multitasking (something that came up often with more advanced students), we set up something like this: int time = 0; int max_period = 10000; void loop() { if (time % 100 == 0) { everyTenthSecond(); } if (time % 1000 == 0) { everySecond(); } // ... time = (time + 1) % max_period; } This `loop` assumes functions are perfectly non-blocking, which obviously is not always true, but works well for 99% of actual use cases. If keeping accurate time is required, the student would compare `time` with the elapsed millisecond time since the last loop invocation, adjust accordingly, and check for any periodic functions that weren't executed in that period. It gets tedious quite fast. If I had to imagine a solution, it would be to simply have an easy way to enter parameters to the JS-equivalent of `setTimeout` and `setInterval`.
- joezydeco 4y agoThat is spiritually what their Scheduler library is doing, as mentioned in the article. Which works for a lot of things just fine until one task begins to overrun its time slice or just hangs. And then you're looking into preemption. But if you're overruning an AVR micro maybe it's time to take the training wheels off and move up to a larger system.
- jgerrish 4y agoDon't be too quick to dismiss the "training wheels" of AVR. While ARM and RISC-V may have beefier processors, and will probably be migrated to or adopted, AVR has a lot going for it. First, a common AVR board like the Arduino Uno has built-in peripherals like a temperature sensor. You can build something out of the box without buying external items. If your target market is cheap educational, that's key. Second, it offers basic microcontroller features like power management, external interrupts, serial and other stuff. It provides a terrific cheap platform to understand managing interrupts and concurrency safely in your language of choice. Which can be applied to the bigger boards. Finally, memory constraints require careful thinking through code. I'm not going to implement a full standard library on an Arduino AVR, so what do I bring with me?
- OlaCh 4y agoEnergia IDE was a good example of multitasking for MCU. Here is an example: https://energia.nu/guide/foundations/programming_technique/multitasking/ https://energia.nu/guide/foundations/programming_technique/m...
- mikewarot 4y agoI see an opening for a very good set of tutorials on how to avoid all the pitfalls. [edit] - Actually... they have some good points, I just worry about someone thinking they can just "sprinkle threading" into their code, and failing to understand that in doing so they change the laws of physics of the code.
- nyanpasu64 4y agoI find that Rust-like rules (&T across threads and &mut T within a thread, restricting cross-thread mutation to &Mutex<T> and &AtomicT, global variables are treated as shared) are the best approach I've seen so far to general multithreading (as opposed to structured subsets like message passing or structured concurrency, which I haven't explored as much). However I'm unsure if mutexes are incompatible or unnecessary with the majority of single-core Arduinos with cooperative multitasking, and treating global data as shared is a pain on embedded and binding them to a specific thread is not a problem Rust has solved yet (you'll have to find your own solution).
- ramary 4y agoWe've done quite a bit of experimentation with adding preemptive multitasking support to non-hard real time software running on MCUs at my current company. After a lot of head banging and dead ends, I've come to the conclusion personally that the embedded community could really use an implementation of the POSIX threading APIs or some meaningful subset thereof for various platforms. They're already standardized, well understood/used, and aren't that hard to implement on an MCU. Of course, there would probably be some semantics that wouldn't make sense to or may not be possible to implement on MCUs, and there would be work required to support different cores, but these tradeoffs seem better to me than reinventing the wheel and probably needing to make the same tradeoffs at some point down the line with a ground up new API. For Arduino, exposing POSIX APIs wouldn't be very user-friendly. But wrapping something more user-friendly around them seems like a maintainable and extensible path for the project and community.
- Tajnymag 4y agoThreads are already supported by esp-idf on esp32 source: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/pthread.html https://docs.espressif.com/projects/esp-idf/en/latest/esp32/...
- ramary 4y agoThat's great, thanks for sharing!
- Teknoman117 4y agoDo you know how the core scheduling works? Does it migrate tasks between cores? Is there any notable core to core migration penalty?
- deepspace 4y agoAnd esp-idf uses FreeRTOS, which is pretty much the standard for this kind of thing.
- qbasic_forever 4y agoThis is the direction a lot of RTOSs go, for example Zephyr (https://docs.zephyrproject.org/3.0.0/guides/portability/posix.html https://docs.zephyrproject.org/3.0.0/guides/portability/posi...) and FreeRTOS (https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/index.html https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/i...).
- fmakunbound 4y agoForths such as FlashForth https://www.flashforth.com/index.html https://www.flashforth.com/index.html on the Arduino support multiple tasks .. in addition to including a compiler and interactive REPL
- dariosalvi78 4y agoI like the simplicity of setTimeout and setIntetval of JavaScript. Maybe something similar plus some mutex primitive (which JS doesn't need)?
- oconnor663 4y agoI wonder if async Rust would be a good fit for this use case? It doesn't solve the accidental blocking problem (although async-std did experiment with blocking detection at one point), but you can get transparent support for multiple cores and a lot of thread safety.
- eldruin 4y agoYou can have a look at https://embassy.dev https://embassy.dev Rust+async on embedded
- andrewstuart 4y agoasync/await does not result in bloated code that is hard to maintain and debug. It's a strange thing to say - async/await is now built in to most major programming languages - strange that Arduino would dismiss it so easily. They are correct in that async/await does not solve multicore utilisation, but it's the most important and easiest way to implement parallelism on a single core.
- hamandcheese 4y agoTFA makes no mention of async/await, only asynchronous programming. Specifically, it says: > The traditional way to do this is to write non-blocking code so that the loop() function can run as fast as possible, updating state variables and calling the millis() function to ensure proper timing Indeed, that style of programming is nothing at all like async/await in, say, Javascript.
- eldruin 4y agoIn Rust there is https://embassy.dev https://embassy.dev which is an async Rust framework for embedded. It has been shipping in products for years. Can be made real-time (for some definitions of it). There is also RTIC https://rtic.rs https://rtic.rs which is a concurrency framework for real-time systems using interrupts. IIRC the car industry is interested in it.
- mongrelion 4y agoVery interesting projects. Looking at the documentation and Github pages it's not very clear if ATmel, the microcontroller family for Arduino, is supported at all or not. Do you have a link where this is validated?
- eldruin 4y agoThere are several microcontroller architectures within the Arduino family officially as well as compatible ones that are also called Arduino-something. The classic (and oldest) are the AVR microcontrollers (ATmega), which are not supported by embassy nor rtic at the moment AFAIK. They are supported by Rust, though. see: https://github.com/rahix/avr-hal https://github.com/rahix/avr-hal. However, there are several other Arduino microcontrollers that are supported. For example the Arduino Nano RP2040, Arduino Nano 33 BLE (nRF), the Arduino MKR ones as well as the STM32duino (STM32F103, the one in the hugely popular $2 blue-pill boards) are all based on the ARM cortex-m architecture, which is supported by both embassy as well as rtic. For espressif chips (like the esp32), support is being worked on by the manufacturer itself: https://github.com/embassy-rs/embassy/issues/745 https://github.com/embassy-rs/embassy/issues/745 Here an overview of microcontrollers in the (official) Arduino family: https://www.makeuseof.com/exploring-different-types-of-arduino-microcontroller/ https://www.makeuseof.com/exploring-different-types-of-ardui...
- syncurrent 4y agoSynchronous programming is also a good choice IMHO to handle multiple concurrent activities in a simple way on an embedded system. https://github.com/frameworklabs/proto_activities https://github.com/frameworklabs/proto_activities
- fake-name 4y agoITT: Arduino people re-implement FreeRTOS badly. Seriously, there are SO MANY mature, well-understood RTOS implementations for MCUs out there already, they really, really should just use one.