Sleep cycles and power consumption

Hi Particles,
I have an interesting problem regarding sleep modes and power. I have been experimenting with an Electron in the sleep mode called by this code
System.sleep(SLEEP_MODE_DEEP, 1200, SLEEP_NETWORK_STANDBY);
I am looking at deploying my project using a solar panel/ battery / charge controller configuration – with the Electron being powered by the “Load” output of the charge controller, which sometimes exceeds the recommended 12 Volt tolerance of the Electron but is never above 12.8v and so within absolute maximum tolerance (17 volt). Probably risky but it’s been running for several weeks without a hitch. My intention is to stress the unit – see what it can take.
The conditions are pretty hot and it is possible the temperature inside the project enclosure may exceed 40 degrees C for long periods and as such I’m concerned about including the (Electron) LiPo battery, as operation above 40 degrees C as it may cause thermal runaway and is a fire hazard. So I’ve started running the project without the LiPo battery.
What I’ve found is that the Electron seems to draw significantly more power without the LiPo battery connected.
To be clear if I take the Electron out of circuit my project draws around 1.3Ma. With the electron in circuit and in sleep mode with the LiPo battery connected circuit goes through a cycle of drawing around 38mA for a few 5 second cycles, then settles down to draw around 8-12 mA.
If I remove the Lipo Battery and add the following code to shut down the power management
PMIC _pmic; (prior to setup() ) and _pmic.disableCharging(); (in setup() ).
The circuit draws around 29mA occasionally crashing down to around 6 mA for a few seconds then reverts to 29mA.
Does anyone have any ideas why this is happening? I would have expected a significant sustained drop in power consumption without having to charge the LiPo battery.
Just as a final point – my observations are through using a meter in series with the positive power line (to VIN) – I do not have a scope or analyser.

This is a speculative response, as I don’t have your circuit to look at, but bear in mind SLEEP_NETWORK_STANDBY leaves the cellular radio on and handshaking with the carrier network. It only reduces the processor to a lower power state.

When you have a local current source (ie, the LiPo) in place, any radio transmission current is probably sourced from that, and current from the external power source is averaged out to charge the LiPo. Without the LiPo, the external current will be much more ‘lumpy’.

If you’re in a 3G mode, it could be spiking up to 500mA at times depending on the radio .

With all that in mind, I am also guessing that your meter is a DVM, which typically use dual-slope averaging measurement - it will have a very slow response to current/voltage transients.

Lots of assumptions in the above but, in other words, I am sceptical of the indicated results :slight_smile: You may actually be better off with an analogue meter or a scope (if available).

With regard to powering the Electron from Vin near its limits, I would strongly recommend a high-efficiency down-converter. These are dirt cheap and, for the sake of a few bucks, may save a transient from killing your Electron. I used a Pololu D24V5F5 (5V 500mA) in a recent project for $7 plus a 47uF 50V electrolytic to protect it against transients.

1 Like

Hi Andrew,
Thanks for your response, and I agree with your assessment of undertaking this test without an analyser or oscilloscope (with current leads) – but don’t have.
Couple of things: I replaced the DVM with an analog (coil) ampmeter and the result was much the same, where it could be observed – I don’t doubt there are current spikes in regaining the network etc… but have to accept they are very fast and probably negligible overall.
Not really sure what you mean by “When you have a local current source (ie, the LiPo) in place, any radio transmission current is probably sourced from that, and current from the external power source is averaged out to charge the LiPo. Without the LiPo, the external current will be much more ‘lumpy’.”
If I understand the configuration right , the BQ24195 should not draw from the LiPo by preference over VIN – if that’s what you mean – and the external source should be pretty clean (being a battery). In any case I don’t get how it would be working so hard it draws another 20 odd mA. Might be wrong here and happy to be corrected (maybe one of the Particle Hardware guys might want to jump in).
That said this Particle tutorial and the datasheet suggest Electron in SLEEP_NETWORK_STANDBY should draw under 7 mA – in my test with a LiPo battery attached this is confirmed (I’m drawing around 9mA, but the rest of the circuit in the project draws about 1.3MA).
Regarding the project being at risk from excessive voltage on VIN, good point – but the ratings are pretty solid on the BQ24195, which is actually rated to absolute MAX 22v.
Being a solar configuration on the filtered (by a couple of largish capacitors) LOAD output of the charge controller – and a 15v Zener diode in circuit across VIN in the project – there is not much chance of a transient voltage spike (unlike say, a car battery charged by an alternator) I’ll risk it for a bit more of the testing. I agree it is NOT good practice to exceed recommended op specs with any device – but so far so good. If I can solve this excessive current draw without a LiPo battery, I’ll use a DC/DC converter to drop the supply to 7.5 volts – but it adds another 12 mA to the power draw. I am really trying to minimise the power consumption to reduce costs and size of the solar panel. I’m finding it hard to source a 6 volt solar rig that delivers more than 3 watts – which will be borderline on a device that uses as much power as the Electron.
Last Point – I like the SLEEP_NETWORK_STANDBY mode because of the rapid reconnect to the particle cloud. I’m working on a series of 20 minute sleep cycles, and taking a data sample when they expire (currently at 4 cycles / 80 minutes). If I use the SLEEP_MODE_DEEP option, I’ll reduce sleep power consumption but go through much longer periods of high current drain every time the device wakes up - with cell data signals pretty erratic (due to contention) in Northern Queensland, I could have the device seeking connection for minutes – which could negate much of the low power sleep cycle savings.

What solar panel/ battery / charge controller are you using ?
Also, there is some chatter about Sleep not acting exactly the Same on Electron firmware 1.0.1

Even so, if your Electron is Sleeping w/ a sufficient source on Vin - you should be able to remove the Li-Po and the current should drop (assuming it was not already fully charged, which would be ~No Change in current).

But IMO your (29 mA) result is too high for an Electron that’s truly sleeping in any Sleep Mode, “if” you are measuring a 12V source, with no Li-Po connected. What your seeing is not typical.

1 Like

Hi Ryan,
The solar panel is a mono – 5W / 12 volt, the charger a generic PWM, 10 amp Chinese cheapie (I have used it for a year or so on-and-off and seems to be solid) the battery is a 12 v SLA - 4.5 AH – it is brand new.
Regarding the current draw, I have double checked in circuit and it is as stated previously – with the battery reconnected it draws around 9mA which is what I’d expect.

This is indeed strange behavior.
I can’t think of any reason that unplugging the Li-Po would cause an additional 1/4 watt (20mA @ 12V) load. If 1/4 watt is correct, It’s going somewhere…I assume heat.

It’s a long shot, but maybe the PMIC doesn’t like the 12V Vin Source from the charge controller, and it’s supplementing by discharging the Li-Po for some reason. If that’s the case, the demand isn’t increasing by 20mA when you remove the Li-Po: it’s just passing through your measurement point on Vin when the Li-Po isn’t there to supplement.

Maybe a bad (LOAD) connection that prevents the required current spikes during modem operation ?
image

This theory isn’t valid over a steady state condition, since the Li-Po would eventually be discharged.
Maybe it’s just an acute issue for a short period after startup, verses a chronic symptom?

I’ve used the cheap charge controllers with Electrons & SLA’s without Li-Po’s, but I always let them run 24/7 (no sleeping) in my particular projects.

To drill down on the possible causes, can you try a quick test by removing Sleep and your external circuitry/loads ? Just flash a blank user firmware and let the current settle in after the Handshake, etc. Measure Current & Voltage for several minutes, unplug the Li-Po “on-the-fly”, re-measure Current & Voltage.
If the current through the Vin Source still drops, then it would appear the PMIC is supplementing using the Li-Po during your first measurements. You could repeat the test after letting the Electron run for a longer period of time.

2 Likes

It could easily be that the PMIC Buck circuit is less efficient when bucking higher voltages.

The PMIC is a buck battery charger and the inductor chosen for this circuit may just not be optimized for higher input voltages which causes less than ideal buck conversion efficiency.

Your deffiently going to need less power when bucking the LiPo 3.7v vs bucking 12v down to 3.3v which is a 400% down conversion.

1 Like

I believe He's maintaining 12V on Vin the entire time.
The PMIC needs a good reason to source from Li-Po when Vin is available.

1 Like

I’m just saying feeding 12v in is going to be less efficient than when powering via Vin at higher votages with or without a battery attached.

The PMIC will use a small amount of current to trickle charge the battery also, even after the charging LED goes out it’s still pushing a small amount of current into the battery.

If I remember correctly the red charging led goes out when the charging current drops below 50mA. Which may or may not have etching to do with what he is seeing.

1 Like

OK, a few more tests and observations

  1. With the connection directly from the solar charger LOAD, I am observing random flashing red LED sessions – usually immediately after waking up. The flash cycle is around a second on/off - not the very rapid flash I’ve seen if you do not have the LiPo battery connected in normal operation. It does not appear to be any of the SOS codes, while it’s going it is constant - no intermittent rests between repeated sets of blinking.
  2. I have connected a pure 6 volt battery source (4 series AA Alkaline) and observed the same behaviour as previous – with long (3 - 5 second approx.) sessions at 25-30 mA then a brief collapse down to 4 or 5 mA (maybe half second). Again all approximates and observed on an analogue meter that is now hardwired in circuit.
  3. I repeated the above with a 7.5 DC/DC converter in line with the supply (project input now 7.5v) and observed the same as above with an added 10-12 mA increase draw (due to the DC/DC converter)
  4. I placed a 470uf electrolytic capacitor across the 12-volt (LOAD) supply, close to the power input of the project (as in point 1) and observed some increased delay in the period that the current dropped to below 10mA – but still essentially the same behaviour.
    Conclusions: This behaviour does not seem to be a problem with the PMIC managing the supply from the solar charger – or at a voltage level approaching or exceeding its spec limits.

Additional notes:

Probably important -I am running firmware version 0.7.0 on this electron.

While running the code that should turn off the charge controller function, inserting or removing the LiPo battery (fully charged) makes no difference in the cyclic behaviour (30mA high 3 sec – sub 10 mA 0.5 SEC)

My code uses retained variables, a few libraries and publish commands - to make sure I was not invoking some sort of drain for memory or a background routine I stripped everything back to a very basic code - the result was the same.My test code is as follows:



PMIC _pmic;

const int LEDpin = 7;


void setup() {
 pinMode(LEDpin, OUTPUT); 
 digitalWrite (LEDpin, LOW); 
 
_pmic.disableCharging(); 
}

void loop() {
    Blink_led();
    System.sleep(SLEEP_MODE_DEEP, 60, SLEEP_NETWORK_STANDBY); 
   
}


   
 void Blink_led(){
  
  int blink_warn = 0;
  while (blink_warn <= 3){
      digitalWrite (LEDpin, HIGH);
      delay (200);
      digitalWrite (LEDpin, LOW);
      delay (200);
      blink_warn ++;
  }
}

Update:
Didn’t solve the mysterious power drain without LiPo – but did solve my problem.

The following code sleeps at extremely low power drain (theoretically 161 μA), with practically no power drain during the wakeup periods – I think the absolute limit is a 23-minute sleep time. In this example I’ve set the sleep period for 1 minute cycles – but have tested it at 20 minutes and it works fine.
It works around the SYSTEM_MODE(SEMI_AUTOMATIC); system mode and turning off the cellular module between wakeup cycles. I’m sure you guys are better coders than me and can work it out – but feel free to ping me if you have any questions.
The option for very long, negligible power drain periods more than offsets the very hungry cold wakeup cycle used in System.sleep(SLEEP_MODE_DEEP, XXXX);
I think it’s a very practical solar power solution.
I am really curious about the mysterious power drain when you don’t use the LiPo with System.sleep(SLEEP_MODE_DEEP, XXXX, SLEEP_NETWORK_STANDBY); - but can’t put any more time into it – as this solution is better for my requirements all round.
Thanks to anyone who’s spent time trying to solve the original problem – I think it’s still really worthwhile knowing.

SYSTEM_MODE(SEMI_AUTOMATIC);
PMIC _pmic;
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));// need this fto initialise the RAM
retained int goTosleep; //sleep cycle after a reading
retained int testCycle; // count the number of broadcasts - view on particle console
const int LEDpin = 7;
const int updateButton = D4;

void setup() {
 pinMode(LEDpin, OUTPUT); 
 digitalWrite (LEDpin, LOW); 
 

_pmic.disableCharging(); 
}

void loop() {
        
   if (((((goTosleep !=0) && (goTosleep !=1) && (goTosleep !=2) && (goTosleep !=3)&& (goTosleep !=4)&& (goTosleep !=5))))) {//if the RAM variable isn't between 0-5 it is zero
      goTosleep = 0;// first time or power fail set the condition for goTosleep to 0 
  }
 
    if ((goTosleep >=0) && (goTosleep<4)){// if the goTosleep variable is 1-3 - go to sleePnow() function
       	delay (10);
        sleePnow();// sleep cycle function
    }
    
   if (goTosleep>=4){// time to do a whatever - let's do a particle.publish
       goTosleep = 0; // reset the sleep cycle counter
        Blink_led(); // flash the LED
            Cellular.on(); // turn the cell module on
            Particle.connect(); //connect to the cloud
            delay (50);
            bool cloudReady = Particle.connected(); // check cloud connection
                if (cloudReady) {
                    testCycle++; // records how many successful publish events
                    Particle.publish("test_cycle", String(testCycle)); // publish the number of successful connects
                }
        }
}

 void Blink_led(){ // blink the electron LED to show a publish event
  
  int blink_warn = 0;
  while (blink_warn < 3){
      digitalWrite (LEDpin, HIGH);
      delay (200);
      digitalWrite (LEDpin, LOW);
      delay (200);
      blink_warn ++;
  }
}

void sleePnow(){ //  sleeo cycle - in this case 3 minutes
      
       ++goTosleep;// must be at least 1
       	delay (50);
       if(goTosleep <4){ // if less than 4 eg; 1,2 or 3
          Cellular.off(); // kill the cellular module
         
       }
    System.sleep(SLEEP_MODE_DEEP, 60); // 1 minute sleep cycle
   
   } 

1 Like

Where does that come from?
The 23 minute limit only applies when you need to keep the device from running a cold wake handshake, but this doesn't seem to be an issue for your use case as you also say this

and

1 Like

Thanks for jumping in on this subject – not the first time you’ve set me straight on Particle stuff and I greatly appreciate it. My reference to the 23 minute sleep cycle limit came froma post you did back in 2016 – and on re-read clearly does not apply to the System.sleep(SLEEP_MODE_DEEP, XXXX); - but does apply to System.sleep(SLEEP_MODE_DEEP, XXXX, SLEEP_NETWORK_STANDBY);
Have I got that right?
I think the reason for my confusion was that I spent so much time trying to get the standby mode working (as it has a rapid transition to network and cloud connection) that I thought the 23 minute limit applied to all sleep modes.
My mistake.
So to be clear, if I use the deep sleep mode, I can sleep as long as I like? This will greatly simplify my code and improve power consumption, hopefully to the point where a 6 volt battery, with 3 watt solar panel could easily power my project even through extended periods of no sunlight.
I’m thinking I could use the (Time.hour()); function to sleep for extended periods after sunset until dawn (say 12 hours) – then take samples from sensors every 90 minutes throughout the day.
No need for sleep cycle functions, retained variables, turning on or off the cell module or SYSTEM_MODE(SEMI_AUTOMATIC);
Happy days – I’ll try it.

Yes, as long you don't call Cellular.off() (which would render SLEEP_NETWORK_STANDBY superfluous) :wink:

I usually use something like this

const int wakeTime = 06*60*60 + 30*60 + 00 + 86400; // hh / mm / ss + next day (e.g. 6:30am)

//                next wake - current time in sec since midnight but max 24hours  
int sleepPeriod = (wakeTime - Time.local() % 86400)               %  86400;
1 Like

Got it - thanks. By the time I read this I already had an iteration that simply stated that when the (Time.hour()); function return is >=8 (UTC 7.00PM in my part of the world) sleep for 10 hours - System.sleep(SLEEP_MODE_DEEP, 36000);.
I’ll see how that goes.

Update: little screwup on the UTC clock / Australia time (AEST) calculation set the into a very long and repeating sleep cycle. That I can fix - but what I did observe was that after some 12 hours either asleep, or briefly waking up and going back to sleep - I got the slow blinking (approx 1 sec on / 1 sec off) red LED again. Would love to know what this means. It adds a negligible power overhead (maybe 1 mA).

Do you mean the charging LED?

yes - though there is no LiPo attached and the code includes:
PMIC _pmic;
and in setup()
_pmic.disableCharging();
}