E-series/electron sleep mode, manual mode for full control, etc

My application is that I need to publish a temperature once every 5 minutes. Simply using delay(300000) works fine with the cell modem on all the time, but of course that drains my batteries.

Is there any known good sample code that utilizes the System.sleep() function and/or Manual system mode to turn the cell radio on and off so as to preserve batttery life?

The documentation is simply terrible and just doesn’t give good, practical examples of using many of the functions. I’ve tried setting to manual mode, putting Cellular.off() in the setup routine, then using millis() for elapsed time, and after 5 minutes use this basic paradigm: Cellular.on() > if(Cellular.ready()) > Particle.connect() > if(Particle.connected()) > Particle.publish(). I’ve tried various permutations and combinations, and adding delays throughout to give reasonable amounts of time to wait for things to connect. Someone mentioned to check RSSI instead of Cellular.ready() as I guess there’s a bug where ready() returns true sometimes before there’s a solid cell connection.

Anyway, this is maddening. I would have thought turning the radio/internet on and off every 5 minutes wouldn’t be a big deal, but I just can’t find any solid examples or straightforward explanations on how to properly use these APIs. Someone elsewhere suggested System.sleep() which supposedly turns the radio off and on automatically, but that only seems to work halfway because it never seems to connect to the cloud after wakeup.

help!

The over all negative undertone I sense may not really benefit your cause IMHO.

One thing I’d suggest tho’ is to state what system version your device is running and if it’s not 0.6.4 try to update.
Maybe even investigate 0.7.0-rc.7 and/or 0.8.0-rc.2.

1 Like

Sorry, just very frustrated. I’ll look into changing versions since I’m currently running 0.5.4.

OK, frustration asside, when you say you want your device to be active very briefly to acquire the temperature and actually publish every 5 minutes, I’d suggest not to go SYSTEM_MODE(MANUAL) but stick with default SYSTEM_MODE(AUTOMATIC) and use System.sleep(SLEEP_MODE_DEEP, 300, SLEEP_NETWORK_STANDBY).
Tearing down the cellular connection and reestablishing it every five minutes will blow through your data in no time and also cost extra power on reconnection. With SLEEP_NETWORK_STANDBY the connection will be held alive by the cellular module but in a low-power mode.

ok thanks i’ll give that a try. do i use SYSTEM_SLEEP(SLEEP_MODE_DEEP, 300, SLEEP_NETWORK_STANDBY) simply as the last line of code in the main loop ? so the main loop would be my normal code to publish the data and then just at the very end go to sleep? after the sleep period it would then just start back at the beginning of the loop like normal, kind of like having delay(300000) at the end?

also am i correct in assuming it should be System.sleep() not SYSTEM_SLEEP() ?

Sorry, that was a typo (corrected).

Actually deep sleep does not continue with loop() but basically causes a System.reset() when it wakes up, starting with setup() (and STARTUP() if provided) again.
To store variables across the reset, you need to use retained variables.

Ok not sure what’s happening but I appear to have screwed things up. as of right now, I can’t flash in listen mode, and have to flash from safe mode with CLI. also, from the RGB LED, it looks like it continually is trying to connect (flashing green), then immediately disconnects (breathing white). I never see a “device came online” event.

here’s my code:

SYSTEM_MODE(AUTOMATIC);

const char * myWriteAPIKey = "ABC123DEF456GHI789"; // API write key for ThingSpeak

// MSP getMeas, temp & battery (proprietary UART protocol for connected board)
const uint8_t serCmd[] = {0x80,0x00,0x00,0x80,0x28,0x04,0xc0,0x00,0x00,0x00,0x25,0x4d}; 

PMIC pmic; // PMIC class object instantiation

int numBytes;

char rcvBytes[255], debugMsg[255];

float t, b, sigQual;

CellularSignal sig;

void debugCmdHandler(const char *event, const char *data)
{

    sig = Cellular.RSSI();
    sigQual = (float)sig.qual / 49 * 100;
    snprintf(debugMsg, sizeof(debugMsg), "Signal Strength: %idBm; Signal Quality: %.2f%%", sig.rssi, sigQual);

    Particle.publish("debug", debugMsg);
}

void setup() 
{
    /*
    Using LIPO battery connector as 3.5V power input from M2000,
    charging circuit must be disabled, and PMIC compliance voltage
    lowered to something below new nominal input.
    */
    pmic.setInputCurrentLimit(500);
    pmic.disableCharging();
    pmic.setMinimumSystemVoltage(3300);
    pmic.begin();
    
    
    // We open up a serial port to monitor the sensor values
    Serial.begin(9600); 
    
    Serial1.begin(115200, SERIAL_8N1); // UART comm to M2000 dev board
    
    Particle.subscribe("debugCmd", debugCmdHandler);
}

void loop() 
{
    Serial1.write(serCmd,sizeof(serCmd));
    
    delay(100);
    
    numBytes = Serial1.available();

    if (Serial1.available() > 0)
    {
        for (int i=0;i<numBytes;i++)
        {
            rcvBytes[i] = Serial1.read();
        }
        
        b = *(float *)&rcvBytes[16]; //battery
        t = *(float *)&rcvBytes[24]; //temp
        
        if (Particle.connected() == true)
        {
            Particle.publish("thingspeaktemp", String (t));
            Particle.publish("thingspeakhumi", String (b));
            Serial.print(Time.timeStr());
            Serial.printf(" Temp = %.3f; Batt = %.3f%%",t,b);
        }
        else
        {
            Serial.println("Particle cloud/cellular not connected!");
        }
    }
    else
    {
        Serial.println("UART receive error!");
    }
    
    System.sleep(SLEEP_MODE_DEEP, 300, SLEEP_NETWORK_STANDBY);
}

also it flashes some kind of orange/yellow color between flashing green and breathing white.

Are you already on 0.6.4 or higher? With older system versions you had to have a delay(5000) before going into deep sleep to have Particle.publish() to finish properly.

I suppose you were using CLI to flash in Listening Mode via particle flash --serial <yourFirmware.bin>, right?
If you are using CLI I'd rather use DFU Mode particle flash --usb <yourFirmware.bin> anyway.

I’ve only been using CLI because I can’t do OTA. As of right now I’ve got the code totally stripped down to a delay(10000) and a publish in the main loop, and the device just sits there with a very rapid cyan flashing (like 5Hz+). This device was working before I started messing with the power saving stuff. In my device list it doesn’t show any problems, and has data remaining so it’s not paused. I’m worried I’ve broken it.

I have another device that’s paused because I accidentally exceeded the 5Mbs. Will the site let me unpause it and connect it again? If so I can try this same minimal firmware I just downloaded and see whether that modem can connect.

This should not have broken your device, but yes, you should be able to lift the 5MB limit to allow “unpause” your SIM.
You can also swap SIMs since the SIM and the device aren’t really linked to one-another.

Not sure if that’s possible on an Electron, but i’m using the e-series dev board and i don’t have access to the SIM card. I’ll try using the other device.

I see, on an Electron swapping SIMs is definetly possible but on the E-Series definetly not.

Something weird is definitely going on. I’m sure like you say there’s no relationship with what I’ve been doing, but I now can’t get either device online. we’ll call this second one, previously known working, #2. With #1 i thought the issue was what i’ve been messing around with, and #1 is stuck on rapid flashing cyan. I unpaused #2, but it is running the same simple firmware and it’s stuck on flashing green.

Does Safe Mode do anything different?
Could it be that your local cell provider has some maintenance going on?