Code Locking up

Hi,

I am having issues with my spark core becoming responsive.

when trying to access the API I get a time out.

{
  "error": "Timed out."
}

The project here is pretty simple, I am using a dht11 temperature and humidity sensor, with the values being stored in a char array in JSON format.
There are also two PIR sensors connected to interrupt pins for detecting weather the room is empty and calling a PHP script on a remote server when there is change in state.

I suspect that is the client connection section of the code that is causing the freezes.

Has anyone had any problems with similar issues ?

Thanks,
Mark.

Here is the code running on the spark core:

/*
Using Parallax PIR sensor 
*/
/// Motion Related Variables. 
//both these vars are set to volatile because they will be changed when there is an interupt  
volatile boolean motion = false; 
volatile uint32_t lastmotiontime = 0; 
uint32_t interval  = 900000; //15min 
boolean currentMotion = true; //variable that is going to be available through the spark api a nonvolatile var is required
//char server[] = "torrentslave.local";
IPAddress serverIP(192,168,1,99);
TCPClient client;

// Temperature and humidity variables
int dht = D0;
int rh = 0;
int temp = 0;
char resultstr[64];
    
void setup(){
    RGB.control(true);
    Spark.variable("motion", &currentMotion , BOOLEAN);
    Spark.variable("result", &resultstr, STRING); 
    pinMode(dht, INPUT_PULLUP); // enable ping D0 as input with internal pullup resistor enabled.

    unsigned long Ltime = millis(); //wait 30 sec for the PIR to calibrate itself. 
    while(Ltime < 30000){
        RGB.color(255, 0, 0);
        delay(750);
        RGB.color(0,0,0);
        delay(250);
        Ltime = millis(); 
    }
    //attaching interrupt pins for both my motion sensors. 
    attachInterrupt(A0, motionInterupt, RISING);
    attachInterrupt(A1, motionInterupt, RISING);
}

void loop(){
  noInterrupts();
  unsigned long currentMillis = millis();
  //catch for when millis() overflowing 
  if (currentMillis < lastmotiontime){ 
    lastmotiontime = 0 ; 
  } 

  //reseting motion variable if no motion has been detected in a while 
  if (motion && (currentMillis - lastmotiontime   > interval)){
    motion = false; 
  }
  
  //call server script when there is a change to room being empty. 
  if (currentMotion != motion){
      //allow us to react to change run the testNatLight script on remote web server. 
    if(client.connect(serverIP, 80)){
    client.println("GET /phpHue/testNatLight.php HTTP/1.0");
    client.println();
    client.flush();
    delay(50); //wait for caches to clear. 
    client.stop();
    }
  }
  
    currentMotion = motion;  //store the current state in a non volatile variable - for access from spark.variable 
    rh = read_dht(dht, &temp);
    // format your data as JSON, don't forget to escape the double quotes
    sprintf(resultstr, "{\"Temperature\":%d,\"Humidity\":%d,\"Presence\":%d}", temp, rh, motion); 
    
  interrupts();
  
  delay(500); 
}

void motionInterupt(){
  motion=true;  
  lastmotiontime = millis(); 
  RGB.color(0, 0, 50);
}


int read_dht(int pin, int *temperature)
{
    uint8_t data[5] = {0, 0, 0, 0, 0};

    noInterrupts();
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
    delay(20);
    pinMode(pin, INPUT_PULLUP);
    while (digitalRead(pin) == HIGH) {
        delayMicroseconds(10);
    }
    while (digitalRead(pin) == LOW) {
        delayMicroseconds(10);
    }
    while (digitalRead(pin) == HIGH) {
        delayMicroseconds(10);
    }
    for (uint8_t i = 0; i < 40; i++) {
        uint8_t counter = 0;
        while (digitalRead(pin) == LOW) {
            delayMicroseconds(10);
        }
        while (digitalRead(pin) == HIGH) {
            delayMicroseconds(10);
            counter++;
        }

        data[i/8] <<= 1;
        if (counter > 4) {
            data[i/8] |= 1;
        }
    }
    interrupts();

    if (data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
        *temperature = -254;
        return -1;
    }

    *temperature = data[2];
    return data[0];
}

Hi @markp1989,

Ooh, good question! Since your code doesn’t run in a sandbox on the Core it’s possible to block and prevent the Core from maintaining its connection to the Cloud.

There are a few ways your code can yield and let the core maintain the connection.

  • Delay where the delay is >= 1000ms.

    • The firmware will take the opportunity to check the connection during long delays.
  • Call SPARK_WLAN_Loop() manually

  • This is the function that pings the server, and makes sure it’s handling function calls and such.

  • Or try not to block for longer than 10 seconds in your setup / loop functions.

Thanks!
David

2 Likes

@Dave Thanks for the reply some quality information there!

I have added a call to the SPARK_WLAN_Loop() within the block of code that connects to the remote server.

Since last night there have been no lockups but I will leave it for a couple of day to verify.

The PHP script on the server can take a few seconds to run so it looks like this was causing the lockups. I will have a crack at streamlining the PHP script in order to speed up execution once all the uni stuff has finished for the summer.

Thanks, :slight_smile:

1 Like

Awesome! Glad that helped :slight_smile: Good luck with the uni(-versity?) stuff!

Thanks,
David

1 Like

Hi, I believe I have a similar issue where my core will work fine for 12hrs then it appears to lockup. It may be when I call functions from my webpage.
Is it recommended to insert a delay in the loop?
Also, how do I implement the Spark_WLan_loop()? What do you mean by do not block longer than 10s?

Thanks allot!!
Dup

Hi @Dup,

Ideally your loop function should end normally about every 5-15 seconds, and give the background tasks a chance to run. We also now run the background tasks during long delay calls (longer than 1 second, I think), so that works too. It’s possible the cc3000 patch will fix your issue, or if you wanted to share your code we could try and look for any issues that might be hiding. :smile:

Thanks,
David

1 Like

Thanks Dave!
It seems to be back live. I will keep an eye on it. It might have been the wrong web page version I was using :slight_smile:

Is the patch part of the web IDE May build?

Thanks!

Hi @Dup,

Awesome, glad it’s working again! We’ll be shipping the patcher as an opt-in separate step of re-flashing your core, since it requires a driver payload for the cc3000. We’ll post when it’s released, and you’ll see a big notification when you log into the build IDE the first time. :smile:

Thanks,
David

1 Like