Power Consumption
-
Hi,
The m5stack is an impressive product!
I'm wondering about its use as a long term data logger, and didn't see any data on power consumption of the various modules, or what the deep sleep current is.
I'd like the power data so that I can calculate how long it could run on a battery waking up periodically to record data.
Has any one measured power consumption?Thanks.
Jim -
I am also interested in this.
From the data sheet, the chip itself draws 10uA in deep sleep. Integrator's boards draw between 12uA to 10mA. The m5stack isn't very power efficient and with the the "leaking" speaker amp it may be in the high teens. I'll measure mine when I get home on Monday.
In the meantime you can start with this tuto on deep sleep mode. The mention of a limitation, or could be a bug of the esp32, it needs to wait 500ms after wakeup or it randomly won't wake up again.
-
I received a USB amp meter, the Eversame dual and I'm afraid to say that the m5stack is very power hungy in deep sleep. I am reading 70 mA
The test program based on that link I gave you:#include <M5Stack.h>
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds /
#define TIME_TO_SLEEP 3 / Time ESP32 will go to sleep (in seconds) */RTC_DATA_ATTR int bootCount = 0;
void setup()
{
M5.begin();delay(500); if (bootCount == 0) //Run this only the first time { M5.Lcd.printf("first time"); } else { M5.Lcd.println(String(bootCount)); } bootCount = bootCount + 1; delay(3000); M5.Lcd.clear(); esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); esp_deep_sleep_start();
}
void loop()
{}
-
Thanks for measuring this!
-
And today deep sleep eats up 0.10A, either this meter is ~ or m5stack power consumption is whimsical. And after a few minutes deepsleep consumes 0.08A... I think what's happening here is the USB is charging the battery, as the battery is fuller the regulator drops current usage.
So I took out the battery module and tada - current usage is stable.
One core doing not much = 0.06A
One core heavy gfx = 0.08A
Two cores = 0.08A
Two cores with heavy gfx = 0.10A
deep sleep = 0.01A, that's 1000x the esp32 specs but similar to boards which don't even have a display. -
Just another experience:
I put my Fluke current meter in series with the battery connection on my M5StickC.
With screen on it draws approximately 80ma
When I call M5.Axp.DeepSleep(); 15ma.There's something very wrong going on here....
-
@Morris45 In m5stick there is others chip that consumes power like power management chip axp192 (it consumes power whole time),rtc and mic. esp32 itself when turned off consumes very little power. Somewhere in the forum they wrote that the grove socket has a voltage of 5V after turning off the power supply, so the inverter probably works, but I haven't checked it yet.
-
@morris45 there is some ways to improve it down to 2.44 mAh thanks to software improvements: https://community.m5stack.com/post/4949
But there is an issue with the device and even when "powering off the "board" thanks to the AXP192 there is still 1.92 mAh consumed :'(
-
@oliv I've been trying to solve this again and I've found something very interesting in my project:
Using the sleep.ino in the examples in Arduino IDE with M5StickC library installed I've confirmed this:
When the device goes into light sleep it draws 6mA
when it goes into deepsleep it draws 2mA
however if I press the power button just once, in deepsleep it draws 25mA for that loop of the program, once you press button A again the current consumption returns to 2mA in deepsleep.
However, when I run the program for using my M5StickC as a smart watch, when in deepsleep it draws 2mA in deepsleep like normal UNTIL I press the power button just once. If I do that, it draws 16mA in deepsleep! The only way to stop it doing this is to press the power button for 6 seconds to turn it off, and then press the power button once more. If I do that, it goes back to drawing 2mA in sleep once again.
Do you have any idea what's causing this?
Here's my code:
#include <M5StickC.h> RTC_TimeTypeDef RTC_TimeStruct; RTC_DateTypeDef RTC_DateStruct; uint8_t led_count = 15; long brightnessTime, tiltTime = 0, tiltTime2 = 0; float b, c = 0; int battery = 0; float accX = 0; float accY = 0; float accZ = 0; #define TFT_GREY 0x5AEB float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; // Saved H, M, S x & y multipliers float sdeg = 0, mdeg = 0, hdeg = 0; uint16_t osx = 120, osy = 120, omx = 120, omy = 120, ohx = 120, ohy = 120; // Saved H, M, S x & y coords uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0; uint32_t targetTime = 0; // for next 1 second timeout static uint8_t conv2d(const char* p); // Forward declaration needed for IDE 1.6.x uint8_t hh, mm, ss, YY, MM, DD, dd; boolean initial = 1; void setup() { //COMMENT next line after first upload M5.begin(); // Wire.begin(32, 33); pinMode(M5_BUTTON_HOME, INPUT); pinMode(M5_BUTTON_RST, INPUT); pinMode(M5_BUTTON_HOME, INPUT_PULLUP); pinMode(33, OUTPUT); esp_sleep_enable_ext0_wakeup(GPIO_NUM_37, 0); //1 = High, 0 = Low //COMMENT next 12 lines after first upload hh = conv2d(__TIME__), mm = conv2d(__TIME__ + 3), ss = conv2d(__TIME__ + 6); // Get H, M, S from compile time RTC_TimeTypeDef TimeStruct; TimeStruct.Hours = 23; TimeStruct.Minutes = 10; TimeStruct.Seconds = 30; M5.Rtc.SetTime(&TimeStruct); RTC_DateTypeDef DateStruct; DateStruct.WeekDay = 6; DateStruct.Month = 06; DateStruct.Date = 12; DateStruct.Year = 2020; M5.Rtc.SetData(&DateStruct); //COMMENT UPTO HERE M5.Rtc.GetTime(&RTC_TimeStruct); hh = RTC_TimeStruct.Hours; mm = RTC_TimeStruct.Minutes; ss = RTC_TimeStruct.Seconds; M5.Rtc.GetData(&RTC_DateStruct); YY = RTC_DateStruct.Year; MM = RTC_DateStruct.Month; DD = RTC_DateStruct.Date; dd = RTC_DateStruct.WeekDay; M5.Lcd.setRotation(1); M5.Lcd.fillScreen(TFT_GREY); M5.Lcd.setTextColor(TFT_WHITE, TFT_GREY); // Adding a background colour erases previous text automatically // Draw clock face M5.Lcd.fillCircle(40, 40, 40, TFT_BLACK); M5.Lcd.fillCircle(40, 40, 36, TFT_BLACK); // Draw 12 lines for (int i = 0; i < 360; i += 30) { sx = cos((i - 90) * 0.0174532925); sy = sin((i - 90) * 0.0174532925); x0 = sx * 38 + 40; yy0 = sy * 38 + 40; x1 = sx * 32 + 40; yy1 = sy * 32 + 40; M5.Lcd.drawLine(x0, yy0, x1, yy1, TFT_WHITE); } // Draw 60 dots for (int i = 0; i < 360; i += 6) { sx = cos((i - 90) * 0.0174532925); sy = sin((i - 90) * 0.0174532925); x0 = sx * 34 + 40; yy0 = sy * 34 + 40; // Draw minute markers M5.Lcd.drawPixel(x0, yy0, TFT_WHITE); // Draw main quadrant dots if (i == 0 || i == 180) M5.Lcd.fillCircle(x0, yy0, 2, TFT_WHITE); if (i == 90 || i == 270) M5.Lcd.fillCircle(x0, yy0, 2, TFT_WHITE); } M5.Lcd.fillCircle(40, 40, 2, TFT_WHITE); M5.Lcd.drawCentreString("WAyKEy", 120, 260, 4); targetTime = millis() + 1000; M5.Axp.ScreenBreath(9); M5.MPU6886.Init(); } void brightnessT() { M5.MPU6886.getAccelData(&accX, &accY, &accZ); accX *= 1000; accY *= 1000; if ((accX > (200) && (accX < 900)) && ((accY > 0 - 300) && (accY < 300))) { if (millis() > (tiltTime + 500)) { M5.Axp.ScreenBreath(12); brightnessTime = millis(); // while (accX < (0 - 500) && ((accY > 0) && (accY < 100))); } } else tiltTime = millis(); if (brightnessTime < millis() - 2000) { M5.Axp.ScreenBreath(7); brightnessTime = 0; } } void wristWatch() { if (targetTime < millis()) { targetTime += 1000; ss++; // Advance second if (ss == 60) { ss = 0; mm++; // Advance minute if (mm > 59) { mm = 0; hh++; // Advance hour if (hh > 23) { hh = 0; } } } // Pre-compute hand degrees, x & y coords for a fast screen update sdeg = ss * 6; // 0-59 -> 0-354 mdeg = mm * 6 + sdeg * 0.01666667; // 0-59 -> 0-360 - includes seconds hdeg = hh * 30 + mdeg * 0.0833333; // 0-11 -> 0-360 - includes minutes and seconds hx = cos((hdeg - 90) * 0.0174532925); hy = sin((hdeg - 90) * 0.0174532925); mx = cos((mdeg - 90) * 0.0174532925); my = sin((mdeg - 90) * 0.0174532925); sx = cos((sdeg - 90) * 0.0174532925); sy = sin((sdeg - 90) * 0.0174532925); if (ss == 0 || initial) { initial = 0; // Erase hour and minute hand positions every minute M5.Lcd.drawLine(ohx, ohy, 40, 40, TFT_BLACK); ohx = hx * 15 + 40; ohy = hy * 15 + 40; M5.Lcd.drawLine(omx, omy, 40, 40, TFT_BLACK); omx = mx * 20 + 40; omy = my * 20 + 40; } // Redraw new hand positions, hour and minute hands not erased here to avoid flicker M5.Lcd.drawLine(osx, osy, 40, 40, TFT_BLACK); osx = sx * 25 + 40; osy = sy * 25 + 40; M5.Lcd.drawLine(osx, osy, 40, 40, TFT_RED); M5.Lcd.drawLine(ohx, ohy, 40, 40, TFT_WHITE); M5.Lcd.drawLine(omx, omy, 40, 40, TFT_WHITE); M5.Lcd.drawLine(osx, osy, 40, 40, TFT_RED); M5.Lcd.fillCircle(40, 40, 2, TFT_RED); } dd = RTC_DateStruct.WeekDay; weekDay(); Date(); } void weekDay() { M5.Lcd.setCursor(110, 12, 2); M5.Lcd.setTextColor(WHITE, TFT_GREY); // M5.Lcd.print(dd); switch (dd) { case 1: M5.Lcd.print("SUN"); break; case 2: M5.Lcd.print("MON"); break; case 3: M5.Lcd.print("TUE"); break; case 4: M5.Lcd.print("WED"); break; case 5: M5.Lcd.print("THU"); break; case 6: M5.Lcd.print("FRI"); break; case 0: M5.Lcd.print("SAT"); break; } } void Date() { M5.Lcd.setCursor(110, 26, 2); M5.Lcd.setTextColor(WHITE, TFT_GREY); M5.Lcd.print(DD); M5.Lcd.print('/'); M5.Lcd.print(MM); } void batteryLevel() { M5.Lcd.setCursor(110, 3, 1); c = M5.Axp.GetVapsData() * 1.4 / 1000; b = M5.Axp.GetVbatData() * 1.1 / 1000; // M5.Lcd.print(b); battery = ((b - 3.0) / 1.2) * 100; if (c >= 4.5) { M5.Lcd.setTextColor(TFT_YELLOW, TFT_GREY); M5.Lcd.print("CHG:"); } else { M5.Lcd.setTextColor(TFT_GREEN, TFT_GREY); M5.Lcd.print("BAT:"); } if (battery > 100) battery = 100; else if (battery < 100 && battery > 9) M5.Lcd.print(" "); else if (battery < 9) M5.Lcd.print(" "); if (battery < 10) M5.Axp.DeepSleep(); // if (digitalRead(M5_BUTTON_HOME) == LOW) { // while (digitalRead(M5_BUTTON_HOME) == LOW); // M5.Axp.DeepSleep(SLEEP_SEC(1)); // } M5.Lcd.print(battery); M5.Lcd.print("%"); } void batterySaver() { M5.MPU6886.getAccelData(&accX, &accY, &accZ); accX *= 1000; accY *= 1000; if (!((accX > (200) && (accX < 900)) && ((accY > 0 - 300) && (accY < 300)))) { if (millis() > (tiltTime2 + 3000)) { // M5.Axp.DeepSleep(); digitalWrite(33, LOW); M5.Axp.DeepSleep(SLEEP_SEC(20)); // while (accX < (0 - 500) && ((accY > 0) && (accY < 100))); } } else tiltTime2 = millis(); digitalWrite(33, HIGH); } void loop() { brightnessT(); wristWatch(); batteryLevel(); batterySaver(); } static uint8_t conv2d(const char* p) { uint8_t v = 0; if ('0' <= *p && *p <= '9') v = *p - '0'; return 10 * v + *++p - '0'; }
-
How do you guys track the amperage draw of the stick when sleeping? Do you take it apart, cut a power line, hook up a multimeter in between, and later resolder?
Also have you guys experimented with the difference between
M5.Axp.DeepSleep();
and
esp_deep_sleep_start();
?AFAIU Axp.DeepSleep is only supposed to turn off "external devices" (gyro, screen, etc.) but not the ESP itself, right?
And @Morris45 what does the
Wire.begin(32, 33);
line do in your code above? And why are we commenting outM5.begin()
? What's the battery life you're getting from your watch? I'm trying to do a simple infrared remote (that only wakes up when you first pres the main button) and even in full deep sleep, I'm only getting 2 days.