-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can not reach low power state when radio is declared outside of main() #227
Comments
Thank you for raising this detailed GitHub issue. I am now notifying our internal issue triagers. |
@charlesmodrich-tc I have similar issues in #222. Did you find a solution? For tcxo control, I am exploring modifying the set_operation_mode call in the driver i.e. set to 0 when RF_OPMODE_SLEEP otherwise 1. But that still leaves a high residual ~300uA. |
Unfortunately no, I wasn't able to find a solution. Ultimately I was forced
to move away from Mbed OS for this reason since I wasn't able to get the
low current performance all of my devices would require.
…--
Charles Modrich | Senior Hardware Engineer
TeraCode | 405 Cochituate Road | Suite 205 | Framingham MA 01701
M: 847-951-7543 | F: 781-207-0724
http://www.teracode.com | LinkedIn
<https://www.linkedin.com/in/charlesmodrich/>
On Sat, Jun 26, 2021 at 4:58 AM Evan Davey ***@***.***> wrote:
@charlesmodrich-tc <https://github.com/charlesmodrich-tc> I have similar
issues in #222
<#222>. Did you
find a solution? For tcxo control, I am exploring modifying the
set_operation_mode call in the driver i.e. set to 0 when RF_OPMODE_SLEEP
otherwise 1. But that still leaves I high residual.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#227 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ARXQAUS7K7DS4CDEOWWATCDTUWQDTANCNFSM435LKRXQ>
.
|
@charlesmodrich-tc - very frustrating. |
It really is! I spent a lot of time and hope on this before giving up. |
Yes, have been in the same boat! Having to revert back to the manufacturer SDKs is its own path of pain given all the messy #defines to support multiple targets and tight coupling of business logic to SDK logic. It's a shame support resources for MBED seem to have dropped off recently and it is stuck being half a corporate project and half an open source project with neither seeming to have particularly strong momentum. |
@charlesmodrich-tc - I have been doing some more debugging, this time on a Murata ISJ dev board (link). This is a STM32L072 + SX126X radio. With the Murata supplied AT firmware, I measure this board at the expected 2uA, so I know this is the baseline. I am using a new example from scratch, but using the master branch of mbed-os (as I needed to make some non power related changes to the SX126X driver). With the code below, I am able to achieve an average of 50uA. Interestingly, if I power up the board (which puts the radio to sleep), then re-upload the code with the radio.sleep() line commented out, current falls to 11uA, which is very similar to the 14uA you measured. I think this is related to GPIO/peripheral configuration in sleep but I haven't been able to figure out why, or where I am losing 9uA relative to the AT firmware. mbed_app.json
main.cpp
|
This is not tested, not validated, so not recommended... |
@jeromecoutant - this line saves about 30uA . At the moment my objective is to just get current down to 2uA with nothing running, then start adding back functionality to be able to do a full LoRaWAN test so I'll admit I've been trying things such as that line without fulling understanding the impact. The 2uA firmware is written in https://www.st.com/en/embedded-software/i-cube-lrwan.html but I find the structure such a headache to deal with. |
That's interesting because I wanted to post a comment this night but went to bed before. In the meantime conversation has new comments. |
I really don't understand how can this structure give you headache (kidding), but I'm glad I don't feel alone on this ST structure 👍 |
@hallard - I have some E5's on order along with the https://www.seeedstudio.com/LoRa-E5-mini-STM32WLE5JC-p-4869.html. Is there a target already that works with this chip and can give low power? I don't care what chip I use at this point as long as I can get something functional - don't know if there is anyone using MBED lorawan in the real world. As to i-cube-lrwan, honestly my adaptions are relatively minor and I could probably mod it to get it working, but 😱 the business logic would be so tightly coupled with that structure I couldn't deliver in good conscience. |
Sure take a look there (not tested on Low Power yet ) for STM32WL i-cude-lrwan has been replaced by STM32Cube MCU Package for STM32WL series(SDK) may be it was too simple. |
@hallard thanks for the links. Not Low Power tested is the concern. I've tried the Type ABZ (custom build and DISCO LRWAN1), Type 1SJ and STM32L0/RFM95 (draguino LNS50 node) so far with no luck for easy low power < 10uA (and even struggling for <100uA). I guess the trade-off for using a simplified framework like MBED is you lose that fine-grain control to library implementations. Still, it is such a common problem I'd hope there would be sufficient community support / documentation to get things running at least with a viable battery life for a low power long-term node (i.e. 1 year plus). Especially for dev boards like the DISCO LRWAN1. |
Worth looking at this sample code https://os.mbed.com/users/kenjiArai/code/Check_DeepSleep_os6/ |
@hallard I have attempted something like the "LowPowerConfiguration" function before. Firstly, I don't think "AHBENR" exists for a L0 target (so I switched for "IOPENR"). Secondly, I think the presence of the radio messes with this code as I have experienced worse performance after calling such a function following radio.sleep (as in mA). Otherwise, I don't see anything obvious in this code that is doing anything I haven't tried before. I haven't found anything documented as to what happens to peripherals/gpio when deep sleep is called. |
BTW, with the exact some code and the LNS50 as a target (so swapping the SX126X driver for SX1276) I see 500uA. But I am not convinced the pin mappings for the SX1276 are correct for the RFM95 module (https://github.com/dragino/Lora/blob/master/LSN50/v2.0/LoRa%20ST%20Sensor%20Node%20v2.0.sch.pdf and https://raw.githubusercontent.com/dragino/Lora/master/LoRaST/v1.0/LoRa%20ST%20v1.0_Sch.pdf). |
Ok done some testing on my LoRa-E5 board, after removing all code of the sample (and all GPIO config such as LED and Button) here we go 1.43uA in deep sleep mode, perfect !!
{
"requires": ["bare-metal", "events", "lora", "mbedtls"],
"target_overrides": {
"*": {
"target.printf_lib": "std"
}
}
}
code // Include --------------------------------------------------------------------
#include "mbed.h"
// Constructor ----------------------------------------------------------------
//DigitalIn my_sw(BUTTON1);
//DigitalOut myled(LED1,1);
static BufferedSerial pc(CONSOLE_TX, CONSOLE_RX, 115200);
//------------------------------------------------------------------------------
// Control Program
//------------------------------------------------------------------------------
int main()
{
while (true) {
// myled = 0 ; // ON
// ThisThread::sleep_for(1s);
// myled = 1 ; // Off
// ThisThread::sleep_for(2s);
hal_deepsleep();
}
}
Please not that using |
@hallard - great, sounds promising. Is this the Seeed Studio dev board or one of your own? I think with bare metal you need to use thread_sleep_for rather than ThisThread::sleep_for for the sleep manager to work (or events.dispatch_forever() like I used). What's happening with the radio? Is it defaulting to off for this board? What are the settings for PeripheralPins.c? What is the system clock configuration? This code gives me ~1.14mA on the Type 1SJ dev board (which is most likely the radio being on). |
@evandavey yes it's my basic own board, pin definitions are here and the radio is included into the STM32WL chip.
As you can see as soon as I'm using this code consumption in sleep goes from 1.5uA to 2.9mA int main()
{
while (true) {
thread_sleep_for(5000);
}
} |
@hallard - I might be wrong on thread_sleep_for https://forums.mbed.com/t/clarification-on-os-6-empty-vs-os-6-bare-metal-example-programs-1-0-0/8950 and it is equivalent and doesn't call the sleep manager. What do you get using events.dispatch_forever()? Maybe the radio defaults to its sleep state on the STM32WL? |
Same thing with int main()
{
EventQueue queue;
queue.dispatch_forever();
}
{
"requires": ["bare-metal", "events", "lora", "mbedtls"],
"target_overrides": {
"*": {
"target.printf_lib": "std"
}
}
} |
Same code but not using bare-metal? |
Sorry same code, same config so yes |
Sorry, I meant, what do you get running the same code but not in bare-metal? |
Yeah but I’m on another project where I need murata to be to 2uA like with grumpyoldpizza framework so if team could solve this low power issue would be fine |
Certainly something with the init/deinit of pins, and the TCXO control, so at least we've discovered that. I wish they would separate out the MBED specific stuff from the driver stuff so that the driver logic could be kept up-to-date with the Semtech (or other) reference implementation. Kind of what they are moving to with HAL layer in https://github.com/Lora-net/sx126x_driver but looks like a lot of work to implement that with the current MBED way of doing things. |
Yeah and lorawan stack in current implementation is 1.0.2 so behind LoRa Mac node current version 1.0.4 and 1.1.0 hope they will be able to update the stack |
@evandavey Quick investigation shows that there is no control of txco off in loramac-node radio sleep/standby implementation void SX1276SetSleep( void )
{
TimerStop( &RxTimeoutTimer );
TimerStop( &TxTimeoutTimer );
TimerStop( &RxTimeoutSyncWord );
SX1276SetOpMode( RF_OPMODE_SLEEP );
// Disable TCXO radio is in SLEEP mode
SX1276SetBoardTcxo( false );
SX1276.Settings.State = RF_IDLE;
}
void SX1276SetStby( void )
{
TimerStop( &RxTimeoutTimer );
TimerStop( &TxTimeoutTimer );
TimerStop( &RxTimeoutSyncWord );
SX1276SetOpMode( RF_OPMODE_STANDBY );
SX1276.Settings.State = RF_IDLE;
} mbed radio sleep implementation void SX1276_LoRaRadio::sleep()
{
// stop timers
tx_timeout_timer.detach();
// put module in sleep mode
set_operation_mode(RF_OPMODE_SLEEP);
}
void SX1276_LoRaRadio::standby(void)
{
tx_timeout_timer.detach();
set_operation_mode(RF_OPMODE_STANDBY);
_rf_settings.state = RF_IDLE;
} I managed If anyone has an idea of why we can't go below, we take it. |
@hallard - thanks, that agrees with my analysis and the key seems to be the init/deinit code which I could never get working. I've also built a board to test out the AcSIP ST50H http://www.acsip.com.tw/index.php?action=products-detail&fid1=19&fid2=&fid3=&id=151 which should hopefully function the same as the E5 module. Had some board design issues so fixing them up now for testing hopefully in a few weeks. |
@evandavey Mainly I put the GPIO to type /**
* Sets the module in low power mode by disconnecting
* TX and RX submodules, turning off power amplifier etc.
*/
void SX1276_LoRaRadio::set_low_power_mode(bool status)
{
if (radio_is_active != status) {
radio_is_active = status;
if (status == true) {
_chip_select.input();
if (_rf_ctrls.rf_switch_ctl1 != NC) {
_rf_switch_ctl1.input();
}
if (_rf_ctrls.rf_switch_ctl2 != NC) {
_rf_switch_ctl2.input();
}
if (_rf_ctrls.pwr_amp_ctl != NC) {
_pwr_amp_ctl.input();
}
if (_rf_ctrls.txctl != NC) {
_txctl.input();
}
if (_rf_ctrls.rxctl != NC) {
_rxctl.input();
}
if (_rf_ctrls.ant_switch != NC) {
_ant_switch.input();
}
if (_rf_ctrls.tcxo != NC) {
_tcxo.input();
}
} else {
_chip_select.output();
_chip_select = 1;
if (_rf_ctrls.pwr_amp_ctl != NC) {
_pwr_amp_ctl.output();
_pwr_amp_ctl = 0;
}
if (_rf_ctrls.rf_switch_ctl1 != NC) {
_rf_switch_ctl1.output();
_rf_switch_ctl1 = 0;
}
if (_rf_ctrls.rf_switch_ctl2 != NC) {
_rf_switch_ctl2.output();
_rf_switch_ctl2 = 0;
}
if (_rf_ctrls.txctl != NC) {
_txctl.output();
_txctl = 0;
}
if (_rf_ctrls.rxctl != NC) {
_rxctl.output();
_rxctl = 0;
}
if (_rf_ctrls.ant_switch != NC) {
_ant_switch.output();
_ant_switch = 0;
}
if (_rf_ctrls.tcxo != NC) {
_tcxo.output();
_tcxo = 1;
ThisThread::sleep_for(5);
}
}
}
}
|
@hallard - have you pushed up changes in that repo? Not seeing your commits. From when I was testing, I was seeing some power impact deintiing the SPI pins but could never work out how to reinit them. I was trying calling the STM32 HAL calls rather than using MBED initially just to see if that would work. So copy/pasting the relevant init/deint sections from the STM32 Cube LoRaWAN libraries. |
This was un unpushed commit sorry, now it's done, but I did not touched SPI pins for now, may be next step de init SPI. |
@hallard - I have just built up a couple of Seeed LoRa E5 based boards and have done a real-world test. Over about 620m from node to gateway (RSSI ~-125-135, SNR: -13-14.5 but urban area with no line of sight and node indoors) so that's looking promising. Sampling (UART based) sensors including using mbed trace and sending via TTN. Seeing ~50uA in sleep but it's installed in a 3rd party carrier board so could be leakage there and 50uA 'good enough for Australia' (as Dave from the EEVBlog would say). Still trying to read VBAT using the ADC but otherwise seems good. Waiting on some AcSIP ST50H chips so I can test those too using the same platform. |
@evandavey you still want to sleep at 3uA on Murata with mbed 6? Looks like we looked at the wrong place with GPIO, I don't know how my partner found this one but looks like misconfiguration of DIO registers :-) |
1 similar comment
@evandavey you still want to sleep at 3uA on Murata with mbed 6? Looks like we looked at the wrong place with GPIO, I don't know how my partner found this one but looks like misconfiguration of DIO registers :-) |
Dear @evandavey Please, could you share how to configure Mbed to get 2uA. By the way, regarding reading de Vbat, I have done it using this code:
|
@IoTopenTech - no special configuration should be needed for the E5/STM32WLE5C using the latest mbed/drivers other than making sure you are not building a debug build. Have you tried the bare minimum code used by Charles above (using https://github.com/ARMmbed/stm32customtargets for the target)? I had some leakage from other components (power regulator) that could also be your issue. Thanks for the VBAT code - this is very similar to what I ended up using:
|
@hallard - thanks for the Murata info. Will try this when I get a chance. |
Thank you very much @evandavey Now I am getting 2.5uA after uplink. |
As we though initially with @evandavey it was a matter of GPIO but did not tried to reconfigure GPIO on SX1276 side, magic to do was on /* FIXME taken from set_modem, it reduces the power consumption
*from 300µA to 1.5µA */
write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode
write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., |
@hallard - will dig up an old Murata ABZ based board to test and report back. The Type 1SJ uses a SX126X radio so exploring how to do the equivalent. |
Any news on this. Working on a project and seeing large sleep current for a similar board. |
@carriegong - which board/radio in particular? |
@evandavey Custom Murata ABZ. I do not tick lora_fsm from start. Until some user input... But on sleep without ticking lora_fsm it seems to draw 3.4mA oddly. Can't seem to find what. Disabled all GPIO/ all inits.. and still the same. Seems like something else in radio needs to be off. |
@carriegong - not sure what you mean by ticking lora_fsm? But a few things to check/try:
|
@evandavey Like this lora_fsm |
@carriegong - the info here is mostly mbed specific so not sure how much help it will be as results vary significantly by framework due to implementation differences (which can be very hard to compare/audit). Have you tried https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0? (see #227 (comment)) or even the Loramac reference implementation https://github.com/Lora-net/LoRaMac-node? |
@evandavey would you be so kind sharing full LoRa test code Currently I am able to produce bare-bones low-power test but can't figure out the full picture.
|
@JenertsA - I will try to dig out the exact code I used, but it was pretty much the example in this repo but built for an E5/STM32WLE5C (using https://github.com/ARMmbed/stm32customtargets). What is the exact target/gateway combo you are trying? |
@evandavey I am using a custom RAK3172 board and RAK3172 target from previously mentioned smt32customtargets. |
@JenertsA - the main example is complicated by things like the duty cycle flags and supporting multiple targets but the main thing is that the API is event driven. The LoRa callbacks are hooked in https://github.com/ARMmbed/mbed-os-example-lorawan/blob/master/main.cpp#L110 and then handled https://github.com/ARMmbed/mbed-os-example-lorawan/blob/master/main.cpp#L216. |
Description of defect
Inability to enter sleep mode (or at least reach expected sleep mode average current) after calling
static LoRaWANInterface lorawan(radio);
when working with NRF52840-DK + SX1262MB2xAS mbed shieldeven when building with Develop profile. Results in average "sleep" current of ~6.5mA. Uncommenting all code before main() (except for above line) and removing all code except sleep_for within main() yields expected sleep current (~14uA).
Target(s) affected by this defect ?
NRF52840-DK
Toolchain(s) (name and version) displaying this defect ?
Mbed Studio 1.4.0
What version of Mbed-os are you using (tag or sha) ?
6.3.0
What version(s) of tools are you using. List all that apply (E.g. mbed-cli)
Mbed CLI 2
How is this defect reproduced ?
Set up 2 NRF52840 DK's: one with PowerProfilerKit, another with SX1262MB2xAS mbed shield. Connect both to PC via microUSB (not nRF USB). Have PPK DK power LoRa shield DK via External supply, switch power on LoRaDK ON, nRF ONLY switch, VEXT->nRF switch to ON. Load up nRF Connect utility for the power profiler kit application, and enable DUT power and monitoring.
Use the default example for this sketch, but remove most of the code such that all that remains looks as below:
change the following in mbed_app.json:
"target_overrides": { "*": { "platform.stdio-convert-newlines": true, "platform.stdio-baud-rate": 115200, "platform.default-serial-baud-rate": 115200, "lora.over-the-air-activation": true, "lora.duty-cycle-on": false, "lora.phy": "US915", "lora.device-eui": "{ 0x00, 0x80, 0xA0, 0xD0, 0x09, 0xEA, 0x82, 0x37 }", "lora.application-eui": "{ 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x03, 0xE4, 0x02 }", "lora.application-key": "{ 0xEE, 0xB6, 0x72, 0x7D, 0xEB, 0x52, 0x08, 0x1C, 0x2E, 0x32, 0xC4, 0x3B, 0xB8, 0x96, 0x86, 0x6D }", "target.components_add": ["SX126X"], "lora.app-port": 2, "lora.fsb-mask": "{0xFF00, 0x0000, 0x0000, 0x0000, 0x0002}" },
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\"", "MBED_TICKLESS=1"]
Now, compile, upload and compare the average currents when
static LoRaWANInterface lorawan(radio);
is commented, and uncommented. For me, results for commented are ~14uA average sleep current over 52ms period, while uncommented shows an average sleep current of approximately 6.5mA over 52ms period.The text was updated successfully, but these errors were encountered: