#define a very large number, failing

Hi, I am putting an ESP 01 to sleep for 60 minutes.

This line used to work in IDE V 1.8.10 ( I think it was that version )

pseudo code ...

#define  minutes  60000  // uSeconds in 1 minute.
#define  Low_battery_sleep_time   60 * minutes

ESP.deepSleep( Low_battery_sleep_time * 1000 ); // the time in microseconds

But if I try it in V1.8.19 the ESP 01 appears to crash with that code, as the TX led keeps transmitting.

But if I hard code the actual number of microseconds, it does work.
ESP.deepSleep( 3600000000 );

Is there a way to do this in a more human readable way, similar to how I used to do it ?
# Low_battery_sleep_time 60 // Minutes

Any ideas , thanks

I think you are running into integer overflow. Try adding a UL suffix on the end of your numbers to ensure it does the math in unsigned long numbers and doesn’t overflow and do something unexpected.

#define minutes 60000UL // uSeconds in 1 minute.

1 Like

that won't work

the deepSleep function expects and unsigned long long (64 bits not 32)

void deepSleep(uint64_t time_us);

by default integral literals are int (if they fit) and int on an ESP32 are only 32 bits and when you do maths with only 32 bits values, the results is limited to 32 bits. That' what happens when the preprocessors replaces the #define in this

ESP.deepSleep( Low_battery_sleep_time * 1000 ); // the time in microseconds

➜ it turns into

ESP.deepSleep( 60 * 60000 * 1000 ); // the time in microseconds

and 60 * 60000 * 1000 is evaluated as a 32 bit expression and it does not fit

I would suggest to not use #define in general as it does not carry a distinctive type (you could add the ull suffix to force the format but it's not great)

It's better to give the correct types to the compiler for every constant

constexpr uint64_t oneSecond = 1000000;                  // 1 million µs in 1 second
constexpr uint64_t oneMinute = oneSecond * 60;           // 60 seconds in one minute
constexpr uint64_t lowBatterySleepTime = oneMinute * 60; // 60 minutes
...
ESP.deepSleep(lowBatterySleepTime); // the time in microseconds

because I have a uint64_t for every multiplication, when evaluating the expression the compiler picks that type. so oneSecond * 60 is evaluated as uint64_t (same goes for oneMinute * 60).

If you really want to show you want to play with unsigned long long and be sure that's what being used for the math, you can go the extra mile and show the ull suffix for all the integral numbers

constexpr uint64_t oneSecond = 1000000ull;                  // 1 million µs in 1 second
constexpr uint64_t oneMinute = oneSecond * 60ull;           // 60 seconds in one minute
constexpr uint64_t lowBatterySleepTime = oneMinute * 60ull; // 60 minutes
...
ESP.deepSleep(lowBatterySleepTime); // the time in microseconds
3 Likes

Hi,

Thanks to you all and especially J-M-L, it is now working, I used

constexpr uint64_t oneSecond = 1000000;                  // 1 million µs in 1 second
constexpr uint64_t oneMinute = oneSecond * 60;           // 60 seconds in one minute
constexpr uint64_t lowBatterySleepTime = oneMinute * 60; // 60 minutes
...
ESP.deepSleep(lowBatterySleepTime); // the time in microseconds

:slightly_smiling_face:

great - have fun (hope you understood why it was failing)

Hi,

Yes you explained it very well, I would never have found that problem to be 64bit problem !
I knew it was crashing somewhere in the code as the TX led stayed on.

Funnily :upside_down_face: I have been chasing this problem on and off for the last week.
As recently I had changed various code, because I added ArduinoJson recently.

I thought that was the problem and was trying to find why, as that was the final line before sleeping, send out a JSON object literal: message via MQTT.

This morning i ruled that out, as I had added code to make sure it wasn't that.

So then I knew it was the sleep part, it wasn't until I added the full microsecond number that it worked, so that is why I came on here :slightly_smiling_face:

Thanks much appreciated.

kuddos for trying to solve it by yourself and the work for zooming in onto the faulty piece

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