Temperature sensor reading fails every other time

I am trying to understand why is my waterproof temperature sensor (the one from the Photon Maker Kit) fail to read every second time. I have a simple code with a while loop in which I read from temp sensor every ~1 minute and publish the result. The loop exits after 15 iterations. Looking at the Photon events console I see that every other temp reading failed (attached screenshot). What am I doing wrong ?

LEDStatus blinkRed(RGB_COLOR_RED, LED_PATTERN_BLINK, LED_SPEED_NORMAL, LED_PRIORITY_IMPORTANT);
DS18 tempSensor(D4);
double temperature;
int n;

void loop(void) {
  n = 0;
  while(true) 
  {
    n += 1;
    if (tempSensor.read()) 
    {
      blinkRed.setActive(true);
      temperature = tempSensor.celsius();
      Particle.publish("temp", String(temperature, 1), 3600, PRIVATE);
      blinkRed.setActive(false);
    }
    Particle.publish("n", String(n), 3600, PRIVATE);
    delay(1000);
    if(n == 15)
      break;
    else
      delay(59000);
  }
  // rest of the code (send to MQTT, etc.)
}

Typically you would not have an infinite loop inside loop().
There are certain tasks that want to be happening between iterations of loop().

Long delay() calls will also impact the devices cloud responsiveness to the negative.

2 Likes

Hi @ScruffR , thanks for your reply. I am aware of the code is rubbish, but I am still working out what I actually want (how often to send data, whether to average samples, etc.). It’s not an infinite loop. I mean, yes it’s not ideal but while true exits after 15 iterations.

Anyway. Are you suggesting that the most likely culprit is delay(59000); ? But then why would every other publish was affected ? It’s very persistent. I will re-write the code, but I’d like to understand why is it behaving in such way with the code I’ve got. Thanks!

I’ve rewritten the code to use timers, and the issue is (unsurprisingly) gone. Next step: build event-based queue.

#include "DS18.h"

DS18 tempSensor(D4);
double temperature;
bool publish_temperature = false;

void timer_callback_temperature_check();

Timer temperatureTimer(5 * 60 * 1000, timer_callback_temperature_check);

void timer_callback_temperature_check() {
    publish_temperature = true;
}

void setup() {
  Particle.variable("tempC", temperature);
  temperatureTimer.start();
}

void loop() {
    if (publish_temperature)
    {
      if (tempSensor.read())
        temperature = tempSensor.celsius();
      Particle.publish("temp", String(temperature, 1), 3600, PRIVATE);
      publish_temperature = false;
    }
}
1 Like