Electron sleep(nn) works but sleep(SLEEP_MODE_DEEP,nn) not working


#1

My electron is being used on a weather station. It worked for a while, then wouldn’t wake from sleep(nn) or sleep(SLEEP_MODE_DEEP,nn). I figured it was the antenna, so put on an antenna with 3.5 Dbi gain. The sleep(nn) works, but not the sleep(SLEEP_MODE_DEEP,nn).

I know the problem is not due to a weak signal since the cellular sleep works. This is my third Electron with problems. I am beginning to think that the Particle IoT products are not reliable enough for prime time.

Below is the simplified code. It collects data for 5 minutes then publishes it. After publishing the cellular is put to sleep for three minutes, and thus has 2 minutes to regain cellular signal before the next time to publish. This part works. After five times publishing, the electron is put to deep sleep for 5 minutes. (The real code has it sleeping overnight). The Electron never wakes up from deep sleep.

unsigned long thingspeakChannelNumber = xxxxxxxx;
char thingSpeakWriteAPIKey[] = "XXXXXXXXXXXXXX";

// Each time we loop through the main loop, we check to see if it's time to publish the data we've collected
unsigned int publishPeriod = 300000;
unsigned int timeNextPublish; 
int publishCount = 0;
String api_key = "XXXXXXXXXXXXXXXXXX"; // Replace this string with a valid ThingSpeak Write API Key.
String field1 = "";
String field2 = "";  // i.e. field2 is null
String field3 = "";
String field4 = "";    
String field5 = "";
String field6 = "";
String field7 = "";
String field8 = "";
String lat = "";
String lon = "";
String el = "";
String status = "";

void setup() {
    // Set time zone to Eastern USA STANDARD time
    Time.zone(float(-5));
    timeNextPublish = millis() + publishPeriod; 
    publishCount = 0;
//    Particle.connect();
}

void loop() {
      if (publishCount < 5) {               //  Publish for 5 periods
          
          // collect data etc.
          
        if(timeNextPublish <= millis()) {   // Publish every 5 minutes (300000 seconds)
            publishCount += 1;
            float tempF = publishCount;     // Simlification just to have something to publish in example
            publishToThingSpeak(tempF);
            delay(20000);                   // make sure publish has time to complete
            timeNextPublish = millis() + publishPeriod;
            System.sleep(180);              // Turn cellular off for 3 minutes to save power 
                                            // 2 minutes remain to regain cellular brfore next publish
        }

    } else {                                // time for deep sleep after 5 publish periods
        publishCount = 0;
        waitUntil(Cellular.ready);          // Make sure to wakeup from previous sleep
        System.sleep(SLEEP_MODE_DEEP,300);  // deep sleep for 5 minutes
    }
}  // end loop

void publishToThingSpeak(float tempF) {
    // To write multiple fields, you set the various fields you want to send
    
    field1 = String(tempF,1);
/*
    field2 = String(humidityRH,0);
    field3 = String(pressureKPa,1);
    field4 = String(rainInches,1);
    field5 = String(windMPH,1);
    field6 = String(gustMPH,1);
    field7 = String(windDegrees, 0);
    field8 = String(voltage,1);
*/
    String TSjson;
    createTSjson(TSjson);
    Particle.publish("TSwriteall",TSjson,60,PRIVATE);

}
void createTSjson(String &dest)
{
  // dest = "{ \"k\":\"" + api_key + "\", \"1\":\""+ field1 +"\", \"2\":\""+ field2 +"\",\"3\":\""+ field3 +"\",\"4\":\""+ field4 +"\",\"5\":\""+ field5 +"\",\"6\":\""+ field6 +"\",\"7\":\""+ field7 +"\",\"8\":\""+ field8 +"\",\"a\":\""+ lat +"\",\"o\":\""+ lon +"\",\"e\":\""+ el +"\", \"s\":\""+ status +"\"}";
    dest = "{"
    if(field1.length()>0){
        dest = dest + "\"1\":\""+ field1 +"\",";
    }
    if(field2.length()>0){
        dest = dest + "\"2\":\""+ field2 +"\",";
    }
    if(field3.length()>0){
        dest = dest + "\"3\":\""+ field3 +"\",";
    }
    if(field4.length()>0){
        dest = dest + "\"4\":\""+ field4 +"\",";
    }
    if(field5.length()>0){
        dest = dest + "\"5\":\""+ field5 +"\",";
    }
    if(field6.length()>0){
        dest = dest + "\"6\":\""+ field6 +"\",";
    }
    if(field7.length()>0){
        dest = dest + "\"7\":\""+ field7 +"\",";
    }
    if(field8.length()>0){
        dest = dest + "\"8\":\""+ field8 +"\",";
    }
    if(lat.length()>0){
        dest = dest + "\"a\":\""+ lat +"\",";
    }
    if(lon.length()>0){
        dest = dest + "\"o\":\""+ lon +"\",";
    }
    if(el.length()>0){
        dest = dest + "\"e\":\""+ el +"\",";
    }
    if(status.length()>0){
        dest = dest + "\"s\":\""+ status +"\",";
    }
    dest = dest + "\"k\":\"" + api_key + "\"}";
}

#2

It’s not quite clear what this waitUntil(Cellular.read); before deep sleep should do :confused:

I also don’t really get the connection between not waking and the antenna :confused:


#3

ScruffR,

Thanks for responding.

The waitUntil(Cellular.ready); before the deep sleep was to make sure the electron had regained the cellular connection from the previous sleep(nn) since I read that the deep sleep restored the state to the previous state before the sleep. Doesn’t matter since I have the same results with or without the statement.

I was getting an inconsistent wakeup before with the antenna provided due to low signal strength. I read that, if the cellular connection cannot be re-established, the Electron will not wake up from sleep. I believe the original antenna has about a -2.5 Dbi capability. I replaced it with a 3.5 Dbi antenna from Adafruit and improved reception. All the sleep(nn) now worked - but not the deep sleep. What is different between the two sleeps that would cause sleep(nn) to consistently wake up but sleep(SLEEP_MODE_DEEP,nn) not to wake up?

I have purchased 3 Electrons and each one stopped working after a while. One was replaced by Particle. It begins to get expensive for a simple weather station.

Thanks,

Lee


#4

I wouldn’t know how the “future” ability to connect would affect the wake before the fact. The modem will be powered down (unless SLEEP_NETWORK_STANDBY was used on sleep) during sleep so the connection state won’t have any influence on the actual wake as the reconnect will only happen after wake.

Sleep(nn) is no sleep at all, it’s nothing else than WiFi.off() with a subsquent timed WiFi.on()/Particle.connect().

Have you downloaded CLI 1.25.0 and perforemed a particle update already?


#5

I realize the sleep(nn) only turns off/on the cellular. It works!
Please ignore the sleep(nn). The sleep(SLEEP_MODE_DEEP,NN) is not working.
I had CLI 1.25.0. I updated to CLI 1.27.0. No change in code behavior
I updated the Electron firmware to version 0.7.0-rc.4 and recompiled the app to match that version of firmware. No change.
I deleted the sleep(nn) since I know it works (and removed the waitUntil(Cellular.ready)). Now the code still publishes every 5 minutes but the Electron still doesn’t wake from deep sleep. I can’t get any simpler.

void loop() {
      if (publishCount < 5) {               //  Publish for 5 periods
          
          // collect data etc.
          
        if(timeNextPublish <= millis()) {   // Publish every 5 minutes (300000 seconds)
            publishCount += 1;
            float tempF = publishCount;     // Simplification just to have something to publish in example
            publishToThingSpeak(tempF);
            delay(20000);                   // make sure publish has time to complete
            timeNextPublish = millis() + publishPeriod;
        }

    } else {                                // time for deep sleep after 5 publish periods
        publishCount = 0;
        System.sleep(SLEEP_MODE_DEEP,300);  // deep sleep for 5 minutes
    }
}  // end loop

#6

I’ll try your code on one of my Electrons (withouth the ThingSpeak stuff tho’)

BTW, have you got anything hooked to the WKP pin?


Update:
Just tried with 0.6.2 and my device woke just fine.
Will try with 0.6.3, 0.6.4 and 0.7.0-rc.3 now (rc.4 seems to have issues with long running sketches) next.

Update2:
Yup, works on all of them as expected.

BTW, although I tried with your original code, I couldn’t resist rewriting this a bit

const uint32_t thingspeakChannelNumber = 1234567890;
const char     api_key[]             = "XXXXXXXXXXXXXXXXXX"; // Replace this string with a valid ThingSpeak Write API Key.

// Each time we loop through the main loop, we check to see if it's time to publish the data we've collected
const uint32_t publishPeriod = 300000;
uint32_t timeLastPublish; 

const int fieldCount = 13; 
char fieldNames[fieldCount][ 4] = { "dmy", "1", "2", "3", "4", "5", "6", "7", "8", "a", "o", "e", "s" };
char fields    [fieldCount][12]; // for testing: = { ".dmy", ".1", ".2", ".3", ".4", ".5", ".6", ".7", ".8", ".lat", ".lon", ".el", ".status" };
int  publishCount;

void setup() {
    // Set time zone to Eastern USA STANDARD time
    Time.zone(-5);
    timeLastPublish = millis(); 
    publishCount = 0;
    
//    Particle.connect();

}

void loop() {
      if (publishCount < 5) {               //  Publish for 5 periods
          
          // collect data etc.
          
        if(millis() - timeLastPublish <= publishPeriod) {   // Publish every 5 minutes (300000 seconds)
            publishCount += 1;
            float tempF = publishCount;     // Simlification just to have something to publish in example
            publishToThingSpeak(tempF);
            delay(20000);                   // make sure publish has time to complete
            timeLastPublish = millis();
            //System.sleep(180);              // Turn cellular off for 3 minutes to save power 
                                            // 2 minutes remain to regain cellular brfore next publish
        }

    } else {                                // time for deep sleep after 5 publish periods
        //publishCount = 0;
        //waitUntil(Cellular.ready);          // Make sure to wakeup from previous sleep
        System.sleep(SLEEP_MODE_DEEP,300);  // deep sleep for 5 minutes
    }
}  // end loop

void publishToThingSpeak(float tempF) {
    // To write multiple fields, you set the various fields you want to send
    snprintf(fields[1], sizeof(fields[1]), "%.1f", tempF);
/*
    snprintf(fields[2], sizeof(fields[2]), "%.0f", humidityRH);
    snprintf(fields[3], sizeof(fields[3]), "%.1f", pressureKPa);
    snprintf(fields[4], sizeof(fields[4]), "%.1f", rainInches);
    snprintf(fields[5], sizeof(fields[5]), "%.1f", windMPH);
    snprintf(fields[6], sizeof(fields[6]), "%.1f", gustMPH);
    snprintf(fields[7], sizeof(fields[7]), "%.0f", windDegrees);
    snprintf(fields[8], sizeof(fields[8]), "%.1f", voltage);
*/
    char TSjson[196];
    createTSjson(TSjson, sizeof(TSjson));
    Particle.publish("TSwriteall",TSjson,60,PRIVATE);
}

void createTSjson(char *dest, int len)
{
    strcpy(dest, "{");
    
    for (int i=1; i < fieldCount; i++) {
        if (strlen(fields[i]))
            snprintf(dest+strlen(dest), len-strlen(dest), "\"%s\":\"%s\",", fieldNames[i], fields[i]);
    }

    snprintf(dest+strlen(dest), len-strlen(dest), "\"k\":\"%s\"}", api_key);
}

And make sure nothing is pulling WKP high before/when you send the device to sleep.
https://github.com/spark/firmware/issues/1262


#7

Thanks for the code verification and rewrite.
The electron was on a Sparkfun Weather Shield (and was working before). I disconnected the Electron from the Weather Shield to ensure the WKP was not pulled high (nothing is connected to it). Still no wake up.
I guess once again I have a defective Electron (#3).

ScruffR, thank again for all your effort. After sinking several hundred dollars into a weather station for my flying club (without reimbursement for a non working weather station), I must consider sucking up the loss and stopping this project due to unreliable Particle IoT technology.

Cheers,

Lee


#8

I can’t vouch for the Sparkfun Weather Shield, but I have a fair amount of Particle devices and have never had any problems with the reliability of the devices nor the backend. Sure there might be the one-off defective device in a batch, but with a 100% failure rate I’d search the issue elsewhere.

Maybe @KyleG or @rickkas7 can find a way to resurrect your faith in Particle :wink:


#9

“Sure there might be the one-off defective device in a batch, but with a 100% failure rate I’d search the issue elsewhere.”

ScruffR,

You may possibly be right. My weather station is housed in a Ambient Weather SRS100LX Temperature and Humidity Solar Radiation Shield, uses SparkFun Weather Meters, SparkFun Photon Weather Shield, and the Particle Electron. It is powered by a 5000 mA battery connected to the Electron. The 5000 mA battery is kept charged by a Voltaic 4000 mA battery connected to the Electron USB port, which is in turn charged by a 6W solar panel. All this is mounted on a pole.

Maybe the Electron got wet during one of the rain/wind storms we have had. Or, maybe it’s just due to human malfunction:)

I will make one final attempt and ask @KyleG or @rickkas7 for assistance.

Thanks,

Lee