Author Topic: [BitCloud] End device's power consumption  (Read 23562 times)

0 Members and 1 Guest are viewing this topic.

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
[BitCloud] End device's power consumption
« on: October 22, 2016, 09:34:52 am »
Hi Guys,

How can I make an ED to sleep?
I programmed Bitcloud's ED stack into an atmega256RFR2 with some additional codes.
CS_END_DEVICE_SLEEP_PERIOD is 60000. So basically ZB stack should be sleeping for a minute.

Anyway, I have some timers running @10000ms or so.

Power consumption seems always ~15mA@3.3V.
But I'd love to see it way lower when the chip is sleeping.

So I have two questions:
1.) how can I make it sleep?
2.) is it possible to have a timer which wakes up the chip, but not the ZB stack itself (for example to initate a measurement and store it for later sending when ZB is active).

Thank you,
danergo
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #1 on: October 22, 2016, 06:09:44 pm »
1.) how can I make it sleep?
What version of the stack? Older versions required you do to ZDO_SleepReq(), newer versions have a feature called Sleep When Idle. You call SYS_EnableSleepWhenIdle() and device will sleep all the time when there is nothing to do.

If you are already doing one of those things, then are you sure if this power consumption does not come from external circuitry on the board?

2.) is it possible to have a timer which wakes up the chip, but not the ZB stack itself (for example to initate a measurement and store it for later sending when ZB is active).
It is possible, but not easy. You will have to look though the HAL sleep code and modify it. I'm not even sure what type of modifications may be required without actually going in and doing it.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #2 on: October 23, 2016, 09:32:51 am »
You call SYS_EnableSleepWhenIdle() and device will sleep all the time when there is nothing to do.

I'm using Bitcloud 3.2.0, which I believe has this function.

If you are already doing one of those things, then are you sure if this power consumption does not come from external circuitry on the board?

There is not much else mounted on the board except this chip and the sorroundings (antena, balun, etc, what is mentioned in this chip's sheet).
I would not expect the rest to consume more than 1mA altogether.

It is possible, but not easy. You will have to look though the HAL sleep code and modify it. I'm not even sure what type of modifications may be required without actually going in and doing it.

Could you guide me a bit in this topic? It might be a material on the net somewhere maybe?
The problem is now, that I have 3 buttons handled by an AppTimer. Which would obviously wake up everything in every 50 or 100 ms.
I also looked at the docs, becaue I wanted to make it sleep manually, but in this case, all the AppTimers would only fire after CS_END_DEVICE_SLEEP_PERIOD. (which I'd increase as much as I can, for 15 or 30 mins).

Also, I found something interesting in the source code of sysIdleHandler.c on line 26-41:
"...If an end device wakes up on expiration of CS_SLEEP_PERIOD it polls
  its parent, otherwise it doesn't.
..."
It sounds for me that polling only occurs if CS_SLEEP_PERIOD expires. CS_SLEEP_PERIOD means CS_END_DEVICE_SLEEP_PERIOD in here?

Anyway what I'd like to do is to make HAL to differentiate it's waking up source:
1.) wake up by expiring CS_END_DEVICE_SLEEP_PERIOD timer (and only this one) -> normal wakeup procedure
2.) wake up by anything else -> calls wakeup routines but do _not_ wake up the RF.


Thanks.
« Last Edit: October 23, 2016, 04:25:58 pm by danergo »
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #3 on: October 23, 2016, 05:43:43 pm »
I'm using Bitcloud 3.2.0, which I believe has this function.
In this case you need to careful - if you enable this, then you don't have to manually go to sleep, but device will wakeup (briefly) on every hardware timer interrupt (10 ms for default system timer).

There is not much else mounted on the board except this chip and the sorroundings (antena, balun, etc, what is mentioned in this chip's sheet).
I would not expect the rest to consume more than 1mA altogether.
Have you ever seen this board to go to low power mode? Can you try to run unmodified WSNDemo and see what numbers do you get?

The problem is now, that I have 3 buttons handled by an AppTimer.
Why not pin change interrupts? Your scenario looks 1:1 like WSNDemo.

It sounds for me that polling only occurs if CS_SLEEP_PERIOD expires. CS_SLEEP_PERIOD means CS_END_DEVICE_SLEEP_PERIOD in here?
There is some mix in terminology. Internally there are 3 types of wakeups:
1. Very short (a few us) every 8 seconds - this is because of limited range of the asynchronous timer and it is unavoidable. This is totally transparent to the application.
2. MCU wakeup. When external interrupts happen. This one does not wake up the radio, but the stack (parts of it) is awake. You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed. It sounds like that's exactly what you want and it is already implemented.
3. CS_SLEEP_PERIOD - the whole stack and radio wakes up and sends the poll request.

Anyway what I'd like to do is to make HAL to differentiate it's waking up source:
It already does this. Look at WSNDemo application.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #4 on: October 23, 2016, 06:34:02 pm »
Have you ever seen this board to go to low power mode?
If I put a simple code inside the chip, I can reproduce the low power mode, yes.

Can you try to run unmodified WSNDemo and see what numbers do you get?
WSNDemo is not really suitable for this board, since it hasn't got any LEDs on it, and the Buttons might be overlapped with the WSNDemo's outputs, etc.
Anyway, I tried to follow WSNDemo's coding structure in my codes. This means that I use Bitcloud at the same way as WSNDemo.

The problem is now, that I have 3 buttons handled by an AppTimer.
Why not pin change interrupts? Your scenario looks 1:1 like WSNDemo.
This is the board's specification. Buttons are not tied to INT pins right now.

Anyway what I'd like to do is to make HAL to differentiate it's waking up source:
It already does this. Look at WSNDemo application.
HAL only differentiate between Timers (whichever expires first, apptimer or sleeptimer),
and External interrupts.
I mean differentiation between apptimers and sleeptimers. Do you believe it's somewhat possible?
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #5 on: October 23, 2016, 06:40:45 pm »
WSNDemo is not really suitable for this board, since it hasn't got any LEDs on it, and the Buttons might be overlapped with the WSNDemo's outputs, etc.
You can strip all the parts that don't match. The important part is sleep.

Your first order of business to make sure that this board can sleep (not even wake up) using BitCloud APIs.

This is the board's specification. Buttons are not tied to INT pins right now.
Some of Pin Change interrupts can wake up the MCU as well. They are actually better than real INT pins.

HAL only differentiate between Timers (whichever expires first, apptimer or sleeptimer),
and External interrupts.
I mean differentiation between apptimers and sleeptimers. Do you believe it's somewhat possible?
App timers can't wake up the MCU. When you have Sleep When Idle enabled, sleep timer is reprogrammed to wake up at the interval of the first AppTimer, so it appears that AppTimer woke up the system.

This is a very complicated system and messing  with it can be dangerous and result in some non obvious bugs.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #6 on: October 23, 2016, 07:49:52 pm »
WSNDemo is not really suitable for this board, since it hasn't got any LEDs on it, and the Buttons might be overlapped with the WSNDemo's outputs, etc.
You can strip all the parts that don't match. The important part is sleep.

Your first order of business to make sure that this board can sleep (not even wake up) using BitCloud APIs.
[/qoute]
[/qoute]

Will try that tomorrow, thank you!

This is the board's specification. Buttons are not tied to INT pins right now.
Some of Pin Change interrupts can wake up the MCU as well. They are actually better than real INT pins.

Unfortunately, buttons are connected to PD7 and PD6 and PD5. They are not either INTx or PCINTx.

This is a very complicated system and messing  with it can be dangerous and result in some non obvious bugs.

Totally agreed.
I'll redesign this board, but for now, I'd need to overcome with this.
What I'm thinking right now, is to use a custom timer instead of AppTimer which acts like an external interrupt.
In this case I would be able to use this: "2. MCU wakeup. When external interrupts happen. This one does not wake up the radio, but the stack (parts of it) is awake. You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed. It sounds like that's exactly what you want and it is already implemented."

This won't be a large hack, and could be done in user code instead of modifying HAL. What do you think?
There are only 2 questions:
1.) which timer could be used
2.) Is my assumption correct that when a timer overflows, it will result as an MCU wakeup?


Thank you!

 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #7 on: October 23, 2016, 07:53:40 pm »
What do you think?
Regular timers can't be wake up sources, only asynchronous TC2 can. And it is used by the sleep system in BC.

You also have WDT. If you are not using it in your normal operation, then you can use that as your timer.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #8 on: October 23, 2016, 08:01:22 pm »
What do you think?
Regular timers can't be wake up sources, only asynchronous TC2 can. And it is used by the sleep system in BC.

You also have WDT. If you are not using it in your normal operation, then you can use that as your timer.

Good point!
If I use WDT for handling the buttons, is this true?
"You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed."
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #9 on: October 23, 2016, 09:39:00 pm »
If I use WDT for handling the buttons, is this true?
"You need to manually call ZDO_WakeupReq() or ZDO_SleepReq(), depending on hoe you want to proceed."
Yes. Wake up on WDT will look just like wakeup on external interrupt.

You don't actually need to write any new code for this, BitCloud has APIs for WDT, including callback mode.

You need to remember that every time you go to sleep, poll sleep timer starts counting again, so you need to make sure that you still poll in a timely manner, even if buttons are pressed a lot.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #10 on: October 24, 2016, 06:58:45 am »
That sounds perfect.

Anyway, todays news:
I was able to put the board to sleep by issueing ZDO_SleepReq().
Total consumption is less than 1mA after this call.
However, is it possible to wakeup the stack but not the radio itself?
I have a button event which triggers a change on a display.
The display is handled by BC's state machine.

So I want to do some actions with the basic microcontroller before actually deciding on the further wakeup/sleep activities.

Is it possible to run BCs state machine with a radio sleeping?
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #11 on: October 24, 2016, 03:15:23 pm »
However, is it possible to wakeup the stack but not the radio itself?
It is possible to wake up the MCU without waking up the stack. That's exactly what happens when you wake up from an interrupt other than sleep timer interrupt (including WDT).

So I want to do some actions with the basic microcontroller before actually deciding on the further wakeup/sleep activities.
That's fine. Just do ZDO_WakeupReq() before you use the stack, or ZDO_SleepReq() if you want to go to sleep right away.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #12 on: October 24, 2016, 04:10:27 pm »
I might have some misunderstandings here.

ZDO_WakeupReq() will make the stack wake up, right?
In this case I'll be able to use BC's state machine, but does this also wake up the radio interface, or does not?

If it does not wake up the radio, how can I do that?

If it does wake up the radio, I guess I can live with it, and I need to call ZDO_SleepReq when I finished updating the screen and so on (basic tasks that doesn't require radio).
What I wanted to be 100% sure is that I don't want to wait for shutting down the radio after issueing ZDO_SleepReq (because in this case I hadn't wanted it to be waken up at all. So waiting for it would be an extra consumption for the battery just because I updated the screen with BC's state machine).



 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #13 on: October 24, 2016, 04:23:07 pm »
ZDO_WakeupReq() will make the stack wake up, right?
Yes.

In this case I'll be able to use BC's state machine, but does this also wake up the radio interface, or does not?
You don't need to wake up the stack to use the state machine. You only need to wake it up if you use any radio-related interfaces.

and I need to call ZDO_SleepReq when I finished updating the screen and so on (basic tasks that doesn't require radio).
You need to do this anyway, there is no other way to go back to sleep.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #14 on: October 24, 2016, 04:53:10 pm »
Thank you, I'm getting now closer and closer.

So: after a HW Interrupt (WDT) wakes up the chip, if I call a SYS_PostTask() function it will call my APL_TaskHandler() and don't go back to sleep automatically?
During this operation the radio interface is still sleeping, and I'm not gonna get ZDO_WakeUpInd() unless I issue ZDO_WakeupReq(). Right?
In this case, I can have an awakened chip, with running BC (with state machine), but powered down radio. To make the whole chip sleeping again, I have to call ZDO_SleepReq() and it will sleep until the next HW interrupt (or CS_END_DEVICE_SLEEP_PERIOD of time). Right?

So the point might be to call SYS_PostTask() in the HW interrupt handler to make the ball rolling.

 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #15 on: October 24, 2016, 04:56:30 pm »
So: after a HW Interrupt (WDT) wakes up the chip, if I call a SYS_PostTask() function it will call my APL_TaskHandler() and don't go back to sleep automatically?
No, nothing goes back to sleep.

I'm not gonna get ZDO_WakeUpInd() unless I issue ZDO_WakeupReq().
I don't think you will ZDO_WakeUpInd() even after ZDO_WakeupReq(), you just get a normal confirmation from ZDO_WakeupReq().

ZDO_WakeUpInd() is only called when stack woken up on its own, from a sleep timer.

In this case, I can have an awakened chip, with running BC (with state machine), but powered down radio. To make the whole chip sleeping again, I have to call ZDO_SleepReq() and it will sleep until the next HW interrupt (or CS_END_DEVICE_SLEEP_PERIOD of time). Right?
Correct.

So the point might be to call SYS_PostTask() in the HW interrupt handler to make the ball rolling.
Yep, that's the idea.
Alex
 
The following users thanked this post: danergo

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #16 on: October 24, 2016, 05:00:56 pm »
Alex,

thank you very much for your efforts and patience.
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #17 on: October 28, 2016, 06:26:50 pm »
Hello,

I don't really have success with the WDT + ZDOSleepReq.
It seems if I choose a WDT for 64ms (for buttons), ZDOSleepReq take more time to sleep, and the whole chip will reset before even going to sleep.
How long should the ZDOSleepReq take?

My initial idea was:
Code: [Select]
ISR(WDT) {
  handle_buttons
  WDTRestart

  if nothing to do then {
    ZDOSleepReq
  }
}

This keeps restarting with WDT set to 64ms.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #18 on: October 28, 2016, 06:29:03 pm »
How long should the ZDOSleepReq take?
You can't call BitCloud APIs from interrupt handlers. You need to set a flag (or change the state machine state) and do actual work in the main task handler.

Also, show your WDT initialization code. If WDT restarts the system, no WDT restart will help, you need to disable reset bit on the WDT configuration.
« Last Edit: October 28, 2016, 06:30:38 pm by ataradov »
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #19 on: October 28, 2016, 06:44:54 pm »
Auch  |O. I forgot to avoid calling BC's functions from ISR.

Wdt reset should be fine, because without the sleep request, it is handling the buttons correctly, without resets. But it consumes power in this case ofc.

Thanks, I'll reorganize the whole thing into the state machine.
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #20 on: October 29, 2016, 10:27:20 am »
Hello,

I modified the code to call ZDO_SleepReq inside the statemachine and not in the ISR's callback.
However, the chip still keeps restarting. I found that it's not related to WDT however ZDO_SleepReq call.
If I disable the SleepReq, chip is not restarting. When enable the SleepReq (on pushing a button), the chip restarts immediately. It seems I'm not using it correctly:

Could you confirm this section, please?
Code: [Select]
  zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;
  ZDO_SleepReq(&zdoSleepReq);
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #21 on: October 29, 2016, 05:18:36 pm »
Is zdoSleepReq a global or static variable?

Also, in ISR(WDT) you need to call a function that informs the stack about wakeup. I don't remember exact name, look at any other ISR() inside HAL and you will see it.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #22 on: October 29, 2016, 09:50:35 pm »
zdoSleepReq is static right now. Should it be global?
zdoStartReq is also static, and it works as inteneded. I've just copied this one.

Regarding wakeup for the stack, I've found halPowerOn(...). Shall I call this one? It extists in each ISR routine.
However, it will wake up the radio also, which is absolutely not needed in this case (halPowerOn contains TRXPR &= ~(1 << SLPTR)).
« Last Edit: October 29, 2016, 10:00:56 pm by danergo »
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11228
  • Country: us
    • Personal site
Re: [BitCloud] End device's power consumption
« Reply #23 on: October 30, 2016, 12:15:58 am »
zdoSleepReq is static right now. Should it be global?
It just needs to stay valid until confirmation callback is called.

Regarding wakeup for the stack, I've found halPowerOn(...). Shall I call this one? It extists in each ISR routine.
However, it will wake up the radio also, which is absolutely not needed in this case (halPowerOn contains TRXPR &= ~(1 << SLPTR)).
I would look at what else it does. If I'm not mistaken, it also updates system time, which lets application timers expire properly.

The radio will be in the TRX_OFF state, so power consumption will be low.
Alex
 

Offline danergoTopic starter

  • Regular Contributor
  • *
  • Posts: 111
  • Country: hu
Re: [BitCloud] End device's power consumption
« Reply #24 on: October 30, 2016, 10:59:08 am »
zdoSleepReq is static right now. Should it be global?
It just needs to stay valid until confirmation callback is called.

It was defined in the same file as the zdoSleepReq call and the callback, so it remains valid yes.
I now changed that variable to global, but I still get the same restart issues upon calling the sleepreq.

My sleep function is this:
Code: [Select]
void appSleep()
{
  zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;
  ZDO_SleepReq(&zdoSleepReq);
}
After I realized, that this function is called 2-3 times in a row, I've reorganized the code into the state machine:

Code: [Select]
void appSleep()
{
  appstate = PREPARE_TO_SLEEP
  postglobaltask
}
void appPrepareSleep()
{
  zdoSleepReq.ZDO_SleepConf = appZdoSleepConf;
  ZDO_SleepReq(&zdoSleepReq);
}
void appZdoSleepConf(conf)
{
  if (ZDO_SUCCESS_STATUS == sleepInfo->status)
    appstate = APP_SLEEP
  else
    appSleep()
}

switch(appstate)
{
  ...
  case PREPARE_TO_SLEEP
    appPrepareSleep()
   
  case APP_SLEEP
  ...


And I put halWakeupFromIrq(); in the WDTISR's callback function. It was marked as a generic entry point from all external interrupts.

However, bad luck. Still keeps restarting when calls sleepreq. Unfortunately, I can't examine ZDO_SleepReq function because it's compiled into the libraries of BC. :(

One more thing: in the makefile I have SLEEP_WHEN_IDLE defined.
But in the source code it is not, so in theory, sleeping when idle is turned off, so manual sleep should work.

Also, an additional note is that I dump MCUSR after restart every time, and it's always 0. So it's not the WDT which resets the CPU, but some SW bug I guess. (Like division by zero, or something similar).
« Last Edit: October 30, 2016, 05:33:42 pm by danergo »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf