Cellular connects when not supposed to

I am currently designing a wireless temperature sensor. Every 60 seconds I want the device to turn on, read the temperature, and send it to the cloud.

int tmp102Address = 0x48;
double tempF1;
double tempF2;
FuelGauge fuel;

SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
    Cellular.off();
    Wire.begin();
    tempF1 = 0;
}

double getTemp() {
    Wire.requestFrom(tmp102Address,2); 
    byte MSB = Wire.read();
    byte LSB = Wire.read();
    int TempSum = ((MSB << 8) | LSB) >> 4; 
    double celsius = TempSum*0.0625;
    double fahrenheit = (1.8*(celsius)) + 32.0;
    int a = round(fahrenheit * 10); 
    fahrenheit = a / 10.0; 
    return fahrenheit;
}

void loop() {
    Cellular.off();
    tempF2 = getTemp();
    if (abs(tempF2 - tempF1) > 1) {
        Cellular.on();
        Particle.connect();
        waitFor(Particle.connected, 5000);
        Particle.publish("t", String(tempF2), 16777215);
        tempF1 = tempF2;
        Cellular.disconnect();
        Cellular.off();
    }
    
    float battPercent = fuel.getSoC();
    if (battPercent > 50) {
        System.sleep(SLEEP_MODE_DEEP,SLEEP_NETWORK_STANDBY, 60);
    } else if ((battPercent < 50) && (battPercent > 25)) {
        System.sleep(SLEEP_MODE_DEEP,SLEEP_NETWORK_STANDBY, 120);
    } else if ((battPercent < 25) && (battPercent > 10)) {
        System.sleep(SLEEP_MODE_DEEP,SLEEP_NETWORK_STANDBY, 180);
    } else {
        System.sleep(SLEEP_MODE_DEEP,SLEEP_NETWORK_STANDBY, 240);
    }
    Cellular.off();
}

To save battery, I am putting the microcontroller in deep sleep for 60 seconds after every time it checks the temperature. To save data, I set my code to only update online if the temperature is 1 degree greater than before. The plan is for the device to only use data whenever the temperature needs to be updated, and then turn it off after that. If there isn’t a 1 degree temperature difference then cellular shouldn’t turn on at all.

The problem I am facing is that the device turns on cellular and connects to the cloud every 60 seconds, even when there isn’t a 1 degree temperature change. I have tried throwing in some random cellular.off()s in the code in order to fix this, but it hasn’t helped at all. Any suggestions?

If you don’t want to stay connected, you should not use SLEEP_NETWORK_STANDBY and shouldn’t that flag not be last in the parameter list?

 static void sleep(Spark_Sleep_TypeDef sleepMode, long seconds=0, SleepNetworkFlag flag=SLEEP_NETWORK_OFF);

I’m surprised your code even builds :confused:

The next thing (which might be the actual reason for what you see) is: "How do you know of a one degree difference between before and now?"
You don’t have any code that stores the old temperature across deep sleeps to compare to next time round.
TempF1 is always reset to 0 and unless you have freezing temperatures right now, your temp difference will always be greater 1°

So it actually is supposed to connect - despite you not wanting it to :wink:

1 Like

So would this be the correct fix?

STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));

int tmp102Address = 0x48;
retained double tempF1 = 0;
double tempF2 = 0;
FuelGauge fuel;

void setup() {
    Cellular.off();
    Wire.begin();
}

double getTemp() {
    Wire.requestFrom(tmp102Address,2); 
    byte MSB = Wire.read();
    byte LSB = Wire.read();
    int TempSum = ((MSB << 8) | LSB) >> 4; 
    double celsius = TempSum*0.0625;
    double fahrenheit = (1.8*(celsius)) + 32.0;
    int a = round(fahrenheit * 10); 
    fahrenheit = a / 10.0; 
    return fahrenheit;
}

boolean verifyTemp(double temp) {
    if ((temp > 0) && (temp < 200)) {
        return true;
    } else {
        return false;
    }
}

void loop() {
    tempF2 = getTemp();
    if ((abs(tempF2 - tempF1) > 1) && verifyTemp(tempF1)) {
        Cellular.on();
        Particle.connect();
        waitFor(Particle.connected, 500);
        Particle.publish("t", String(tempF2), 16777215);
        Cellular.disconnect();
        Cellular.off();
        tempF1 = tempF2;
    }
    
    float battPercent = fuel.getSoC();
    if (battPercent > 50) {
        System.sleep(SLEEP_MODE_DEEP, 90);
    } else if ((battPercent < 50) && (battPercent > 25)) {
        System.sleep(SLEEP_MODE_DEEP, 120);
    } else if ((battPercent < 25) && (battPercent > 10)) {
        System.sleep(SLEEP_MODE_DEEP, 180);
    } else {
        System.sleep(SLEEP_MODE_DEEP, 240);
    }
}

That looks better, but you should not reset your retained variable on each wake, which you do in setup()


Update:
Above comment applied to the previous version of the code

void setup() {
    Cellular.off();
    Wire.begin();
    tempF1 = 0;
}

which was edited after the post.

@jmcf were you able to get it corrected?

Sadly no, I have still been trying to fix my problem. Even with my corrected code above my device still connects to the internet every minute. I have seen four different options on this forum for retained variables: connecting SRAM to vbat, connecting to GND, connecting to 3v3, and also not having to do anything for retained variables to work. I can’t find anything except an external battery in the docs so I don’t know which are true. If its possible I’d prefer not to use another battery.

On the Electron do not connect VBAT to anything! It’s internally connected to 3V3 with a 0 ohm resistor. If you connect it to ground, you’ll short out the Electron. The instructions for connecting it to other things are really more important for the Photon, which doesn’t have a battery.

By the way, make sure you’ve upgraded your Electron to 0.5.0 or later. I think there was a bug in 0.4.8 that prevented retained memory from working correctly when in SLEEP_MODE_DEEP.

boolean verifyTemp(double temp) {
    if ((temp > 0) && (temp < 200)) {
        return true;
    } else {
        return false;
    }
}

I guess now (after you edited your previous code) this code in connection with this check is tripping you up again

    tempF2 = getTemp();
    if ((abs(tempF2 - tempF1) > 1) && verifyTemp(tempF1)) 

Your retained tempF1 is initialized with 0, so that if() will never ever be satisfied and hence tempF1 will never change from 0 to a valid number.

I guess you actually wanted to check for verifyTemp(tempF2), or not?


Please don’t edit your code in previous posts, since it renders comments refering to it confusingly inapplicable and as in this case introducing new errors to code sections that have been fine before might prevent you from getting pointed to it (if I hadn’t reread the whole lot and checked the edit history).

Ahh correct, thanks for that catch. I’ll run it right now and see if it works.

1 Like

@ScruffR It mostly works now. It still connects to the cloud for a short amount of time, but it doesn’t publish a new variable. Should I switch the mode to Semi-automatic or should I add

Startup() { 
    Cellular.off(); 
}

Sure, when you know your device would be offline regularly using a non-AUTOMATIC mode is always better.
MANUAL would also start with Cellular.off() while SEMI_AUTOMATIC uses (AFAIK) Cellular.on() but doesn’t really connect to the cell network.
You might see a change of color with SEMI_AUTOMATIC since you do call Cellular.off() but that’s not an indication that the device tried to connect.