Why Spark seems to reset itself?

Does anyone know why my code could be reseting itself after several cycles of the reed switch? Seems like it’ll make it 5+ times through, others might reset after one try. I’d like to figure out how to make this more stable. And FYI, I’m a newbie, so everything is pretty new to me. Just started on Arduino and came across the Spark.

const char * DEVID1 = "XYZ"; // Secret Code from Pushing box within ""

int pinDevid1 = D1;  // Reed Switch connected between D1 and GND
int val = 0;
int LED = D7; //Initialize LED

// Debug mode
boolean DEBUG = TRUE;

const char * serverName = "api.pushingbox.com";   // PushingBox API URL
boolean pinDevid1State = false;             // Save the last state of the Pin for DEVID1
TCPClient client;

void setup() {
    Serial.begin(9600);                     // Start the USB Serial
    
    pinMode(LED, OUTPUT);      // sets the digital pin as output for LED indication
    pinMode(pinDevid1, INPUT_PULLUP); //Pin for door magnetic sensor
    digitalWrite(LED, LOW); //turn off LED for reset

    delay(1000);

    // Prints out the network parameters over Serial
    if(DEBUG){
        Serial.print("SSID: ");
        Serial.println(WiFi.SSID());
        Serial.print("Core IP: ");
        Serial.println(WiFi.localIP());    
        Serial.print("Gateway: ");
        Serial.println(WiFi.gatewayIP());
        Serial.print("Mask: ");
        Serial.println(WiFi.subnetMask());
        Serial.print("WiFi RSSI: ");
        Serial.println(WiFi.RSSI());
    }
}

void loop() {

        val = digitalRead(pinDevid1);
        if (val == HIGH && pinDevid1State == false) // switch on pinDevid1 is ON
    {
           if(DEBUG){Serial.println("Door is Open!");}
        pinDevid1State = true;
        // Sending request to PushingBox when the pin is HIGH
        sendToPushingBox(DEVID1);
    }
    val = digitalRead(pinDevid1);
       if (val == LOW && pinDevid1State == true) // switch on pinDevid1 is OFF
    {
        if(DEBUG){Serial.println("Door is Closed!");}
        pinDevid1State = false;
        // Sending request to PushingBox when the pin is LOW
        
    }
    
}

void sendToPushingBox(const char * devid)
{
    digitalWrite(LED, HIGH);          // sets the LED on
    Serial.print("closing... ");
    client.stop();
    if(DEBUG){Serial.print("connecting... ");}
    if (client.connect(serverName, 80)) {
        delay(250);
        if(DEBUG){Serial.println("connected");}
        client.print("GET /pushingbox?devid=");
        client.print(devid);
        client.println(" HTTP/1.1");
        client.print("Host: ");
        client.println(serverName);
        client.println("User-Agent: Spark");
        //client.println("Connection: close");
        client.println();
        delay(250);
        client.flush();
        if(DEBUG){
            Serial.print("sent! - RSSI:");
            Serial.println(WiFi.RSSI());
            Serial.println("");
        }
        digitalWrite(LED, LOW);           // sets the LED off
        delay(250);
    } 
    else{
        digitalWrite(LED, HIGH);          // sets the LED on. If always on, last connexion was failed
        if(DEBUG){Serial.println("connection failed");}
    }
}

You have a lot of serial debugging messages in your code–what does it print out just before it dies? That might give a clue.

I no longer like to rely on client.flush() to clear out returned bytes from the server you are not interested in–I like to use two while loops with a timeout now.

You can help us read your post by formatting code in the forum like this:

 ```cpp
 <code here>
2 Likes

oopps..I just jumped in and made that edit. Next time I'll look before leaping! Teach a person to fish... etc.. :slight_smile:

Hopefully this tidbit of info helps. So within the Serial Window:
"Door is Closed!
Door is Open!
closing… connecting… connected
sent! - RSSI:-58

Door is Closed! "
(This is where is freezes up and status LED goes from breathing blue to a quick flashing blue, the quick flashing green then back to breathing blue)

Thanks for the pointer on inserting the code in the forum. Sorry about that.

A couple of things catch my eye,

switch bounce, in the original code for pushingbox there was a 50ms delay and read the input again, if its still in the same state then the code executes. Its a pretty crude debounce but it works.

Also try changing the client.flush(); in your code posted above with this snippet of code below. It waits for the servers response (with a 3 second timeout) then prints the response if debug is enabled or just throws it away. What can happen and i think could cause the issue you see is the response comes in after the 250ms delay in your code, then your code continues but your buffer is already partially full.

unsigned long lastTime = millis();
while( client.available()==0 && millis()-lastTime<3000) { //3 second timeout
}  //do nothing
lastTime = millis();
while( client.available() && millis()-lastTime<3000 ) {  //3 second timeout
if (DEBUG) Serial.print(client.read());  //print data
else client.read();  //flush data
}
client.flush();  //for safety
delay(200);
client.stop();
2 Likes

Hey @MMike When I was rewriting the Phant library I ran into problems with client.print() I found strange behavior where after a few iterations my app stopped sending data and appeared to hang. I noticed when looking at the TCP stream from the other end I was receiving the first two client.prints but it would hang on the third. What’s strange is that it would work successfully for a while and then have this problem. I found that putting two empty client.print(""); statements at the beginning of my send appeared to clear the problem. I have no idea why it worked.

So you can give that a try.

if(DEBUG){Serial.print("connecting... ");}
if (client.connect(serverName, 80)) {
    delay(250);
    if(DEBUG){Serial.println("connected");}
    client.print("");    // try this
    client.print("");    // try this
    client.print("GET /pushingbox?devid=");
    client.print(devid);
    client.println(" HTTP/1.1");

I have subsequently stopped using client.print(); and now use client.write();. I also recommend minimizing your calls to client.print or client.write. Send as much as you can in one call. Finally as @bko & @Hootie81 pointed out, don’t rely on client.flush(); it’s better to just use client.read(); until there is no more data.

2 Likes

@bko & @Hootie81, the use of two while statements made it so it doesn’t crash now. Much more stable. Every 30 or 40 times it won’t connect (where it times out), but it doesn’t reboot like it once did. Thanks to everyone for your input!
Cheers,
Mike

1 Like

@MMike, I made a slight change to the second while loop following a load of testing with large files. It might not make a huge difference for the tiny bit that comes back from pushing box, but shouldn’t make too much difference to the overall execution time. it resets the timeout if there was data.

unsigned long lastTime = millis();
while( client.available()==0 && millis()-lastTime<3000) { //3 second timeout
}  //do nothing
lastTime = millis();
while( client.available() && millis()-lastTime<3000 ) {  //3 second timeout
if (client.available()) {
if (DEBUG) Serial.print(client.read());  //print data
else client.read();  //flush data
lastTime = millis();  //reset the timeout only if there was data 
} else delay(10);  //slow it down a tad, we are waiting anyway
}
client.flush();  //for safety
delay(200);
client.stop();