-
Notifications
You must be signed in to change notification settings - Fork 83
millis() does not work during sleep #44
Description
Subject of the issue
checkUbloxI2C() uses millis() to check time and this time can be unreliable if the mcu goes to sleep since the SysTick on which millis() is based is stopped during sleep. Since checkUbloxI2C() uses a global "lastcheck" to track time elapsed between calls to checkUbloxI2C(), this causes an undesirable additional delay when checking the module after waking from sleep resulting in increased power consumption.
millis() is also used in waitForResponse() but since that function only uses millis() for relative time elapsed within the function itself, it is not a problem here except that generally, it would be preferable if waitForResponse() was not blocking.
My workaround for this problem was to use a tick from the real time clock instead of millis(). In the code snippet below, I have replaced the call to millis() with a global variable (volatile) that keeps track of the time from the rtc.
I suggest perhaps the "proper" solution might be abstract millis() using a virtual function and if the user needs to replace it with something else, it can be replaced by instantiating your own millis() function.
boolean SFE_UBLOX_GPS::checkUbloxI2C()
{
if (rtcTickMS - lastCheck >= I2C_POLLING_WAIT_MS)
{
//Get the number of bytes available from the module
uint16_t bytesAvailable = 0;
_i2cPort->beginTransmission(_gpsI2Caddress);
_i2cPort->write(0xFD); //0xFD (MSB) and 0xFE (LSB) are the registers that contain number of bytes available
if (_i2cPort->endTransmission(false) != 0) //Send a restart command. Do not release bus.
return (false); //Sensor did not ACK
_i2cPort->requestFrom((uint8_t)_gpsI2Caddress, (uint8_t)2);
if (_i2cPort->available())
{
uint8_t msb = _i2cPort->read();
uint8_t lsb = _i2cPort->read();
bytesAvailable = (uint16_t)msb << 8 | lsb;
}
if (bytesAvailable == 0)
{
if (_printDebug == true)
{
_debugSerial->println("No bytes available");
}
lastCheck = rtcTickMS; //Put off checking to avoid I2C bus traffic
return true;
}
I also noticed today commit e3e170e made in July to address an issue when the module is not ready. The commit adds a blocking delay in this event which causes additional power consumption. I would like to ask if there is something that can be done to eliminate the blocking delay.