UIflow power functions Core INK
-
Does anyone know how the uiflow power functions for Core INK are supposed to work?
There is
- power.off()
- power.restart_after_seconds()
- power.restart_on()
- power.on()
off() seems to switch off* the device.
restart_after_seconds() takes one int argument (seconds I assume). It also seem to switch off* the device. But it does not restart after the number of seconds given.
restart_on() haven't tried it, but I assume the same as restart_after_seconds() except it takes a time (RTC need to be set then) as argument instead of a delay.
on() seems meaningless to me. How can this function be called if the device is off?
*)I see the green led switch off when the device is running on its internal battery only i.e. no USB connected.
-
After some further testing I can follow up a bit here.
The power.restart_after_seconds(<int sec>) does indeed work as expected as long as there is always battery connected to the unit.
I however took out the battery of my unit because I am planning to use it with a larger external battery. After being without battery (and other power sources) the unit stopped to wake-up after the given time.
In my desperation to find a solution I switched from Uiflow (MicroPython) to C++ Arduino and tried the shutdown(<int sec>) function..... and it worked as expected. By coincidence then, I switched (flashed) back again to Uiflow (without removing the battery) and now the power.restart_after_seconds() was working again.I have now confirmed the following several times:
I Remove all power sources including internal battery and short BAT/GND or leave powerless for some hours: wake-up part of power.restart_after_seconds(<int sec>) does not work any more.I then flash and run once a simple Arduino sketch like this:
#include "M5CoreInk.h"
void setup() {
M5.begin(); // Initialize CoreInk.
//M5.shutdown(10);
}
void loop() {
//Nothing here
}
(note I just call the M5.begin() once in setup() and nothing else)Then while keeping the battery connected I flash back to UIflow again and the power.restart_after_seconds(<int sec>) wake-up as expected.
I suspect there is some kind of initialization for the BM8563 in UIflow missing or failing.
I have tried to browse though functions (dir(), Help()) in the m5stack library:
and I found an tried m5stack.power.power.init() without any luck.Does anyone have some tips to where I should look for a solution?
-
It will fail if you removed the internal battery because the battery powers an RTC which is used for the sleep timer
-
Hello ajb2k3,
Thanks for your comment!Yes, agree the RTC (BM8563) needs power during the sleep period.
Sorry but it seems I wasn't clear in my previous description: The tests described above are all done with battery power only. I feed the unit from an external battery through the BAT and GND pins via the female bus header at the underside of the CoreINK. And I do not remove the battery while the unit is sleeping - only between the tests.
What I did is:
- Firmware latest UIflow. Load a simple MicroPython program that waits a bit and then calls power.restart_after_seconds(10)
- disconnect USB while leaving external battery connected (BAT/GND) via amp-meter.
- press reset button and then power on button
- unit starts, waits and goes to sleep
- unit wakes up after 10 sec waits a bit and goes to sleep again
- let the unit loop through step 5 a few times. The amp meter (I-bat)shows less than 100 µA while sleeping and about 50 mA while running.
- remove the battery and leave off for a while or short BAT/GND
- reconnect battery
- reset button and then power on button (same as step 3)
- unit starts, waits and goes to sleep (program is the same)
- unit never wakes up
- try manual reset and power up (like step 3) a few times but unit is now unable to wake up after each time power.restart_after_seconds(10) is called.
- connect USB and flash simple Arduino program that just calls M5.begin()
- Run Arduino program one time
- flash back UI firmware and load same MicroPython program as in step 1.
- Continuing as from step 2
- The unit is now able to wake-up again and keeps looping as before like in step 5
-
Ahh I was assuming you were using a usb power bank and so the automatic shutdown was causing the problem.
Sound like the internal battery is not charging and so the BPS in cutting out which is used by the ULP and the RTC for the low power sleep. From your description it looks like it only works with external power which leads me to the conclusion Of the dead internal battery
-
Thanks for your comments.
As mentioned the internal battery is removed, but the external battery is fine and charging when the unit is connected to USB. I have a Amp-meter in the loop where I can monitor I_bat.Let me try to explain in a different way:
The unit is connected to the external battery only (no USB ) and loaded with a UIflow-program that calls power.restart_after_seconds(n). Everything works as expected. The unit goes to sleep and wakes up after n seconds. I can reset and power down/up etc. etc. and it is still sleeping and waking up as expected - every time.Then I disconnect the battery for a while for some reason - say to change the battery or simply because I don't need to use the unit for a while.
When I reconnect the battery and power up, everything still works except the wake-up. The unit goes to sleep but does not wake up after n seconds any more.
Erasing flash, reloading firmware and reloading the (same) program does not help - the only thing that helps so far is to flash and run M5.begin() from the Arduino C++ library and then flash back to the UIflow firmware.
I think there is some kind of setup for or in the RTC which is not truly persistent i.e. it relies on constant power from the battery and that the (re)initialization of this particular setup is missing or buggy in the Uiflow firmware.
-
As I said, the battery 🪫 a used by the RTC and so removing the battery resets the RTC meaning you will need to reset the RTC every time yo reconnect power.
That’s why RTC modules normally have (and old computer bios’s ) have backup batteries to keep the RTC memory settings. -
I fully agree with your last reply!
but to comment ".... you will need to reset the RTC every time yo reconnect power.":
I would be more than happy to do so in my program, but there seems to be no way to do it within the scope of the UIflow firmware - I can't find any power.rtc_init() function or what ever it could be called.
The only workaround (as far as I have found) is to use the Arduino C++ M5.begin() and then flash back the UIflow firmwareAnyone who replace the battery in their CoreINK risks "bricking" the low power sleep functionality unless they read this thread ;)
By the way, do you have any idea to what the power.on() function is for? It seems meaningless to be able to power on programmatically?
-
There is a whole section for setting the RTC in UIFlow under the hardware section.
-
Yeah I have been looking there already and tried:
- "dunder" init() (one is normally not supposed to run "dunder" functions)
- set_datetime()
- enable_timer_interrupt()
None of those helped.
-
Update: some further notes and a workaround solution.
I decided to dig a bit deeper into how the BM8563 RTC works and how it is initialized by the M5Stack Arduino C++ library. Without going into all the details I have so far found out the following:
Taking out the battery and leaving the CoreINK powerless does not in it self lead to the problem, as I have stated earlier in this thread. I seems the reason is some registers of the RTC sometimes become corrupted. Exactly how this happens, I'm not sure of, but one way may be when power (aka. the battery) is removed while data are written via I2C to the RTC. Important is however the matter of the fact: it can happen!
Apparently the the UIFlow firmware does not reset these registers correctly at start up. Digging into the Arduino library (which I knew could fix problem) I found the RTC init routine which resets the three control registers* of the BM8563. I then thought I could do the same with the I2C library in UIFlow. And sure enough, it works. So the workaround is to run the following code:
import i2c_bus i2c0 = i2c_bus.easyI2C(i2c_bus.M_BUS, 0x51, freq=400000) i2c0.write_u8(0x00, 0x00) i2c0.write_u8(0x01, 0x00) i2c0.write_u8(0x0D, 0x00)
some where in your script before the
m5stack.power.restart_after_seconds(n)
is called.
I haven't tested but I suppose it is the same if you use:
m5stack.power.restart_on(minutes=n, hours=n, date=n, weekday=n)
Notes to above code:
Please use the UIFlow I2C library (import i2c_bus) as the native Micropython I2C library (machine.I2C) messes up the "internal" I2C communication of the UIFlow firmware.
i2c_bus.M_BUS = (21,22) aka I2C pins for the BM8563 on the CoreINK
0x51 is the I2C address of the BM8563
0x00,0x01 and 0x0D are the control registers which are set to 0x00
The Arduino library for RTC init for comparison :void RTC::begin(void) { Wire1.begin(21, 22); WriteReg(0x00, 0x00); WriteReg(0x01, 0x00); WriteReg(0x0D, 0x00); }
*) please refer to the BM8563 datasheet for further details.
-
@cognitive5525 there is a way to do this in UIFlow and I will look into it over the weekend. Thanks for finding the cause and a walk around
-
Thank you for your insight and investigation.
I was facing same situation after my m5stack core2 lost its battery at all. Then I almost gave up development with m5stack since I'm not familiar to this ecosystem but it started restart again after your i2c cord had been tried.
Thank you so much again!!