Programs that require the Arduino to run 2 things at once?

I asked a question here before about whether the Arduino can run 2 things at ones (say two parts of a code at once) and the answer I got was no, the Arduino had just one processor and so I had to write the code linearly in such a way as to appear to be running 2+ things at once if I wanted the Arduino to 'multitask'. That made sense.

But then, as I'm learning some more programming concepts or trying out certain projects, this subject comes up again and there doesn't seem to be any sort of explanation for it. Like for instance, the concept of Interrupts and how certain programs are running in the background? And articles like this:

What gives? Don't these things require that the Arduino run multiple things at once? And I'm also thinking that at some point, there is almost no way to just write a code linearly for big projects, so there must be some kind of multi-tasking capabilities, especially for reading values from many sensors and at the same time running, say motors and LEDs and communications and whatnot. And come to think of it, how do computer microprocessors run a whole OS? None of the books I have downloaded to learn this stuff nor any articles online from what I've searched seem to explain this well, so can someone please explain it here. Because this is getting really frustrating. Is this something esoteric for computer science and engineering majors? The only thing I can think of is using more than one microcontroller, and I don't know anything about that yet, so...

Huh? There is information everywhere on the forum about this and it's far and away the most frequently asked question here. I don't know how you could have missed this

This is just one of many guides on this topic... Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Typically you do not need interrupts, just use of millis() and keeping track of when you've done things. Interrupts are tricky and should be used only when you need them

A MCU with one processor can only execute one line of code at a time and is about as linear as you get with code. A interrupt does not make things run in parallel. It stops whatever current process it was currently doing and immediately jumps to the more important interrupt-process. Interrupts can be specified to have hierarchy, such that a interrupt, can be interrupted, if one has more priority than the other.

If this happens the highest priority is done first. Then is returns to the interrupted-interrupt. Then the rest of the code.

In an ideal world. Your void loop{} would be entirely empty.
All functions would be handled by interrupts and controller would be ordered to prioritize them correctly. Meeting all deadlines. But this is really only necessary for critical applications. But still code is still executed one line at a time. Registers are filled one at a time.

Have a look at the demo several things at a time.

Interrupts are not necessary - in fact they slow things down slightly.

Strictly speaking only one thing can be done at a time, but the Arduino can switch between tasks fast enough to give the illusion they happen in parallel.

...R

DrAzzy:
Huh? There is information everywhere on the forum about this and it's far and away the most frequently asked question here. I don't know how you could have missed this

This is just one of many guides on this topic... Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Typically you do not need interrupts, just use of millis() and keeping track of when you've done things. Interrupts are tricky and should be used only when you need them

Sigh... The question is not how to do it, cuz I've had my own little projects where I used all of this, nor is it whether or not it can be done, which has an obvious answer. My question is how is any of this done if the Arduino runs things linearly... Performing only one task at a time... For instance, the very existence of the millis() function means that from the very beginning of the launching of a program, the Arduino is at the very least running the code AND keeping track of the amount of time that had passed. Same applies to interrupts. All of this points to multi-tasking capabilities...

And also, concerning the post given, at the part of the loop calling all the functions, does the Arduino run all those functions at the same time? Because, if it were reading linearly as I understand it, it would go to the readButton() function first, do that bit, then updateOnBoardLedState(), and so on. But instead, this program somehow tells the Arduino to run all of this at once? How?

Pluto1:
Sigh... The question is not how to do it, cuz I've had my own little projects where I used all of this, nor is it whether or not it can be done, which has an obvious answer. My question is how is any of this done if the Arduino runs things linearly... Performing only one task at a time... For instance, the very existence of the millis() function means that from the very beginning of the launching of a program, the Arduino is at the very least running the code AND keeping track of the amount of time that had passed. Same applies to interrupts. All of this points to multi-tasking capabilities...

And also, concerning the post given, at the part of the loop calling all the functions, does the Arduino run all those functions at the same time? Because, if it were reading linearly as I understand it, it would go to the readButton() function first, do that bit, then updateOnBoardLedState(), and so on. But instead, this program somehow tells the Arduino to run all of this at once? How?

No it does not "run all of this at once".

You may get a better grasp on things by going back to 1945.
The basic foundation of processing is still same.
Here is the reference.

Vaclav:
No it does not "run all of this at once".

You may get a better grasp on things by going back to 1945.
The basic foundation of processing is still same.
Here is the reference.

von Neumann architecture - Wikipedia

I had a feeling that I'd need to understand the basics of all this, in terms of the electronics and computer hardware, and I have been/am doing this. I'm going through the hierarchy of knowledge in this respect to avoid situations in which I would just need to 'go with it' or not fully understanding something because I'm missing pieces of knowledge from the subject.

BUT. I still would very much like an answer as to what happens when the functions are called? And something that also has me puzzled is when you put a function outside of the loop and don't call it, and the Arduino runs it. Doesn't the Arduino repeat whatever is in the loop and stop when the loop function ends? And oh man, so much stuff like that, I'm getting sick of it.

Pluto1:
For instance, the very existence of the millis() function means that from the very beginning of the launching of a program, the Arduino is at the very least running the code AND keeping track of the amount of time that had passed.

That is vague way of putting it. The AVR MCU does in fact take care of your code and load resisters with timer values. It does not use the same resources to do that. In fact the resources it uses are very much different with the exception that they both use clock cycles.

All millis() does is take the current values of the counters, and there is even overhead involved in doing so.

In the end, the program is still executed linearly.

If you want to dig into the meat of this, learning assembly code would help you out. That... isn't an easy feat but it gets very close to putting the exact instructions into the registers to be executed and how sections of code can be executed by jumping over others. When writing code you even have to tell the compiler to jump back up several lines of code to implement loops.

Also real-time embedded systems, is an area that describes exactly what goes into building a MCU. These are both pretty advanced topics, but you could still get a rough understanding out of it.

An easier way of learning is probably to find youtube videos on how computers execute code.

@ ApexM0Eng

A MCU with one processor can only execute one line of code at a time and is about as linear as you get with code.

First - lines of code are not executed - by the time the cpu "sees" anything they have been turned in to instructions. Lines are there just for the sake of layout.

A interrupt does not make things run in parallel. It stops whatever current process it was currently doing and immediately jumps to the more important interrupt-process.

There are no process in this context so the cannot be started or stopped. The interrupt changes the address of the next instruction to be executed.

Interrupts can be specified to have hierarchy, such that a interrupt, can be interrupted, if one has more priority than the other.

Again not on the Arduino! If 2 interrupts happen at the same time then there is a rule to say which will be dealt with first. During an interrupt, by default, new interrupts are not actioned. Interrupts do not interrupt each other.

f you want to dig into the meat of this, learning assembly code would help you out.

Totally untrue there is no need to use assembly code with the AVR processors

Pluto1:
I had a feeling that I'd need to understand the basics of all this, in terms of the electronics and computer hardware, and I have been/am doing this. I'm going through the hierarchy of knowledge in this respect to avoid situations in which I would just need to 'go with it' or not fully understanding something because I'm missing pieces of knowledge from the subject.

BUT. I still would very much like an answer as to what happens when the functions are called? And something that also has me puzzled is when you put a function outside of the loop and don't call it, and the Arduino runs it. Doesn't the Arduino repeat whatever is in the loop and stop when the loop function ends? And oh man, so much stuff like that, I'm getting sick of it.

After you digest the Von_Neumann_architecture take closer look at this part

"a control unit containing an instruction register and program counter, a memory to store both data and instructions,"

It is the "program counter" which keeps tabs on " location" ( memory and other so far not relevant in your search for knowledge stuff ) where the program is at any given time. And when your program is directed to "execute" function "outside " of loop() ( as a example) this program counter just switches to whatever location such function resides in and continues on its way, basically incrementing its count with each execution of single step in your program until told to switch back or to another function...

Don't these things require that the Arduino run multiple things at once?

There's only one of you, right? With the one brain? But you can boil water for coffee, fry eggs, have the dishwasher running, and the washing machine, send someone a text, and answer the phone all at the "same" time, yes?

You allocate your brain to do a bit of this, and then a bit of that. It seems like you are doing multiple things at once. The Arduino is the same.

@OP

BUT. I still would very much like an answer as to what happens when the functions are called? And something that also has me puzzled is when you put a function outside of the loop and don't call it, and the Arduino runs it. Doesn't the Arduino repeat whatever is in the loop and stop when the loop function ends? And oh man, so much stuff like that, I'm getting sick of it.

loop() is called over and over again forever It's that simple.

If a function is not call from any where in the code then UNLESS it is an ISR it is not even put into the finished object code. ISR's are not called directly from your code. The CPU " calls then when an interrupt occurs.

Mark

While you're at the textbooks, look up the concept of a "stack". That is how the system keeps track when one function calls another function. The stack keeps all the local variables so that when the second function exits, it goes back to the first one and it still remembers where it's up to.

Pluto1:
concerning the post given, at the part of the loop calling all the functions, does the Arduino run all those functions at the same time? Because, if it were reading linearly as I understand it, it would go to the readButton() function first, do that bit, then updateOnBoardLedState(), and so on. But instead, this program somehow tells the Arduino to run all of this at once? How?

The Arduino DOES work linearly through the functions as you say - readButton() followed by updateOnBoarLedState() etc. But it does them so quickly that they appear to all happen at the same time.

And, yes, it does use interrupts to keep micros() and millis() updated and also to receive serial data.

...R

MorganS:
While you're at the textbooks, look up the concept of a "stack". That is how the system keeps track when one function calls another function. The stack keeps all the local variables so that when the second function exits, it goes back to the first one and it still remembers where it's up to.

Nice add. And that is what I was referring to initially as.

"other so far not relevant in your search for knowledge stuff "

And same goes for dreaded "interrupts".

As far as Setup() and Loop() - that will be a subject of "Advanced Arduino 102 " class next semester.

For now look up "main" (function) and how that gets started / implemented both in hardware and software.
Hint - you already now that function can call another function and another function....all under the direction of "program counter".

"Reset" will be covered in details after lunch.

Smoke the'm if you have the'm...

Have fun.

Robin2:
And, yes, it does use interrupts to keep micros() and millis() updated and also to receive serial data.

One other thing I would say is don't get too deep into the von Neumann architecture thing - he was a Princeton man, and the AVR uses a Harvard architecture.
The principle is roughly the same but some of the details differ.