Programming particle photon in low power mode

We are finding ways to drive particle photon in low power mode. It is consuming lot of power when wifi is on i.e around (0.5 Watts).

  1. Are there any ways so that we can reduce this consumption ?
  2. Is there any other way so that we can drive WiFI on core with low power consumption.
  3. Other query is that, when I am using System.sleep() in code, it is still drawing 40 to 50 mA current whereas in operating conditions it is given that it draws around 1 to 3 mA current. What is wrong here ?

Yes, like turning WiFi off. But AFAIK there are some more low-power modes in the pipeline.
And I don’t think your 500mA readings are correct - unless you have additional circuiry attached, which can’t be “blamed” on the Photon.

You’d need to explain which kind of System.sleep() you are using. There are three different ones with quite different power consumption figures.

Above are our readings in two cases when V= 4.8 volts and V = 3.6 Volts. The voltage is provided by DC power supply to VIN pin.

If you want to see, i have attached code below in which for transmission only, we are using Wifi ON. This code is written just to check power measurements and we got above readings.

Any further suggestions to improve our power consumptio OR is there anything wrongly implemented in the code ?

#define     PORT    9009
TCPClient client;
byte server[] = { 192, 168, 31, 27 }; // to the queen(one as a server photon)  wlan IP

int led1 = D7; 
int DUTY_CYCLE = 5; // specify duty cycle in seconds 


void setup() {
  //udp.begin(11200);
  Serial.begin(9600);
  Serial.println("Process Started"); 
  pinMode(led1, OUTPUT);
}


void loop() {
    
    /* sleep mode instead of delay is becaause sleep mode disables TX and RXX as well as microcontroller.
     It just keeps LED on, but do not forget to cconnect wifi after calling System.sleep as wifi does not wake up automatically
    once System.sleep is called*/
    
    // Mode 1:- TX On for DUTY CYCLE
    unsigned long now_time  = millis();
    Serial.println(now_time);
    
    while(now_time + (DUTY_CYCLE*1000) > millis()){
        Serial.println("TX");
        if (client.connect(server, PORT))
            {
                Serial.println("server connected");
                client.write(2);
            }
            else
            {
                Serial.println("connection failed");
            }
        }
    
    // Mode 2:- LED High
    digitalWrite(led1, HIGH);
    System.sleep(DUTY_CYCLE);
    
    WiFi.connect();
    
    delay(2000); // delay so that Wifi should settle
  
}

I see, sorry I misread your 0.5Watts for 0.5Amp (hence my comment about 500mA being wrong) - my bad :blush:

But this part here puzzles me

I think the comment is not quite correct.
System.sleep(timeout) just turns the radio off, but does not stop µC and code execution, so your following WiFi.connect() would be executed immediately after that but should fail for DUTY_CYCLE seconds, as should any client.connect() atempts.
On the other hand, System.sleep(timeout) should in fact come back to the same connection status it had before going to sleep, so WiFi.connect() should not be required anyway (but this I’d have to confirm again).

If you want to stop code execution, you’d need to use System.sleep(pin, edge, timeout) (Stop Mode sleep).

See here
https://docs.particle.io/reference/firmware/photon/#sleep-sleep-

and

.and

Hi, Thanks very much for detailed reply. I was wondering how can we reduce power consumption when wifi is on. We are getting 100 to 125 mA current when device is sending TCP packets ( WiFI is On). Is there any way we caan reduce consumption when wifi is on ?

I came across a field in photon datasheet.

  1. Operating Current (Wi-Fi on, w/powersave) IVIN avg 18 100[2] mA

  2. Is there anyway we can get this power-save mode for wifi? How to invoke this powersave if there is any so that we can reduce power consumption when wifi is on ?

AFAIK it’s on the Particle ToDos, but I know of no ETA.

https://github.com/spark/firmware/issues/922
https://github.com/spark/firmware/issues/935
https://github.com/spark/firmware/issues/501

Can you elaborate your reply a bit. I did not understand it completely.

Hi,

So we are measuring particle photon power consumption when it is sending only 1 UDP packet. I have attached code below:-

Code:-

#define PORT    9009
#define TCP_COMMUNICATION
TCPClient client;
byte server[] = { 192, 168, 31, 27 }; // to the queen(one as a server photon)  wlan IP
UDP udp;
IPAddress broadcast(192,168,31,255);

int led1 = D7; 
int DUTY_CYCLE = 60; // specify duty cycle in seconds 


void setup() {
  Serial.begin(9600);
  Serial.println("Process Started"); 
  pinMode(led1, OUTPUT);
}


void loop() {
    
    /* sleep mode instead of delay is becaause sleep mode disables TX and RXX as well as microcontroller.
     It just keeps LED on, but do not forget to cconnect wifi after calling System.sleep as wifi does not wake up automatically
    once System.sleep is called*/
    
    // Mode 1:- TX On for DUTY CYCLE
    unsigned long now_time  = millis();
    int count = 0;

    udp.begin(11200);
    udp.beginPacket( broadcast, PORT);
    udp.write(5);
    udp.endPacket();
        
    // Mode 2:- LED High
    digitalWrite(led1, HIGH);
    Serial.println(millis()/1000);
    System.sleep(D7, RISING, DUTY_CYCLE);
    Serial.println(millis()/1000);
}

Our Snapshot of power consumption:-

My questions :-

  1. As I am sending only 1 UDP packet after device awakes from sleep mode, there should be only one spike in snapshot. But there is substantial area under curve for 1 UDP packet. How can we reduce this and get only 1 spike corresponding to 1 UDP packet.

  2. I think it consumes power for WiFI to settle down after device awakes from sleep. How can we keep wifi standby and not disconnected provided that it still consumes least power when wifi is on OR wifi is in standby mode

Your code is using the default SYSTEM_MODE(AUTOMATIC) which will by default hook you up to the Particle cloud with all the handshaking and Particle feature enumeration.
If you won’t need any of that, use SYSTEM_MODE(MANUAL), but you’ll still see more than just one UDP packet as you’ll still need WiFi.connect() which usually performs some negotiation with your WiFi AP including DHCP requesting an IP.
To further cut down on that, you could use WiFi.useStaticIP().

If you want to use the low-power features of the Broadcom module before Particle has their APIs for this ready, you’d need to dig into the Broadcom WICED SDK.

1 Like

Any timeline for this API will be available ?

Repeat of my previous post

ETA is Estimated Time of Arrival

Is there any documentation how should we use WICED SDK in particle application code and how should we invoke low power mode ?

I’d also be interested in trying this, while waiting for official API support. Anyone can provide some tips on how to start?

Sorry for reviving this thread. I did not find more recent information and it seems it is still on Particle’s ToDo list (if I read correctly, postponed to 0.8.0). Has anyone found a clever workaround to minimize power?

I have tried all three system modes: AUTOMATIC, SEMI and MANUAL; in combination with System.sleep() and I found inconsistent behavior.

System.sleep(time) keeps the code running. This is partly useful because the CPU keeps running. It seems to be the best that can be achieved. It seems that since the Photon keeps running, it doesn’t matter what the value of “time” is.
I think this delay represents how long the wifi stays off, but I found that this command doesn’t turn it back on, even in AUTOMATIC mode.

System.sleep(pin,event,time) pauses execution, but it turns on the wifi and reconnects regardless of system mode. The Photon does not stay in a low power state. I wish I could use this command and that it would not reconnect in MANUAL, or even SEMI mode.

My goal is to keep the Photon asleep for 15 seconds, then check if it should reconnect to publish data. In the end, the Photon sleeps for 14 minutes and is awake for 1 minute. The wifi is on only during that minute. This allows me to send updates and check status at a predictable time of day.
For now I have decided to stay in MANUAL mode.

The code below is what I adopted for now, but power is not minimized.

void loop()
{
  if (Time.minute() % 15 == 0) //Do this every 15 minutes, for the whole minute
  {
    if (!Particle.connected())
    {Particle.connect();}
    Particle.process();
.
.
Do stuff
.
.

  }
  else  //turn off wifi, doesn't pause code
  {
    System.sleep(15);
  }//end else

} //end loop()

This code uses less power, but I would like to avoid getting online/offline events every 15 seconds.

void loop()
{
  if (Time.minute() % 15 == 0) //Do this every 15 minutes, for the whole minute
  {
.
Do stuff
.

  }
  else  //pause execution and turn off wifi. Resume if level change on D2 or after 15 seconds
  {
    System.sleep(D2, CHANGE, 15);
  }//end else

} //end loop()

Finally, I wish flash updates could be queued and that the Photon would check for that when it reconnects to the cloud.
Then I would not need to keep the Photon idling for 1 minute, just in case there is an update.

Stop Mode sleep (System.sleep(pin,event,time)) will reestablish the connection state that was active before going to sleep - irespective of SYSTEM_MODE(). So if you want the device to stay offline after wake you need to cut the connection before calling System.sleep()
Also this is problematic

    if (!Particle.connected())
    {Particle.connect();}

Since a connection process will take several seconds, it’s not good practice to hammer the Particle.connect() command over and over again while it’s trying to do its job.

Finally, via the Particle Console and a “Product” device updates can be “queued” but in order to pull a pending update in, you still need to keep the device connected for long enough to realise the pending update and actually download and flash the new firmware.

Thank you ScruffR, the “before” connect state detail escaped me.
I am going to add WiFi.off(). Should I first do Particle.disconnect() and then WiFi.off()? I am not sure if there is an advantage.

I think Particle.connect() is a blocking function. I followed the example in the docs.
Is there a better way of doing this?

About the pending update, is this not a blocking process either?
I found some info in System.updatesPending(), but this documentation section seem to be under construction.
How would I manage the download process?

WiFi.off() should suffice. If it doesn’t it’d be on an old system version or a hard to squash bug :wink:

Particle.connect() hasn’t been a blocking function for most of the time I remember, but recently things have changed so I have lost track which version was the first to block and under what circumstances. The docs don’t always keep up with dev :sunglasses:
BTW, I much prefered the straight forward non-blocking version where the application could still attend to other things while the WiFi module could do it’s job which may take a long time in some cases. I’m not happy with the change.

Pending updates are not blocking for most of the time, only once the binary has been downloaded and the actual falshing is about to start your application will be halted - SYSTEM_THREAD(ENABLED) adds some variables to that too.

That’s a good question. There are some strategies but they all seem to be a bit hacky still.
There are some open issues on GitHub in connection with that topic.