Electron power consumption with Cellular off

Hey all,

I’ve been running an experiment for the last few days where I first ran the Electron with Cellular “on” and had it sample it’s own battery level and report it every hour or so.

I then did a similar experiment where Cellular was off but every hour or so it was turned back on so the Electron could report back battery levels for that hour before turning Cellular back off.
I did not sleep the Electron (just Cellular on/off).

In both cases I noticed that the battery was draining at pretty much the exact same pace. Was I wrong to think that turning Cellular off would help conserve battery?

Best,
Or

Are you able to share the code used for the experiment?

Also, did the RGB led turn to breathing white (if i remember correctly) after Cellular is turned off?

Hey Kenneth,

Here’s a somewhat representative snippet of the code. And yes - the led does breath white for the duration of time Cellular is off.

Here’s the code I used - let me know if it’s a bit too verbose and I can try to explain further.

Thanks!
Or

the RGB LED is going to consume a non-trivial amount of current, especially when R, G, and B are on at the same time (making it look white.)

I always turn that LED off in battery-driven applications, and quickly flash D7 every 5-10 seconds so I can see that it’s alive.

I haven’t done a side-by-side test to be sure, and I think I’d find that that RGB LED to be a large power consumer.

Can anyone tell me if I’m right or wrong on this? this is an assumption that I’ve held for a while.

Hmm… the code seems to turn the network on and off once in setup() and once ever 24 hours.

Once in the beginning so I can fetch the current time from the server, then every 24 hours when I want to flush data. That said, you are correct - during the experiment I flushed every 1 hour instead.

How is the test with cellular on conducted then?

In the test WITH Cellular I just turn the Cellular on in the beginning and never turn it off. And indeed, the the led breathes green the entire time.

How much difference are you observing in these tests?

I can run another test later this week. How much of a difference should I be expecting?

Looking at the operating current between the two modes, at least 2x difference should be observed based on: https://docs.particle.io/datasheets/electron-datasheet/#recommended-operating-conditions-

Here is how I wake up every 2 mins and send fuel gauge data and then back to sleep.

I also put the Electron into deep sleep mode when the battery hits 20% SOC then wake up every hour to check if the SOC has risen above 20% from solar charging before running my main code again to prevent the Electron from shutting down or having low voltage brownout issues.

Powering the Photon from the 3.3v pin will give you the lowest deep sleep mode current readings.

SYSTEM_MODE(SEMI_AUTOMATIC);
//SYSTEM_THREAD(ENABLED);
// This #include statement was automatically added by the Particle IDE.
#include "Ubidots/Ubidots.h"

#define TOKEN "YourToken"  // Put here your Ubidots TOKEN
#define DATA_SOURCE_NAME "ElectronSleepNew"

SerialLogHandler logHandler(LOG_LEVEL_ALL);  //This serial prints system process via USB incase you need to debug any problems you may be having with the system.

Ubidots ubidots(TOKEN); // A data source with particle name will be created in your Ubidots account.


int button = D0;         // Connect a Button to Pin D0 to Wake the Electron when in System Sleep mode. 
int ledPin = D7;         // LED connected to D1
int sleepInterval = 60;  // This is used below for sleep times and is equal to 60 seconds of time. 

ApplicationWatchdog wd(660000, System.reset); //This Watchdog code will reset the processor if the dog is not kicked every 11 mins which gives time for 2 modem reset's. 

void setup() {
 //Serial.begin(115200);
 pinMode(button, INPUT_PULLDOWN);  // Sets pin as input
 pinMode(ledPin, OUTPUT);          // Sets pin as output

 ubidots.setDatasourceName(DATA_SOURCE_NAME); //This name will automatically show up in Ubidots the first time you post data. 
 
 PMIC pmic; //Initalize the PMIC class so you can call the Power Management functions below. 
 pmic.setChargeCurrent(0,0,1,0,0,0); //Set charging current to 1024mA (512 + 512 offset)
 pmic.setInputVoltageLimit(4840);   //Set the lowest input voltage to 4.84 volts. This keeps my 5v solar panel from operating below 4.84 volts.  
}

void loop() {
    
FuelGauge fuel; // Initalize the Fuel Gauge so we can call the fuel gauge functions below. 
 
    
if(fuel.getSoC() > 20) // If the battery SOC is above 20% then we will turn on the modem and then send the sensor data. 
  {
   
   float value1 = fuel.getVCell();
   float value2 = fuel.getSoC();
   
  ubidots.add("Volts", value1);  // Change for your variable name
  ubidots.add("SOC", value2);    

  Cellular.connect();  // This command turns on the Cellular Modem and tells it to connect to the cellular network. 
  
   if (!waitFor(Cellular.ready, 600000)) { //If the cellular modem does not successfuly connect to the cellular network in 10 mins then go back to sleep via the sleep command below. After 5 mins of not successfuly connecting the modem will reset.  
    
    System.sleep(D0, RISING,sleepInterval * 2, SLEEP_NETWORK_STANDBY); //Put the Electron into Sleep Mode for 2 Mins + leave the Modem in Sleep Standby mode so when you wake up the modem is ready to send data vs a full reconnection process.  
    
}  
  
     ubidots.sendAll(); // Send fuel gauge data to your Ubidots account. 

     digitalWrite(ledPin, HIGH);   // Sets the LED on
     delay(250);                   // waits for a second
     digitalWrite(ledPin, LOW);    // Sets the LED off
     delay(250);                   // waits for a second
     digitalWrite(ledPin, HIGH);   // Sets the LED on
     delay(250);                   // waits for a second
     digitalWrite(ledPin, LOW);    // Sets the LED off
  
     System.sleep(D0, RISING,sleepInterval * 2, SLEEP_NETWORK_STANDBY); //Put the Electron into Sleep Mode for 2 Mins + leave the Modem in Sleep Standby mode so when you wake up the modem is ready to send data vs a full reconnection process.  
    
  }
  else //If the battery SOC is below 20% then we will flash the LED 4 times so we know. Then put the device into deep sleep for 1 hour and check SOC again. 
  {
      
  //The 6 lines of code below are needed to turn off the Modem before sleeping if your using SYSTEM_THREAD(ENABLED); with the current 0.6.0 firmware. It's a AT Command problem currently. 
  //Cellular.on();
  //delay(10000);
  //Cellular.command("AT+CPWROFF\r\n");
  //delay(2000);
  //FuelGauge().sleep();
  //delay(2000);
  
  
  digitalWrite(ledPin, HIGH);   // Sets the LED on
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, LOW);    // Sets the LED off
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, HIGH);   // Sets the LED on
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, LOW);    // Sets the LED off
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, HIGH);   // Sets the LED on
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, LOW);    // Sets the LED off
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, HIGH);   // Sets the LED on
  delay(150);                   // Waits for a second
  digitalWrite(ledPin, LOW);    // Sets the LED off
  
  System.sleep(SLEEP_MODE_DEEP, 3600);  //Put the Electron into Deep Sleep for 1 Hour. 
  
  }
}    

1 Like

I’m having similar issues, extreme power consumption when cellular is (should be) off and the cpu in stop mode. I think I’ve tracked it down to pin PWR_UC not being set to low, but to floating input, when switching off:

hal/src/electron/modem/mdm_hal.cpp, in powerOff():
    HAL_Pin_Mode(PWR_UC, INPUT);

This would be perfect, if there would be a pull down on this pin, but that is not configured*. Between PWR_UC and PWR_UB an SN74LVC1G07 buffer will take whatever noise it sees and make it into a clear power-on signal. So you get random effects and measuring the pin with a probe even flips its value.

So it feels like a bug in the system firmware (0.6.0 and 0.7.0) but it is easily worked around by changing PWR_UC to output and setting it to low value after calling Cellular.off().

Can anyone confirm or correct me in these observations and/or this theory?

*ps. looking at HAL_Pin_Mode(), the INPUT mode even explicitly discards any pull setting:

case INPUT:
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    PIN_MAP[pin].pin_mode = INPUT;
    break;
1 Like

@Bdub May be able to confirm.

Hmm, let’s see if we can figure this out…

When the modem is powered off, an AT command is sent to do that. The PWR_ON pin controlled by PWR_UC and PWR_UB only turns the modem back on. The current board design uses a 10k external pull up on PWR_UC and 100k external pull up on PWR_UB. When MDMParser::powerOff is called, the AT+CPWROFF command is sent, and then PWR_UC and RESET_UC are set to INPUT mode. There is no reason to set these pins to an OUTPUT at that time.

If you do see positive results with setting that pin to an OUTPUT, your external pull up resistors may not be included on the board (possible MFG’ing error). Check to see if R29 and R1 exist.

What kind of currents are you seeing after Cellular.off() is called? Have you tried looking at the debugging output to see if the AT+CPWROFF command is processed properly and you get an OK response?

2 Likes

Any more news on this, I am seeing the same issues too.