## Data Logger Shield - Code Walkthrough - Delay() question Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Data Logger Shield - Code Walkthrough - Delay() question

Your Code Walkthrough on the Data Logger Shield is very clear and helpful. Thanks for including that! I'm buying the shield tonight with some other parts.

I am stumped by the calculation for delay; could you explain this? Why not just use a fixed delay as defined in LOG_INTERVAL?

#define LOG_INTERVAL 1000 // mills between entries

In the "Timestamping" section:
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); // <-- What is being calculated here?

The "delay" formula
I ran this formula independently with fixed delay and got these results:

Code: Select all | TOGGLE FULL SIZE
`#define LOG_INTERVAL  1000 // millis between entriesunsigned long timeNow;void setup() {  Serial.begin(9600);}void loop() {    float delayTime;    timeNow = millis();    Serial.print(timeNow);    Serial.print("\t");    Serial.print(timeNow % LOG_INTERVAL);    Serial.print("\t");    Serial.println((LOG_INTERVAL -1) - (timeNow % LOG_INTERVAL));    delay(500);}`

Col 1 = millis
Col 2 = millis % LOG_Interval
Col 3 = (LOG_INTERVAL -1) - (timeNow % LOG_INTERVAL)
1439978 978 21
1440479 479 520
1440979 979 20
1441480 480 519

The values are being correctly calculated. I then ran using the variable delay per your provided code and got these results:

Code: Select all | TOGGLE FULL SIZE
`#define LOG_INTERVAL  1000 // millis between entriesunsigned long timeNow;void setup() {  Serial.begin(9600);}void loop() {    float delayTime;    timeNow = millis();    Serial.print(timeNow);    Serial.print("\t");    Serial.print(timeNow % LOG_INTERVAL);    Serial.print("\t");    Serial.println((LOG_INTERVAL -1) - (timeNow % LOG_INTERVAL));    delay((LOG_INTERVAL -1) - (timeNow % LOG_INTERVAL));}`

Col 1 = millis
Col 2 = millis % LOG_Interval
Col 3 = (LOG_INTERVAL -1) - (timeNow % LOG_INTERVAL)
17000 0 999
17999 999 0
17999 999 0
18000 0 999
19000 0 999
19999 999 0
20000 0 999
21000 0 999
21999 999 0
22000 0 999
23000 0 999
23999 999 0

Would appreciate any insights as to your thinking about the variable Delay calc. Thanks! SteveInCalif

Posts: 4
Joined: Mon Jan 14, 2019 11:37 pm

Re: Data Logger Shield - Code Walkthrough - Delay() question

The formula creates a variable delay that lasts the difference between the time running since the last delay and when the next action should start. This will create an action as close to LOG_INTERVAL as possible no matter how long the code running took (in case a sensor reading took longer than expected.) franklin97355

Posts: 21089
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: Data Logger Shield - Code Walkthrough - Delay() question

Thanks. So conceptually what you are doing is a bit similar to using...

if (millis() - debounceStart >= debounceDuration )

...to account for execution time? This approach assures that the next invocation will be regularly spaced after accounting for execution time.

It sounds like the approach you use in your formula is to modify the delay to try to stay as close to the desired interval as possible. Is that right?

I'm still struggling to understand how your formula works. SteveInCalif

Posts: 4
Joined: Mon Jan 14, 2019 11:37 pm

Re: Data Logger Shield - Code Walkthrough - Delay() question

I'm still struggling to understand how your formula works.

The calculation in question:
Code: Select all | TOGGLE FULL SIZE
`delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); // <-- What is being calculated here?`

Take it one piece at a time - this part calculates the current time - modulo the LOG_INTERVAL. The result of this calculation will be zero at every LOG_INTERVAL.
Code: Select all | TOGGLE FULL SIZE
`(millis() % LOG_INTERVAL)`

The minus 1 here is because the result of the modulo ('%') operator is zero relative
Code: Select all | TOGGLE FULL SIZE
`(LOG_INTERVAL -1)`

And the difference between the two is how long you need to wait for the LOG_INTERVAL to come around again
Code: Select all | TOGGLE FULL SIZE
`(LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)`

A simpler way of achieving the same thing would be:

Code: Select all | TOGGLE FULL SIZE
`while((millis() % LOG_INTERVAL) != 0) { /* do nothing */}` 