@ScruffR, @jimini, @rwb, @bacichetti, @seulater, @italex
New day, I have good news (good??)!
I flashed 6 devices yesterday with a test firmware and 2 of them are presenting the issue today. It really takes several hours before the behaviour surfaces.
I can see memory degradation. The healthy devices keep a steady 48k of free memory.
The 2 devices losing Cloud connection keep oscillating the total free memory. They lose from 1-4k everytime they go offline/online to a point where the memory rises back to 48k and the cycle starts again.
I can see the RGB blinking cyan during the Cloud reconnections and once every several cycles the RGB will also blink red.
here is the test code I’m using, it’s just a snippet of the code from my production devices.
const int NUM_SCHEDULES = 25;
const int SCHEDULE_LENGTH = 27;
// FUNCTION DECLARATIONS ********************************
int transmit(String command);
int setSchedule(String command);
int setVariable(String command);
int callTest(String command);
// Variables
char scheduleString[NUM_SCHEDULES * SCHEDULE_LENGTH];
char strcountTcpUsage[20];
char statusVariables[400];
char networkVariables[200];
char lastSchedule[100]; //schedule + time
char lastTransmit[25];
char locationVar[200];
char lastLostSubscription[26];
String myLocalIp;
String myPublicIP;
int rssi;
String ssid;
String serialName;
unsigned long previousMillis;
unsigned long cycleTimer_ms;
// callback handler for Particle subscribe public ip and device name,
void handler(const char *topic, const char *data);
void setup() {
Particle.function("transmit", transmit);
Particle.function("setschedule", setSchedule);
Particle.function("setvariable", setVariable);
Particle.function("calltest", callTest);
// Exposed Variables - max 20 (max name length is 12 char)
Particle.variable("status", statusVariables, STRING);
Particle.variable("network", networkVariables, STRING);
Particle.variable("schedulelist", scheduleString, STRING);
Particle.variable("lastschedule", lastSchedule, STRING);
Particle.variable("lastLostSubs", lastLostSubscription, STRING);
Particle.variable("lasttransmit", lastTransmit, STRING);
Particle.variable("location", locationVar, STRING);
Particle.variable("countTcpCall", strcountTcpUsage , STRING);
// Subscriptions
Particle.subscribe("particle/", handler); // to handle Spartk web responses, like the Public IP
updateWiFiInfo();
}
void loop() {
cycleTimer_ms = millis() - previousMillis;
if(millis() - previousMillis > 250){
Particle.publish("debug/loop_delay", String(cycleTimer_ms), 60, PRIVATE );
Particle.publish("debug/free_memory", String(System.freeMemory()), 60, PRIVATE );
}
previousMillis = millis();
}
int transmit(String command){
Particle.publish("debug/transmit", command, 60, PRIVATE );
}
int setSchedule(String command){
}
int setVariable(String command){
updateWiFiInfo();
}
int callTest(String command){
if(command == "reset"){
System.reset();
}
else if(command == "rssi"){
Particle.publish("debug/rssi", String(WiFi.RSSI()), 60, PRIVATE );
}
else if(command == "memory"){
Particle.publish("debug/free_memory", String(System.freeMemory()), 60, PRIVATE );
}
}
void updateWiFiInfo(){
rssi = WiFi.RSSI();
ssid = WiFi.SSID();
myLocalIp = String(WiFi.localIP());
if (Particle.connected()){
Particle.publish("particle/device/ip");
Particle.publish("particle/device/name");
}
}
void handler(const char *topic, const char *data) {
//Spark.publish("received " + String(topic) + ": " + String(data));
String header = String(topic);
header.trim();
String message = String(data);
if(header.endsWith("ip")){
myPublicIP = String(data);
}
else if(header.endsWith("name")){
serialName = String(data);
}
}