Issues using sleep mode with 3rd party sim and ThingSpeak

So I am able to transmit data to ThingSpeak just fine using a 3rd party sim. I am using an Electron with firmware 0.6.2. My issue is I cannot get any sleep modes to work properly. The device breaths blue then shuts off for the time specified but no data is transmitted. I have adjusted the delay before the sleep function. I have tried multiple variations of the program code. I would think that the data would be transmitted before it reached the sleep function. Has anyone been able to post to ThingSpeak, go to sleep, wake up and repeat. Any assistance would be of great help. I provided a few iterations of the program code.

#include "ThingSpeak.h"
#include "cellular_hal.h"

STARTUP(cellular_credentials_set("broadband", "", "", NULL));

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

TCPClient client;

unsigned long myChannelNumber = **********;
const char * myWriteAPIKey = "***************";

void setup() {
  ThingSpeak.begin(client);
  

	Particle.keepAlive(300);
}

void loop() {
    
  float pinVoltage = analogRead(A0) * (3.3 / 4095.0);

  ThingSpeak.setField(1,pinVoltage);

  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  

  delay(60000); // ThingSpeak will only accept updates every 15 seconds. 

Cellular.on();
  delay(10000);
  Cellular.command("AT+CPWROFF\r\n");
  delay(2000);
  FuelGauge().sleep();
  delay(2000);
  System.sleep(SLEEP_MODE_DEEP, 30);

}

or

#include "ThingSpeak.h"
#include "cellular_hal.h"

STARTUP(cellular_credentials_set("broadband", "", "", NULL));

TCPClient client;

unsigned long myChannelNumber = **********;
const char * myWriteAPIKey = "***************";

void setup() {
  ThingSpeak.begin(client);
  

	Particle.keepAlive(300);
}

void loop() {
    
  float pinVoltage = analogRead(A0) * (3.3 / 4095.0);

  ThingSpeak.setField(1,pinVoltage);

  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  

  delay(60000); // ThingSpeak will only accept updates every 15 seconds. 

  System.sleep(SLEEP_MODE_DEEP, 30);
}

I’m not really familiar with the ThingSpeak library, but in general I’d say when you want some network connection (which TS definetly will need) you should connect to the network before you try to send any data via that.
Since you are using SEMI_AUTOMATIC mode, the network won’t be connected at the time you’re intending to use it.
I’d say you’ll need something like

  Cellular.connect();
  // if(!waitFor(Cellular.connected, 300000))  // that was wrong
  if(!waitFor(Cellular.ready, 300000))
    System.sleep(SLEEP_MODE_DEEP, 30);

before any TS action.

So I don’t think your trouble is connected to sleep mode in any way but rather the use of TS without network won’t work even without trying to send the device to sleep.

BTW, for general math reasons I’d rather set my parentheses like this

float pinVoltage = (analogRead(A0) * 3.3) / 4095.0;
// this
// float pinVoltage = analogRead(A0) * (3.3 / 4095.0);
// would introduce a massive loss of precision

Please excuse my lack of knowledge in programming but is there a library that accompanies these functions because the compiler did not like this. Below are the errors I got. I inserted the code in the beginning of the loop before the TS action.

…/wiring/inc/spark_wiring_system.h:165:40: error: could not convert ‘_condition.loop()::__lambda4()’ from ‘void’ to 'bool’
while (_while() && !_condition()) {
^
…/wiring/inc/spark_wiring_system.h:165:28: error: in argument to unary !
while (_while() && !_condition()) {
^
…/wiring/inc/spark_wiring_system.h:168:27: error: void value not ignored as it ought to be
return _condition();
^

#include "ThingSpeak.h"
#include "cellular_hal.h"

STARTUP(cellular_credentials_set("broadband", "", "", NULL));

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

TCPClient client;

unsigned long myChannelNumber = *********;
const char * myWriteAPIKey = "************";

void setup() {
  ThingSpeak.begin(client);
  

	Particle.keepAlive(300);
}

void loop() {
    
  Cellular.connect(); 
  if(!waitFor(Cellular.connected, 300000))
    System.sleep(SLEEP_MODE_DEEP, 30);
    

  float pinVoltage =(analogRead(A0) * 3.3) / 4095.0;

  ThingSpeak.setField(1,pinVoltage);

  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  

  delay(60000); 



}

Sorry, that should be Cellular.ready not Cellular.connected - I updated my code above

But this should actually even happen before ThingSpeak.begin() in void setup() since you can’t really start a TCPClient without network either.

I adjusted the code . The device is breathing green now (not sure if this is telling)…? It IS transmitting data but I am still reading approx 45mA with the K100 probe when in the delay(60000) and around 650mA when transmitting so I do not think the device is actually going to sleep at any point. I have also tried adjusting the seconds in the sleep function. Any other suggestions. Here is the complete program code.

    #include "ThingSpeak.h"
    #include "cellular_hal.h"

    STARTUP(cellular_credentials_set("broadband", "", "", NULL));

    SYSTEM_MODE(SEMI_AUTOMATIC);
    SYSTEM_THREAD(ENABLED);

    TCPClient client;


    unsigned long myChannelNumber = ******************;
    const char * myWriteAPIKey = "*************";

    void setup() {
     
        Cellular.connect();
        if(!waitFor(Cellular.ready, 300000))
          System.sleep(SLEEP_MODE_DEEP, 120);
        ThingSpeak.begin(client);
      
    	Particle.keepAlive(300);
    }

    void loop() {
        
      float pinVoltage =(analogRead(A0) * 3.3) / 4095.0;
      ThingSpeak.setField(1,pinVoltage);
   
      ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  

      delay(60000); 
    }

I have indented the sleep instruction as it should be to show that the device will only go to sleep when it’s unable to connect to the cellular network within 5 minutes.
But if it can, the device won’t sleep, as you removed your original sleep instruction from loop().

BTW, breathing green is correct in this situation as it indicates connected to network but not to cloud.

1 Like

Everything is working great. Thanks for your help. The sleep mode power down works perfectly. It has been a steep learning curve for me so I appreciate your patience. I’m curious about one thing though. When I wasn’t using sleep mode and did not use SYSTEM_MODE(SEMI_AUTOMATIC); SYSTEM_THREAD(ENABLED);and Cellular.connect(), I was still able to transmit data via GSM (breathing blue)…? Why did it not affect transmission without SYSTEM_MODE(SEMI_AUTOMATIC); SYSTEM_THREAD(ENABLED);and Cellular.connect(), but when I put the sleep function in, I needed it.

If you are not explicitly stating any SYSTEM_MODE(), the default mode is SYSTEM_MODE(AUTOMATIC) in which the system makes sure the cellular and cloud connection are established automatically before your program can start running.
But this behaviour is independent of sleep or not.

BTW, we call the RGB LED indicating an active cloud connection breathing cyan

1 Like