1

I have a sketch with multiple functions in it. The 2 main functions in that sketch are get_data and post_data.

Now these functions are called from loop(). The thing is I want these functions to run at different times. Basically I want the get_data function to run once every 4 minutes and the post_data function to run once every hour. How can I achieve that?

As far as I know, you can't run multiple programs together on an Arduino Mega.

P.S: I'm new to Arduino programming.

  • 1
    in loop function ... check time ... if 4 minutes then call get_data ... check time ... if 1 hour then call post_data .... that's it, the whole loop..... you could also check time for the 1 hour at the end of get_data and call post_data from there – jsotola Dec 30 '17 at 6:54
  • can u tell how can i check time in arduino mega with wiznet w5100 ethernet shield .. I dont know much about arduino since am new to it – Mihir Joshi Dec 30 '17 at 7:09
  • google arduino time .... also this .... pjrc.com/teensy/td_libs_TimeAlarms.html – jsotola Dec 30 '17 at 7:39
  • 2
    Look at the “Blink Without Delay” Arduino tutorial. – Edgar Bonet Dec 30 '17 at 14:46
1

I imagine that you tried to figure out how to do it whit the delay() function (if it's not your case, it is for most Arduino beginners). Well... you can't use delay() in this case (and in most other cases) because it completely blocks the program for a given time (1) (except for interrupts, but i won't treat interrupts here). In general it is better not to use delays, except for very simple programs or in initialisation routines (i.e. in stuff you usually put in setup()).


Since your delays are quite long I imagine that you don't need much precision (i.e. you don't need to be more precise than a millisecond). So you could do like that:

void setup() {}

// Times at which we last called the functions
// (These are global variables, which are in general best avoided)
unsigned long lastGetData = 0;
unsigned long lastPostData = 0;

void loop() {

    //                           min.  sec.  milliseconds
    if(millis() - lastGetData >= 4   * 60  * 1000) {

        lastGetData = millis();
        get_Data();
    }

    //                            min.  sec.  milliseconds
    if(millis() - lastPostData >= 60  * 60  * 1000) {

        lastPostData = millis();
        post_Data();
    }
}

void get_Data() {
    // ...
}

void post_Data() {
    // ...
}

Notes:

  • millis() returns the time since the startup of the Arduino in millisecond. To get more precision you could also use micros() which returns the same but in microseconds (then you would need to multiply the number in the if condition by 1000).
  • you can add as much functions as you want whit different execution delays. But you must keep every function as short as possible, i.e. you must not use delay()s, because while executing a function if the time to execute another function comes that function will only be called after the end of the current one.
  • I used the => sign, and not ==, so that even if the loop doesn't evaluates one if condition in the very milliseconds in which it becomes true it can positively evaluate it some milliseconds later (e.g. after the end of another running function).
  • I took the liberty to fix a few bugs: the time comparison was backwards, the test was not rollover-safe, and get/post were mixed up. – Edgar Bonet Dec 30 '17 at 14:45
  • @EdgarBonet, changed your code so that the run time of get_Data() does not affect the 4 second period (same for post_Data()) – jsotola Dec 30 '17 at 19:34
  • @jsotola: 1) If you want the average period to not be affected by the time taken by the code to run, you should just replace lastGetData = millis(); by lastGetData += GET_DATA_PERIOD;. Your proposed edit does not achieve the promised constant period: think for example about the interaction between the getData() code and the postData() timing. 2) When you propose such sort of edit, there is no reason to also change the naming style of the functions. – Edgar Bonet Dec 30 '17 at 22:00
  • @EdgarBonet Firs of all, thank you for the first edit!! ;) --- About your last comment, wouldn't that interaction also affect a lastGetData += GET_DATA_PERIOD; implementation? In any case I edited according to jsotola's comment because I think it's slightly more consistent and easier for a vary beginner to understand (it's time? first reset timer, then perform action, like you would do with a real life timer) and it increases the precision of the period if getData() and postData() take a variable amount of time to execute. – noearchimede Dec 30 '17 at 22:28
  • @EdgarBonet, no offence intended. ... 1) you are absolutely correct. i only changed it to point out that it is something to think about. .... 2) the OP used that naming style in the question. ... – jsotola Dec 30 '17 at 22:32
0

I think you can use timer for it. In microcontroller with c you can use interrupts. You will need one timer and two compare interrupts. In the interrupts you can set different flags.

For example in first interrupt:

....
getSomething = true;
....

For example in second interrupt:

....
postSomething = true;
....

For example in your loop:

....
if(postSomething){
//your code to post something 
postSomething = false;
}

if(getSomething){
//your code to get something
getSomething = false;
}

These functions are only called when the timer interrupt is called (the time reached). In the Handler you set the flag (do not execute big code). In loop you can check if a flag is set and execute than the code. I think in Arduino you can do the same.

  • 2
    Using a hardware timer for such slow things adds useless complexity. – Edgar Bonet Dec 30 '17 at 14:39
0

If you don't need absolute precision, I've written a timer class that doesn't use an interrupt: TimerAction. Usage to simply subclass the base object, define an action() method in the subclass, construct your subclass defining the time interval to run, and place a call to the object's loop() method in your main loop() function in every sketch.

In your case, you'd create a subclass for each of your get_data and post_data actions. This would require two objects to be constructed, and both of them having their loop() method called in the main loop() function.

0

If it works in your situation:

void loop() {
  static int n;

  delay(4 * 60000);
  get_data();

  if (n-- == 0) {
    post_data();
    n = 14;
  }
}

You may need to adjust the 14 and post-decrement to fit your needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.