How to Run Multiple Functions Independently

Greetings, I could use some guidance on how to run separate functions simultaneously and independently. I am reading input pulses and using that as a clock for my counter variables. I am not using millis() or delay() nor do I wish to use those functions. I am counting input pulses for my delay periods.

I have the separate functions working and giving proper time delays when run separately but when two run simultaneously the delay time is doubled. If three are run simultaneously the time delay triples. I understand why the time delays increase because of the shared resources.

Can you please point me in some direction as to how I can get multiple functions to run simultaneously and independently so that the execution of one function does not interfere with the execution of other functions?

Here is a block of pseudocode. Many Thanks for any help you can offer!

void loop() {
    function1();
    function2();
    function3();
    }

function1() {
    if (Count1 not complete) {
        LED1 ON;
        increment count1;
        }
    else {
        LED1 OFF;
        Reset Count1;
        }
    }

function2() {
    if (Count2 not complete) {
        LED2 ON;
        increment Count2;
        }
    else {
        LED2 OFF;
        Reset Count2;
        }
    }

function3() {
    if (Count3 not complete) {
        LED3 ON;
        increment Count2;
        }
    else {
        LED3 OFF;
        Reset Count3;
        }
    }

how I can get multiple functions to run simultaneously and independently

You can't. The Arduino only has one CPU so it can only do one thing at a time. The only way to get true simultaneous functions is to run each one on a separate Arduino.

Pete

Well without the timing specs of the three input signals it's hard to say if or if not. What is the maximum pulse frequency of the external pulses being wired to the arduino?

But basically it's usually possible to perform 'pseudo' independent processes by using either interrupts or millis() or micros() or a combination of both. Independence comes down to can the individual functions be serviced quick enough by the main loop code to satisfy the timing requirements of the external events. In almost all cases the answer is yes, if you avoid blocking commands as you now have embedded into each of your functions.

Just saying:

I am not using millis() or delay() nor do I wish to use those functions. I am counting input pulses for my delay periods.

May very well be limiting your best or only possible solution. It's the results that counts not the methods used or not used.

Lefty

I am not dead set against using millis() if there is a way to get accurate timing. Is there any way to control millis() with an external pulse input on the Arduino's Pin 8?

I can get accurate time delays from the input pulses on Pin 8. When I use millis() or delay(), it's not accurate. What approach would I take to control the Atmeg328's internal counters/timers so that millis()-based time delays will be accurate?

hypercode: I am not dead set against using millis() if there is a way to get accurate timing. Is there any way to control millis() with an external pulse input on the Arduino's Pin 8?

I can get accurate time delays from the input pulses on Pin 8. When I use millis() or delay(), it's not accurate. What approach would I take to control the Atmeg328's internal counters/timers so that millis()-based time delays will be accurate?

I'm afraid you haven't explained what your are actually trying to accomplish. What is your numerical accuracy requirements specifically? Again what are the timing specification of the external signals you are trying to measure?

Lefty

hypercode: I can get accurate time delays from the input pulses on Pin 8. When I use millis() or delay(), it's not accurate. What approach would I take to control the Atmeg328's internal counters/timers so that millis()-based time delays will be accurate?

Can you explain all this? In what way are they not accurate? What amount are they out? What amount is acceptable?

Whether or not you use the internal clock or hook up to an atomic clock on pin 8, there is still some latency introduced by the time taken to execute your code.

Perhaps if you describe what you are trying to do here? Your subject line of "How to Run Multiple Functions Independently" implies that, if you were successful, your problem would be solved. It might be more helpful to describe the problem.

You might find this helpful:

http://www.gammon.com.au/forum/?id=11504

In that I use the internal timers to accurately measure a frequency. The error amount was about 0.04%. Not too bad. Now if you want a lower error rate perhaps specify what that rate is. And what you are currently getting.

Is there any way to control millis() with an external pulse input on the Arduino's Pin 8?

What does that mean?

Have you considered the use of "micros()"?

As others have said; until you tell us what you want to do, not how you think you should (or shouldn't) do it, this is just a guessing game.

With other processors, you can allocate RAM then run a routine in that area of RAM independently of what is happening elsewhere. Can you do that with the Arduino C-style software?

This what I'm trying trying to find out. It's not that I want to do any specific thing where I would write the code to do that specific thing. I'm trying to learn how to use the Arduino software with the Atmeg328.

Thanks for your patience ;^)

Even if you can run code in arbitrary locations, the arduino only has one core and therefore can only execute one instruction at a time.

http://arduino.cc/forum/index.php/topic,74503.0.html http://arduino.cc/forum/index.php/topic,87552.0.html

Hi,

Basically no, but the ATMega chip has some neat features that make it pretty good at measuring inputs and generating accurate output pulses and waveforms. The Arduino is a micro controller, not a computer and so a lot can be achieved using the hardware level rather than in software as you would on a computer - the timer/counters being a strong example of this.

As others have said, if you give a bit more detail on what you are doing you will get better advice.

Or If your up to it, read the ATMega328 data sheet for a complete view of what's available.

Duane B

rcarduino.blogspot.com

With other processors, you can allocate RAM then run a routine in that area of RAM independently of what is happening elsewhere. Can you do that with the Arduino C-style software?

The AVR cannot execute code from RAM - it is a feature of the Harvard architecture - program and data memories are totally different address spaces. This isn't an Arduino limitation, it is a limitation of the processor family.

Even if it wasn't, without two processors you never really run things "simultaneously". And even then, if you have one lot of RAM the two processors cannot both write to the same address at once (usefully anyway) so you need to carefully manage your use of resources.

hypercode: With other processors, you can allocate RAM then run a routine in that area of RAM independently of what is happening elsewhere. Can you do that with the Arduino C-style software?

What other processors? Can you quote one? Generally speaking processors (for safety purposes) delineate memory used for programs (which they don't let you write to) and memory used for data (which you can write to).

PIC16. You designate areas of memory addresses with a srart addy and a stop addy. Known as "stacks".

pyro65... Thanks for the links. Interesting discussion ;^)

With other processors, you can allocate RAM then run a routine in that area of RAM independently of what is happening elsewhere. Can you do that with the Arduino C-style software?

As already said, a micro-controller is a single thread processor, one hardware instruction at a time is executed. But with proper software structure an arduino (any c/c++ program actually) can indeed perform multiple tasks that are independent of each other up to the timing limits for the specific task requirements. This need for 'Independence' is just a limitation in you thinking until you gain the knowledge of program control and structure that one has at their means.

Lefty

hypercode: PIC16. You designate areas of memory addresses with a srart addy and a stop addy. Known as "stacks".

From what I have read so far this is nothing like "run a routine in that area of RAM independently of what is happening elsewhere". It's just an interrupt service routine that has its own stack.

The Atmega328 certainly supports interrupts. But you don't run two things at once.

Thanks for straightening me out there Nick. I'll try to more selective in my phrasing. It's hard to properly as a question when you don't know what thell your'e doing... LOL! I'm the first to admit I'm not a microcontroller expert. It looks like learning how to use interrupts is what I need to pursue at this point.

Hi, Have a look at the timers too, they are effectively a separate hardware module that you set up and let run. You can use it it various modes to generate pulses, interrupts and even to measure input intervals all of which relate to your original post. As the timers run in hardware and are driven by the system clock, code that is also running does not stop the timers or effect their accuracy.

Try and read the data sheets sections on timers, the register bits are litle switches that you turn on or off to setup the timer mode and characteristics, the code might look a bit strange to begin with, but there are lots of examples of using the timers directly.

Duane b rcarduino.blogspot.com

I will repeat what everybody else has said, explain what you are trying to do..

In your "example" you are just while count not complete

If your pseudo-code is what you are trying to do, check millis() or micros() and the fade delay example sketch..

btw, there is a limit to how fast blinking of a led you will see and it is >10 milliseconds IIRC

hypercode: Thanks for straightening me out there Nick. I'll try to more selective in my phrasing. It's hard to properly as a question when you don't know what thell your'e doing ...

OK, well here's a tip. Rather than guessing how your problem needs to be solved (running multiple functions independently) and then asking how to achieve this, you will get a more meaningful and helpful response if you describe what you are actually trying to do. For example: "I am trying to control the air pump and the heater on my aquarium simultaneously". Then people can chip in with helpful suggestions. But something like "running multiple functions" and "but the PIC16 can do that" are just basically going to get people to reply "you can't do that", which hasn't really helped you.

This may help:

http://www.gammon.com.au/interrupts

Inside that are tips about interrupts and also using timers. Timers, as DuaneB said, effectively let you do things independently, because the hardware is counting away while you are doing something else.

Also maybe read this:

http://www.gammon.com.au/blink