0

I have a program which measures temperatures every 30 minutes and sends them to a database. Immediately after running the program the first measurement is sent, however, the second (which should be sent after 30 min), is sent only after 1 hour. From then on the code works fine. The time is measured in millis. However, if I set the time difference to 28 minutes everything works fine from the beginning. What could be the reason for this? Is there a possibility that it goes to sleep mode? I don't understand why it works fine with 28 minutes and it stops working with 29 minutes?

Thanks in advance!

My code:

if (millis() - sendDataPrevMillis > 1740000)
  {
    sendDataPrevMillis = millis();

//other code

}

The only part I change, so it works is setting millis from 1740000 (29 minutes) to 1680000 (28 minutes).

4
  • 1
    Share your code with us. Mar 31 at 18:06
  • 1
    Please provide a minimal compilable example code, that shows your problem, not just a super small code snippet
    – chrisl
    Mar 31 at 21:01
  • 2
    use unsigned long as data type of sendDataPrevMillis
    – Juraj
    Apr 1 at 6:42
  • Did you make sure that millis() returns 0 at startup? For debugging you could print the initial value and any following if the condition is met. Apr 1 at 8:54
-1
  1. Although not strictly required, maybe use parentheses around millis() - sendDataPrevMillis for readability;
  2. I guess you will have initialised sendDataPrevMillis to 0 but the first time you assign sendDataPrevMillis to millis() some time will have elapsed since you evaluated. So calling millis() twice will give different results. That makes it less easy to see what is going on.

Suggestion to try:

long HALFHOUR = 30 * 60 * 1000L;

if ( (millis() % HALFHOUR ) == 0L ) {
    //measure and send
    //....
}

Hope this helps.

NB: % is what is called the 'modulo operator' see: https://www.geeksforgeeks.org/modulo-operator-in-c-cpp-with-examples/

5
  • I don't quite understand, what you mean with your second point. Calling millis() multiple times will give different results, when between the calls at least one millisecond passed. When initializing sendDataPrevMillis to zero, the time will be counted from startup (power cycle or reset). It is not very probable, that the code has run over half an hour before reaching the if statement the first time. So why should that matter?
    – chrisl
    Mar 31 at 21:04
  • The prob. of that will of course be very small indeed. what I was trying to say was about style: when the condition of the loop refers to the actual progressed millis (the first call) I would suggest to store exactly that value. Assignment within the condition if ( (currentMillis = millis()) - sendDataPrevMillis > 1740000) { sendDataPrevMillis = currentMillis; in order to prevent that becomes a bit messy, don't you think?
    – user75521
    Mar 31 at 21:14
  • You can do that with the assigment in if condition, but I don't think that this is better readable. Though that is subjective. In your second point you don't talk about style. As I now understand you say, that the millis() calls in the if condition and in the following inner statement give different results. I don't think that. The code runs way too fast for that. Even if the code happens to accidentally hit the exact point, where millis() increments, that will mean a max error of 1ms. Not important, when in this time range and also when you are using millis().
    – chrisl
    Mar 31 at 21:42
  • what are the odds of hitting that at the exact ms out of thousands?
    – dandavis
    Mar 31 at 22:51
  • 1
    This has too much potential to go wrong in a real time environment and isn't better code than the one in the question. Besides, timers that depend on millis() should always be unsigned long (or uint32_t).
    – StarCat
    Apr 1 at 7:50

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.