Hot answers tagged

57

There is no multi-process, nor multi-threading, support on the Arduino. You can do something close to multiple threads with some software though. You want to look at Protothreads: Protothreads are extremely lightweight stackless threads designed for severely memory constrained systems, such as small embedded systems or wireless sensor network nodes. ...


19

AVR based Arduino's do not support (hardware) threading, I am unfamiliar with the ARM based Arduino's. One way around this limitation is the use of interrupts, especially timed interrupts. You can program a timer to interrupt the main routine every so many microseconds, to run a specific other routine. http://arduino.cc/en/Reference/Interrupts


15

It is possible to do software side multi-threading on the Uno. Hardware level threading is not supported. To achieve multithreading, it will require the implementation of a basic scheduler and maintaining a process or task list to track the different tasks that need to be run. The structure of a very simple non-preemptive scheduler would be like: //...


9

As per the description of your requirements: one thread waiting for an external device one thread blinking a LED It seems you could use one Arduino interrupt for the first "thread" (I would rather call it "task" in fact). Arduino interrupts can call one function (your code) based on an external event (voltage level or level change on a digital input pin), ...


9

Handling multiple patterns at the same time is certainly possible with a platform like Arduino, and there are a number of ways you could go about it. One method I would consider is writing functions which effectively represent each pattern mathematically. You'd just pass it the total time that's elapsed in your program so far, and it will do the appropriate ...


7

A simple solution is to use a Scheduler. There are several implementations. This describes shortly one that is available for AVR and SAM based boards. Basically a single call will start a task; "sketch within a sketch". #include <Scheduler.h> .... void setup() { ... Scheduler.start(taskSetup, taskLoop); } Scheduler.start() will add a new task ...


5

ESP32. Dual core 240MHz, plus an extra XLP state machine. Cheap and easily available on eBay/Amazon/Ali Express etc. And with full Arduino support.


4

I also came to this topic while implementing a matrix LED display. In one word, you may build a polling scheduler by using millis() function and timer interrupt in Arduino. I suggest the following articles from Bill Earl: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview https://learn.adafruit.com/multi-tasking-the-arduino-part-2/...


4

There is indeed a race condition in your code: if an interrupt fires while you are reading one of the counters, you might read garbage. If it fires between reading and resetting the counter, you loose one count. The way to prevent the race is to block interrupts while the main thread (everything that does not run in interrupt context) accesses the counters. ...


4

This is not a direct answer to the question. Instead, I suggest that you do not need an RTOS to do what you want. A lightweight alternative is to use millis() to decide when it is time to perform such or such task: void loop() { uint32_t now = millis(); // Update the LCD every second. static uint32_t last_lcd_update; if (now - ...


4

Arduino is a fine choice for the task - easy to get started with. The key is to write non-blocking code. You could take a look at the BlinkWithoutDelay example. I made a suggestion for your task: // Timing suquences for the LED's in milliseconds // First value is on time, second value is off time, // third value on time and so on (up to 10 values) // One ...


3

You could also give my ThreadHandler library a try https://bitbucket.org/adamb3_14/threadhandler/src/master/ It uses an interrupting scheduler to allow context switching without relaying on yield() or delay(). I created the library because I needed three threads and I needed two of them to run at a precise time no matter what the others were doing. The ...


3

From a previous incantation of this forum, the following question/answer was moved to Electrical Engineering. It has sample arduino code to blink an LED using a timer interrupt while using the main loop to do serial IO. https://electronics.stackexchange.com/questions/67089/how-can-i-control-things-without-using-delay/67091#67091 Repost: Interrupts are a ...


2

You may want to take a look at LMX by David Anderson A Light-Weight Multi-Tasking Executive. He has a very good set of videos on the code that he did for Dallas Personal Robotics Group (DPRG). The specific videos for LMX are: David Anderson on Robotics Software - part 1 David Anderson on Robotics Software - part 2


2

It can be done. The Arduino is a single tasking environment so you have to make sure your code is non-blocking. BlinkWithoutDelay is a good starting point (thanks @Majenko) but you should also look at the Timer1 library. Basically your programs needs to do all the steps it can right away and whenever it does something that could block, it must do it ...


2

My recommendation would be to simply code without needing blocking. I have examples here. Petri Häkkinen coded a game - Toorum's Quest - without using any real-time library. That game (on a Uno) has multiple sprites, TV output and sound effects, all interleaved. The basic technique is to know that you have multiple things you need to have done, from time ...


2

I would recommend NilRTOS. I like the fact that it's really minimal. However, you might find that some libraries (which you would like to use) work in blocking mode and cannot be used with this RTOS, because they might do bad things (polling) or worse things (polling in interrupt context with other interrupts disabled). But that will be the case regardless ...


2

You could also give my ThreadHandler library a try https://bitbucket.org/adamb3_14/threadhandler/src/master/ It uses an interrupting scheduler to allow context switching without relaying on yield() or delay(). I created the library because I needed three threads and I needed two of them to run at a precise time no matter what the others were doing. The ...


2

You can't use threads on an arduino, they don't exist. you can get some pseudo multitasking going with interrupts, but that is not necessary in your case. You should be able to refactor your code to avoid using delays without much work. The arduino library provides millis() to keep tract of the time since the arduino was powered on in milliseconds. ...


2

Check this example: rather than sleep(), it uses PT_WAIT_UNTIL while(1) { PT_WAIT_UNTIL(pt, millis() - timestamp > interval ); timestamp = millis(); doSomething(); } That should be the proto-thread way of waiting: PT_WAIT_UNTIL will make sure that your thread sleeps in a way that allows other threads to run. The rest looks fine, ...


1

Sure there is. All you're doing is reading and writing serial data. All you have to do is learn how to do that without blocking. Most code I see bandied around is of the form: Send AT command Delay for numerous seconds Read and discard anything that might be there Send another AT command Delay for more seconds Read and discard anything that might be there ...


1

In protothreadCollectAndTransmitData you have a timestamp variable that never gets updated: static int protothreadCollectAndTransmitData(struct pt* pt, int interval) { static unsigned long timestamp = 0; // <- This never changes .... When the condition is true you will need to update timestamp = millis();. static int ...


1

I haven't used the TimerOne library, but I have had good success with the SimpleTimer library. http://playground.arduino.cc/Code/SimpleTimer It's served me well in handling building small iot apps. As the arduino has to both maintain connection info as well as doing it's processing data, this library seems to handle keeping both happy pretty well. Here'...


1

You will not have full parallel execution in an Arduino (only one CPU). You might do multi-threading by implementing a small OS (e.g. FreeRTOS) Or write your own task scheduler. Or even just do state machine looping forever checking if push or pop has to be executed. Last and preferred solution: I would consider running the normal Push task always and ...


1

The compiler error is due to that the compiler does not know what Thread is. tcan.h:6:28: error: expected class-name before '{' token class tcan : public Thread { The issue is that the header file is not complete. A good practice is to include all header files that are needed to read the header file. As Thread is defined in mthread.h the tcan.h file ...


1

One way to do this is to use the millis() function. millis() returns the current value of a timer that is incremented once per millisecond (hence the function name). You can compare the value of millis() at some past time with the current value to determine how many milliseconds have passed. By having multiple compare registers you can have multiple ...


1

I would suggest looking into threading. To minimize the time from the first read to the final read, an interrupt and an interrupt timer would probably be good. Have the interrupt timer fire after some interval and place all of your sensor reads in the Interrupt Service Routine (ISR). I would also suggest staying away from functions that the Arduino ...


1

You could use a scheduler and simply start tasks with: #include <Scheduler.h> ... void setup() { ... Scheduler.start(servoSetup, servoLoop); Scheduler.start(sensorSetup, sensorLoop); ... } void servoSetup() { S.attach(servo); } void servoLoop() { int angle; for(angle = 0;angle <= 180; angle++) { S.write(angle); if (angle ==...


1

You may want to take a look at LMX by David Anderson A Light-Weight Multi-Tasking Executive. He has a very good set of videos on the code that he did for Dallas Personal Robotics Group (DPRG). The specific videos for LMX are: David Anderson on Robotics Software - part 1 David Anderson on Robotics Software - part 2


1

I think this needs a major rework. First here: for(int i=0;i<1023;i++) { analogWrite(which, i); } The maximum you can analogWrite is 255, so change 1023 to 255. Next, get rid of the delay() calls. Let's look at turnLeft : // To turn the robot left side void turnLeft() { stopmotor(M2); stopmotor(M3); delay(5000); Runmotor(M2); ...


Only top voted, non community-wiki answers of a minimum length are eligible