Spark core stops publishing after 6x

Hi,

I have some code which makes a heatmap of 16x16. The temperature sensor is connected to 2 servos which are used to move the sensor. For some reason, the spark core stops publishing after 6 publishes (every single reset it stops after 6x) whilst the code keeps running and moving the servos. What is going on here?

The code:

// This #include statement was automatically added by the Spark IDE.
#include "Adafruit_MLX90614.h"
//#include "Wire.h"

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

char publishString[40];
unsigned long tijd = 0UL;
unsigned long tijdvorig = 0UL;
double meting;

Servo servoVert;
Servo servoHori;
int posHori = 90;
int posVert = 90;


void setup() 
{ 
  mlx.begin();
  servoVert.attach(A0,650,2350);
  servoHori.attach(A1,650,2350);
  servoHori.write(posHori);
  servoVert.write(posVert);
  Serial.begin(9600);
} 

void loop() 
{
 heatmap();
}

void heatmap()
{
    tijd = millis();
    
    for(posHori = 74; posHori <= 106; posHori = posHori + 2)
  {
    for (posVert = 106; posVert >= 74; posVert = posVert - 2)
    {
      meting = temp();
      
      publish(true);
      
      
      if (tijd - tijdvorig < 2000UL)
      {
          myDelay((2000UL-(tijd-tijdvorig)));
      }
      
      tijdvorig = tijd;
      
      
      
      servoVert.write(posVert);
      myDelay(200);
      Serial.println(posVert);
    } 
    servoHori.write(posHori);
    myDelay(100);
    Serial.println(posHori);
  }
}

void myDelay(unsigned long duration)
{
    unsigned long start = millis();
    while (millis() - start <= duration)
    {
        
    }
}

void publish(bool doen)
{
    if (doen == true)
    {
      sprintf(publishString,"{\"Temp\": %f}",meting);
      Spark.publish("BSM2",publishString);
      Serial.print("Published!"); Serial.println(meting);
    }
    
}

double temp()
{
    double groot = mlx.readObjectTempC();
    
    return groot;
}
1 Like

@TheHawk1337, one thing which might not be the cure, but I’d avoid the blocking delay you are using. Since you are dealing with longs you might block too long.
If you need really long delays you could wrap a non-blocking delay() in a loop.

    void myDelay(unsigned long duration)
    {
        unsigned long start = millis();
        while (millis() - start &lt;= duration)
        {
    
        }
    }

Your function heatmap() seems to run - worst case - for up to 600sec which is way beyond the limit to keep the cloud connection alive. Which is - I believe - 10sec and so would fit your 6 successful publishes (1 initial plus 5x 2sec per sebsequent call).

Try changing this and see if the problem persists :wink:

What exactly do you mean by ‘way beyond the limit to keep the cloud connection alive.’? The publishes are made in the heatmap() function ( by using the publish(true) function) so the cloud keeps getting data. Or did I misunderstand you?

I edited above.

I believe the limit is 10sec and I also believe that publish() as such is not actually doing any keeping-alive action but only the publishing work. The rest is part of other functions.
I’m not up to date with the internals of the most recent Core firmware, but it used to be necessary to ‘leave’ loop atleast once every 10sec to do the cloud house-keeping (which some functions like delay() do implicitly).

As I understand your code, I don’t see any reason why you need to write your own delay, since you are not going beyond 60sec which should be fine with standard delay().
Just try delay() in place of myDelay() and see if it works.

This code is part of a much larger code. This is for a school project where we are building a bedside monitor (heartrate, blood pressure and temperature) which also has a camera and other stuff which needs to be controlled, hence the reason not to use delay().

I see, so you could rewrite your myDelay() to brake down your long delay into chunks of max. 60sec and employ delay() inside your loop.
But for the 6x-problem just give delay() a shot!

If you are doing this as a school project, I might also have some coding style hints - if you like.

1 Like

A simple way would be call the Spark loop in your delay:

void myDelay(unsigned long duration)
    {
        unsigned long start = millis();
        while (millis() - start <= duration)
        {
          SPARK_WLAN_Loop();
        }
    }
4 Likes

@bko - That’s a good candidate for @kennethlimcp’s Spark Snippets :slight_smile:

3 Likes

@ScruffR All tips/help is welcome :smile:

@bko Thanks! I will test that right now. Edit: works great, thanks!

@dougal, thanks for the ping :slight_smile:

I have added it in! Feel free to send PRs :wink:

3 Likes