Question about ESP32 millis() counter?

Hello,

I have this kind of question. Is there any limitation about max millis() counter? I mean does it matter if currenttime in millis counts up certain value and the whole loop stops?
I’m using millis() in order to set one counter to 0. At the moment ESP32 plugged to serial monitor about 23hours ticking, the millis() was working fine.
If the counter have not been activated, the currenttime=millis() always ticking.
Here is the part of the code which I’m using for the timer:

// Flag variable to keep track if alert SMS was sent or not
bool smsSent = false;
bool timer = false;
bool smscountermax=false;
unsigned long smscounter= 0; 
unsigned long previousMillistemprst = 0;
// constants won't change:
const int tempresetinterval = 3600000;

void_loop()
if((t > temperatureThresholdHI) && !smsSent && !smscountermax){
   String smsMessage = String("Temperature above threshold: ") + 
           String(t) + String("C") + String("\nHumidity=") + String(h) +String("%");
    modem.sendSMS(SMS_TARGET, smsMessage);
     SerialMon.println("\nSending SMS:");
      SerialMon.println(smsMessage);
      smsSent = true;
      smscounter++;
 
    }
    if((t < temperatureThresholdLO) && !smsSent && !smscountermax){
   String smsMessage = String("Temperature below threshold: ") + 
           String(t) + String("C")+ String("\nHumidity=") + String(h) +String("%");
    modem.sendSMS(SMS_TARGET, smsMessage);
      SerialMon.println("\nSending SMS:");
      SerialMon.println(smsMessage);
      smsSent = true;
      smscounter++;
     
      
   }
    unsigned long currenttime=millis(); 
   if (t < temperatureThresholdHI && t > temperatureThresholdLO && smsSent && !timer) {
    // save the last time when the timer was activated
       previousMillistemprst=currenttime;
    timer = true; 
    
   }
// if t values are going over certain values the counter will be set to false again.
   else if(t>temperatureThresholdHI || t < temperatureThresholdLO && smsSent && timer)
   {
   timer = false;    
   }
// if the t values have been in the right place the counter will be set false again.
    if(currenttime-previousMillistemprst >= tempresetinterval && timer)
    {
    SerialMon.println("Setting SMS sent to false");
    smsSent = false;
    timer = false;
    delay(1000);
    }
Serial.println("Current milliseconds:"); Serial.println(currenttime-previousMillistemprst);//Print the time from the reset
 Serial.println("SMS is sent (1) or not (0):"); Serial.println(smsSent);
 Serial.println("Timer is active (1) or not (0):"); Serial.println(timer);
 Serial.println("SMS sent counter is:"); Serial.println(smscounter);
  delay(2500);
}

millis() does have a max limitation of uint32_t and rolls over after 49ish days.

The ESP32 uses a micro counter, esp_timer_get_time(), that is a unint64_t and rolls over after 200+ years.

Using the ESP32 counter requires a code change.

Here is a task using the ESP32 version of micros, esp_timer_get_time(), and the freeRTOS version of millis(), vTaskDelayUntil().

void fDoMoistureDetector( void * parameter )
{
  //wait for a mqtt connection
  while ( !MQTTclient.connected() )
  {
    vTaskDelay( 250 );
  }
  int      TimeToPublish = 5000000; //5000000uS
  int      TimeForADreading = 100 * 1000; // 100mS
  uint64_t TimePastPublish = esp_timer_get_time(); // used by publish
  uint64_t TimeADreading   = esp_timer_get_time();
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 10; //delay for 10mS
  float    RemainingMoisture = 100.0f; //prevents pump turn on during start up
  for (;;)
  {
    //read AD values every 100mS.
    if ( (esp_timer_get_time() - TimeADreading) >= TimeForADreading )
    {
      xEventGroupSetBits( eg, evtADCreading );
      TimeADreading = esp_timer_get_time();
    }
    xQueueReceive(xQ_RM, &RemainingMoisture, 0 ); //receive queue stuff no waiting
    //read gpio 0 is water level good. Yes: OK to run pump : no pump off.   remaining moisture good, denergize water pump otherwise energize water pump.
    if ( gpio_get_level( GPIO_NUM_0 ) )
    {
      if ( RemainingMoisture >= 40.0f ) {
        WaterPump0_off();
      }
      if ( RemainingMoisture <= 20.0f )
      {
        WaterPump0_on();
      }
      //xSemaphoreGive( sema_RemainingMoisture );
    } else {
      log_i( "water level bad " );
      WaterPump0_off();
    }
    // publish to MQTT every 5000000uS
    if ( (esp_timer_get_time() - TimePastPublish) >= TimeToPublish )
    {
      xQueueOverwrite( xQ_RemainingMoistureMQTT, (void *) &RemainingMoisture );// data for mqtt publish
      TimePastPublish = esp_timer_get_time(); // get next publish time
    }
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete( NULL );
}// end fDoMoistureDetector()

Is there any limitation about max millis() counter?

If millis() is used properly then no

Take a look at Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

The examples were written for processors where millis() returns an unsigned long and rolls over after 49 and a bit days, but the principles used are the same no matter what the type of variable as long as it is unsigned

So as a conclusion as long the varible is unsigned long it is okay?

unsigned long currenttime=millis();

What happens after 49days with the millis()? It resets to 0 and starts counting up?

Silverrido4:
So as a conclusion as long the varible is unsigned long it is okay?

as long as the math is done correctly.

Silverrido4:
What happens after 49days with the millis()? It resets to 0 and starts counting up?

Yes.

So as a conclusion as long the varible is unsigned long it is okay?

Yes

What happens after 49days with the millis()? It resets to 0 and starts counting up?

As long as you do the elapsed time comparison by using millis() - previousMillis using unsigned integers then nothing untoward will happen

It is easier to understand using smaller values such as a byte with a max value of 255 before rollover but it holds true for larger unsigned variables

Suppose that start time is 240 and end time is 250. The elapsed time is therefore 250 - 240, ie 10

Suppose that the start time is 250 and the end time is 5 after rollover at 255. Because the value is unsigned the calculation is 255 - 5 - 240, ie 10

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.