user10590: For a school project we're working on a wearable device to track people's movement and heart rate. We use an Arduino Pro Mini with a heartbeat sensor and an accelerometer. The wearable device uses Bluetooth to send data, but only once or twice a day to save battery.
The problem we currently face is having the Arduino keep track of the accelerometer data while also reading the heartbeat sensor on a select interval. See the pseudo-code underneath. In what way (preferably without implementing too many libraries) could we merge these two loops so the accelerometer is read non-stop while keeping an interval (of about 30 minutes) between the heart beat readings? Any input would be greatly appreciated and if needed I can provide additional information.
void loop() {
// Heartbeat sensor loop
  while (array is not full) {
    delay(30 minutes);
    heartbeatArray[index++] = readHeartbeat();
  }
  sendData_Bluetooth(heartbeatArray);
  emptyArray();
// End of heartbeat sensor loop

// Accelerometer loop
  while (true)
    if (readAccelerometerData > limit)
      sendAlert();
// End of accelerometer loop
}


user6959: millis() is your great friend here.
millis() is function that returns the value of a 32 bit counter that is incremented once per millisecond. By adding the current value returned by millis() to a value representing the number of milliseconds that you want to 'delay' for you get a value that can be compared with the ongoing value returned by millis() to see if the time period has elapsed.
You can have as many variables as you wish which hold future timeout values for millis(0 - you perform the related action when millis() returns >= the saved value and reinitialise the value to some new future time.
Variables used to hold values from millis() MUST be type unsigned long.
The millis() timer rolls over every 49.7 days.
( = 2^32/1000 ms/s / 3600 s/hr / 24 h/day)

If your system may run for longer than that without being reset or powered down then handling millis()'s timer rollover must be known about.
It's MUCH easier than many people realise but best not dealt with here EXCEPT to know that if you add a constant to millis() and the value exceeds 2^32 and is truncated the comparisons with and subtractions wrt millis() still work correctly if the variable is type unsigned long. ("Why" is for elsewhere)


micros() is like unto millis() but returns the time since reset in microseconds. Depending on the processor used micros() may have a granularity of 4 uS rather than one uS. ie it steps by 4 counts every 4 uS rather than 1 count per uS.
micros() rolls over every 1.19 hours
( = 2^32 / 10^6/3600s/h)

// Example - not tested:
unsigned long DoitNow;  

void setup(){  
  DoitNow = millis() + 1800000; // Add half an hour of milliseconds 
 }  
void loop(){  
   if(millis() > DoitNow)  
   { Do heartbeat stuff;  
      DoitNow = millis() + 1800000; // Add another half hour of ms
   }  
 Do accelerometer stuff;  
}    


user10591: What you want to do is rather easy task, you just need to forget about delay() function. When writing some more complex programs using it is generally a bad idea, as it blocks code execution, so you won't get any sensor readings, communication, anything. Instead try something like this:
unsigned long delay1 = 100;
unsigned long delay2 = 1800000; //30 minutes in miliseconds
unsigned long t1, t2;

void setup() {
  t1 = t2 = millis();
}

void loop() {
  if(millis() - t1 > delay1) { //this will be executed every delay1 ms
    // do one part of code
    t1 = millis();
  }

  if(millis() - t2 > delay2) { //this will be executed every delay2 ms
    // do another part of code
    t2 = millis();
  }

  // here insert the code that should be executed as frequently as possible
  // (every loop passage)
}

There is also a nice Arduino library called TaskScheduler, that basically does the same thing: periodically executes different functions with different time intervals.

10590: <p>For a school project we're working on a wearable device to track people's movement and heart rate. We use an Arduino Pro Mini with a heartbeat sensor and an accelerometer. The wearable device uses Bluetooth to send data, but only once or twice a day to save battery.</p>

<p>The problem we currently face is having the Arduino keep track of the accelerometer data while also reading the heartbeat sensor on a select interval. See the pseudo-code underneath. In what way (preferably without implementing too many libraries) could we merge these two loops so the accelerometer is read non-stop while keeping an interval (of about 30 minutes) between the heart beat readings? Any input would be greatly appreciated and if needed I can provide additional information.</p>

<pre><code>void loop() {
// Heartbeat sensor loop
  while (array is not full) {
    delay(30 minutes);
    heartbeatArray[index++] = readHeartbeat();
  }
  sendData_Bluetooth(heartbeatArray);
  emptyArray();
// End of heartbeat sensor loop

// Accelerometer loop
  while (true)
    if (readAccelerometerData &gt; limit)
      sendAlert();
// End of accelerometer loop
}
</code></pre>
 6959: <p>millis() is your great friend here.</p>
<p>millis() is function that returns the value of a 32 bit counter that is incremented once per millisecond. By adding the current value returned by millis() to a value representing the number of milliseconds that you want to 'delay' for you get a value that can be compared with the ongoing value returned by millis() to see if the time period has elapsed.</p>
<p>You can have as many variables as you wish which hold future timeout values for millis(0 - you perform the related action when millis() returns &gt;= the saved value and reinitialise the value to some new future time.</p>
<p>Variables used to hold values from millis() <strong>MUST</strong> be type unsigned long.<br />
The millis() timer rolls over every 49.7 days.<br />
( = 2^32/1000 ms/s / 3600 s/hr / 24 h/day)</p>
<ul>
<li><p>If your system may run for longer than that without being reset or powered down then handling millis()'s timer rollover must be known about.</p>
<p>It's MUCH easier than many people realise but best not dealt with here EXCEPT to know that if you add a constant to millis() and the value exceeds 2^32 and is truncated the comparisons with and subtractions wrt millis() still work correctly if the variable is type unsigned long. (&quot;Why&quot; is for elsewhere)</p>
</li>
</ul>
<p>micros() is like unto millis() but returns the time since reset in microseconds. Depending on the processor used micros() may have a granularity of 4 uS rather than one uS. ie it steps by 4 counts every 4 uS rather than 1 count per uS.<br />
micros() rolls over every 1.19 hours<br />
( = 2^32 / 10^6/3600s/h)</p>
<hr />
<p>// <strong>Example - not tested:</strong></p>
<pre><code>unsigned long DoitNow;  

void setup(){  
  DoitNow = millis() + 1800000; // Add half an hour of milliseconds 
 }  
void loop(){  
   if(millis() &gt; DoitNow)  
   { Do heartbeat stuff;  
      DoitNow = millis() + 1800000; // Add another half hour of ms
   }  
 Do accelerometer stuff;  
}    
</code></pre>
 10591: <p>What you want to do is rather easy task, you just need to forget about <code>delay()</code> function. When writing some more complex programs using it is generally a bad idea, as it blocks code execution, so you won't get any sensor readings, communication, anything. Instead try something like this:</p>

<pre><code>unsigned long delay1 = 100;
unsigned long delay2 = 1800000; //30 minutes in miliseconds
unsigned long t1, t2;

void setup() {
  t1 = t2 = millis();
}

void loop() {
  if(millis() - t1 &gt; delay1) { //this will be executed every delay1 ms
    // do one part of code
    t1 = millis();
  }

  if(millis() - t2 &gt; delay2) { //this will be executed every delay2 ms
    // do another part of code
    t2 = millis();
  }

  // here insert the code that should be executed as frequently as possible
  // (every loop passage)
}
</code></pre>

<p>There is also a nice Arduino library called <a href="http://playground.arduino.cc/Code/TaskScheduler" rel="nofollow">TaskScheduler</a>, that basically does the same thing: periodically executes different functions with different time intervals.</p>
