Does anyone have a clue why the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 shield starts to fail after about 12 hours in this 30 min loop. The board is powered by the Arduino Uno rev3. It is using a Hologram Sim card. The REST-API is not an issue as other shields and/or microcontrollers using a Hologram SIM card do post continously to the endpoint which is outside the hologram network.
Something about this board, it would seem, causes it to get stuck in the loop “GPRS #2 not connected”
/*
* Sketch: Sparkfun_from_scratch_with_TinyGSM_HttpsClient_Post_Json_LTE
*/
const char server[] = "your-restapi-domain-name";
const char resource[] = "your-path-to-your-endpoint";
const int port = 443;
// Note: 3600000 is 1 hour.
// Example: delay(60UL * 60UL * 1000UL); //60 minutes each of 60 seconds each of 1000 milliseconds all unsigned longs
// unsigned long sleeping_ms = ((60UL * 60UL * 1000UL) - 60000UL);
unsigned long sleeping_ms = (1800000UL); // 30 minutes
//unsigned long sleeping_ms = (1200000UL); // 20 minutes
//unsigned long sleeping_ms = (600000UL); // 10 minutes
//unsigned long sleeping_ms = (300000UL); // 10 minutes
//unsigned long sleeping_ms = (60000UL); // 1 minutes
//unsigned long sleeping_ms = (30000UL); // 0.5 minutes
#define TINY_GSM_MODEM_SARAR4
#include <SparkFun_LTE_Shield_Arduino_Library.h>
#include <SoftwareSerial.h>
#include <TinyGsmClient.h>
//#include <ArduinoJson.h>
#include <UpTime.h> // https://github.com/jozef/Arduino-UpTime
#include <ArduinoHttpClient.h>
SoftwareSerial lteSerial(8, 9);
LTE_Shield lte;
#define SerialMonitor Serial
#define LTEShieldSerial lteSerial
#define POWER_PIN 5
#define RESET_PIN 6
// Don't use this, if there are problems go back to 00_Register_Operator sketch
// MNO_SW_DEFAULT -- DEFAULT
// MNO_ATT -- AT&T
// MNO_VERIZON -- Verizon
// MNO_TELSTRA -- Telstra
// MNO_TMO -- T-Mobile
const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_ATT;
const String APN = "hologram";
const char apn[] = "hologram";
const char gprsUser[] = "";
const char gprsPass[] = "";
TinyGsm modem(LTEShieldSerial);
String current_imei = "";
void setup() {
SerialMonitor.begin(9600);
delay(2000);
SerialMonitor.println(F("Sketch: Sparkfun_from_scratch_with_TinyGSM_HttpsClient_Post_Json_LTE"));
powerOnShield();
initializeShield();
current_imei = setMno();
checkStatusTinyGSM(); // may not be necessary
}
void loop() {
SerialMonitor.println("Entering loop ...");
String current_uptime = getUptime();
//makeJsonPost(current_imei, current_uptime);
makeHttpsPost(current_imei, current_uptime);
/*
SerialMonitor.println(F("Blink on 5 sec ... web request finished"));
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(5000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
*/
SerialMonitor.println(current_uptime);
SerialMonitor.print(F("Sleeping for "));
SerialMonitor.print(sleeping_ms);
SerialMonitor.println(F(" ms Note: 3600000 is 1 hour\r\n"));
delay(sleeping_ms);
powerOnShield();
initializeShield();
checkStatusTinyGSM(); // may not be necessary
}
void makeHttpsPost(String current_imei, String current_uptime) {
String contentType = "application/json";
String postData = "{\"uptime\":\"";
postData += current_uptime;
postData += "\",\"imei_string\":\"";
postData += current_imei;
postData += "\"}";
TinyGsmClientSecure client(modem);
HttpClient http(client, server, port);
// The above, "first part" ran okay, i.e. 13 hours, 30 min loop.
SerialMonitor.println(F("Performing HTTPS POST request..."));
SerialMonitor.println(postData);
int err = http.post(resource, contentType, postData);
if (err != 0) {
SerialMonitor.println(F("failed to connect"));
delay(10000);
return;
}
// return; // 2nd part
// Testing the above, "second part"
// Mostly stable here
int status = http.responseStatusCode();
SerialMonitor.print(F("Response status code: "));
SerialMonitor.println(status);
if (!status) {
delay(10000);
return;
}
return; // 4th part
SerialMonitor.println(F("Response Headers:"));
while (http.headerAvailable()) {
String headerName = http.readHeaderName();
String headerValue = http.readHeaderValue();
SerialMonitor.println(" " + headerName + " : " + headerValue);
}
int length = http.contentLength();
if (length >= 0) {
SerialMonitor.print(F("Content length is: "));
SerialMonitor.println(length);
}
SerialMonitor.println(F("Done for tonight .... go to sleep"));
}
void initializeShield() {
bool connected = false;
while (!connected) {
if ( lte.begin(LTEShieldSerial, 9600) ) {
connected = true;
SerialMonitor.println(F("LTE Shield connected!"));
delay(1000);
return;
} else {
SerialMonitor.println(F("LTE Shield not connected!"));
delay(1000);
//knock out "while"
//connected = true;
}
}
}
/* Saving on memory - commenting out for the time being
void printInfo(void) {
String currentApn = "";
IPAddress ip(0, 0, 0, 0);
String currentOperator = "";
// SerialMonitor.println(F("Connection info: \r\n"));
// APN Connection info: APN name and IP
if (lte.getAPN(¤tApn, &ip) == LTE_SHIELD_SUCCESS) {
SerialMonitor.println("APN: " + String(currentApn));
SerialMonitor.print(F("IP: "));
SerialMonitor.println(ip);
}
// Operator name or number
if (lte.getOperator(¤tOperator) == LTE_SHIELD_SUCCESS) {
SerialMonitor.print(F("Operator: "));
SerialMonitor.println(currentOperator);
} else {
SerialMonitor.println(F("Operator: Unknown - Yikes!"));
}
}
*/
String getUptime() {
return "uptime: " + uptime_as_string() + " or "+ uptime() + "s";
}
void powerOnShield() {
SerialMonitor.println(F("start: poweron"));
pinMode(5,OUTPUT);
digitalWrite(5,HIGH);
delay(3200);
digitalWrite(5,LOW);
delay(10000);
SerialMonitor.println(F("end: poweron"));
}
// Suspecion: this function perhaps uses up memory if used in loop, causing the program to hang
String setMno(){
bool connected = false;
while (!connected) {
if (lte.setNetwork(MOBILE_NETWORK_OPERATOR)) {
connected = true;
delay(1000);
bool connected02 = false;
while (!connected02) {
if (lte.setAPN(APN) == LTE_SHIELD_SUCCESS) {
connected02 = true;
delay(5000);
SerialMonitor.println(F("APN set"));
return lte.imei();
} else {
SerialMonitor.println(F("APN not set"));
//knock out "while"
//connected02 = true;
}
delay(1000);
}
} else {
SerialMonitor.println(F("Error setting MNO"));
//knock out "while"
//connected = true;
}
delay(1000);
}
}
void checkStatusTinyGSM() {
bool connected = false;
while (!connected) {
if (modem.gprsConnect(apn, gprsUser, gprsPass)) {
connected = true;
SerialMonitor.println(F("GPRS #1 connected"));
bool connected02 = false;
while (!connected02) {
if (modem.isGprsConnected()) {
connected02 = true;
SerialMonitor.println(F("GPRS #2 connected"));
return;
} else {
SerialMonitor.println(F("GPRS #2 not connected"));
delay(1000);
//knock out "while"
//connected02 = true;
}
}
delay(1000);
} else {
SerialMonitor.println(F("GPRS #1 not connected"));
delay(1000);
//knock out "while"
//connected = true;
}
}
}