Photon spark/flash/status FAILED even though confirmed by Web IDE

My first post here and wasn’t able to find many other discussions on this. I am using my photon to take temperature readings and publish them. Also, using one of the temp readings to control a fridge compressor with a 5 minute timeout. Everything seemed to be working but after about an hour the device will stop publishing temp data to the dashboard. When I try to reflash firmware from the web IDE (and Particle Dev), it will say that it was successful. However, if I leave the dashboard running it will publish spark/flash/status failed. Like this:

I have tried to reset the photon. I have reflashed the photon using the dfu-util by flashing tinker, then running particle setup. When I flash my code again through the WebIDE, it will work for a short amount of time and then stop logging again.

Any thoughts? Code attached:


// This #include statement was automatically added by the Particle IDE.
#include "OneWire/OneWire.h"

// This #include statement was automatically added by the Particle IDE.
#include "spark-dallas-temperature/spark-dallas-temperature.h"

OneWire ds = OneWire(D0);// Connected to D0 Pin
OneWire oneWire(ds);//Setup oneWire instance

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// Addresses of the 1-Wire  sensors.
// Tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
DeviceAddress fridgeSensor1 = { 0x28, 0x3C, 0x14, 0xB6, 0x06, 0x00, 0x00, 0xA4 };//white label on sensor
DeviceAddress fridgeSensor2 = { 0x28, 0x0A, 0xBF, 0xB6, 0x06, 0x00, 0x00, 0xB8 };
DeviceAddress fridgeSensor3 = { 0x28, 0x01, 0x7D, 0x2A, 0x07, 0x00, 0x00, 0xB9 };//short cable
DeviceAddress iceboxSensor1 = { 0x28, 0x92, 0xCB, 0x1D, 0x07, 0x00, 0x00, 0x4C };

//variables
//strings for publishing temp data
char fridge1String[10];
char fridge2String[10];
char fridge3String[10];
char icebox1String[10];
char compStateString[10];
int comp  = D1;
float low_temp  = 6.0;
float high_temp = 8.0;
int restTime = 5*60*1000;
int compState = 1;//0=on timeout 1=ready

void setup(void)
{
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(fridgeSensor1, 10);
  sensors.setResolution(fridgeSensor2, 10);
  sensors.setResolution(fridgeSensor3, 10);
  sensors.setResolution(iceboxSensor1, 10);
  //initialize compressor pin as output and turn on
  pinMode(comp, OUTPUT);
  digitalWrite(comp, HIGH);
}

Timer compTimeout(restTime,compStateReset);

void compStateReset()
{
  compState=1;
  compTimeout.reset();
}


void loop(void)
{ 
  delay(15000);
  //SENSOR MEASUREMENT EXECUTION
  //telling sensors to initiate a new measurement
  sensors.requestTemperatures();
  //get temperatures in degrees C as Floats
  float fridge1=sensors.getTempC(fridgeSensor1);
  float fridge2=sensors.getTempC(fridgeSensor2);
  float fridge3=sensors.getTempC(fridgeSensor3);
  float icebox1=sensors.getTempC(iceboxSensor1);
  if ((fridge1<=-127)||(fridge2<=-127)||(fridge3<=-127)||(icebox1<=-127)){//breaks from loop if error received from either temp sensor
      return;
  }
  //DATA PUBLISHING
  //convert floats to strings
  sprintf(fridge1String,"%.2f",fridge1);
  sprintf(fridge2String,"%.2f",fridge2);
  sprintf(fridge3String,"%.2f",fridge3);
  sprintf(icebox1String,"%.2f",icebox1);
  sprintf(compStateString,"%d",digitalRead(comp));
  //publish strings to cloud (note: it looks like can only publish 4 vars)
  Spark.publish("Fridge Temperature 1",fridge1String);
  Spark.publish("Fridge Temperature 2",fridge2String);
  Spark.publish("Fridge Temperature 3",fridge3String);
 
  
  //TEMP CONTROL LOGIC
  if ((fridge1>high_temp) && (compState=1)) {//checks if it is too warm and the compressor is ready
    digitalWrite(comp, HIGH);
  }else if(fridge1<low_temp) { //checks if it is too cold
    digitalWrite(comp, LOW);
    compState=0;
    compTimeout.start();
  }
}
1 Like
void loop(void)
{
  delay(15000);
  ...
}

will make your code somewhat unresponsive for cloud affairs like OTA flashing.

Try this instead

uint32_t msDelay;
void loop(void)
{
  if (millis() - msDelay < 15000) return;
  msDelay = millis();
  ...
}

You could also try to pull your three publishes apart (e.g every 5sec) so that you definetly won’t hit the 4-pub-burst-limit in case your device temporarily disconnects/reconnects, since this will also cause extra publishes that will add to the pub-count.

2 Likes

I’m getting this exact issue as well, except whenever I flash my Photon OTA I get that message in the dashboard, straight after it coming online.

The weird thing is that the firmware flashes and runs perfectly, It just posts as a failure and I can’t see anything I’m publishing in the console (Haven’t tried with the direct link yet).

I can’t even see the variable from the simplest of code:

void setup(){}

void loop()
{
  delay(5000);
  Particle.variable("Variable", "Can't see this");
}

Flashing Tinker through the Android app also brings the same message. It seems to be an issue in the backend.

@BenDLH, Particle.variable() is declared once in setup() whereas you have it in loop().Also, you are not specifying an actual variable so I’m not sure why this compiles but I have some ideas. I believe both of these conditions may be killing the ability to do OTA.

I suggest you read the Particle.variable section of the docs and try the example. You’ll most likely see that IDE flashing and Android flashing will work as expected. :wink:

@peekay123 Hmm, that’s weird. Could’ve sworn I saw it in loop() in the code I found somewhere. I believed the variables to be cached on the server, rather than pulled straight from the device…

In any case putting the registers in setup doesn’t change the problem in any way, still showing a failure in the console despite the code flashing and running fine.

Here’s my running code:

#include "Adafruit_DHT.h"
#include "LiquidCrystal.h"

//
// Ben De La Haye
// CloudTemp-v4.ino
//
// Reads temp and humidity from DHT22 sensor and writes values to LCD panel, Particle
// server and Serial.

#define TEMP_SENSOR_PIN 0 // DHT22 Sensor
#define POT_PIN A1 // Missing potentiometer for LCD
#define SERVO_PIN A4

DHT tempSensor(TEMP_SENSOR_PIN, DHT22);
LiquidCrystal lcdPanel(7, 6, 4, 3, 2, 1);
Servo servo;

double temp;
double humidity;

void setup() {

    // Start Serial
    Serial.begin(9600);
    Serial.println("CloudTemp-v4.ino");

    // Start up the temp sensor
    tempSensor.begin();

    // Replace potentiometer for this pin to control contrast (0 - 127)
    pinMode(POT_PIN, OUTPUT);
    analogWrite(POT_PIN, 127);

    // Start up the LCD
    lcdPanel.begin(16, 2);

    // Set up the servo
    servo.attach(SERVO_PIN);

    // Setup Particle variables
    Particle.variable("temperature", temp);
    Particle.variable("humidity", humidity);
}

void loop() {

    // We cannot read from the temperature sensor more than once a second
    // and Particle has a 4 second publish burst limit
    delay(4000);

    // Read from the sensor
    temp = (double) tempSensor.getTempCelcius();
    humidity = (double) tempSensor.getHumidity();

    // Make sure we have a valid reading
    if (isnan(humidity) || isnan(temp)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    // Print values to Serial
    Serial.print("Temp: ");
    Serial.print(temp, 1);
    Serial.print("C, Humidity: ");
    Serial.print(humidity, 1);
    Serial.println("%");

    // Print temp to LCD
    lcdPanel.setCursor(0, 0);
    lcdPanel.print("Temp: ");
    lcdPanel.print(temp, 1);
    lcdPanel.print("C");

    // Print humidity to LCD
    lcdPanel.setCursor(0, 1);
    lcdPanel.print("Humidity: ");
    lcdPanel.print(humidity, 1);
    lcdPanel.print("%");
}

@BenDLH, I highly recommend using the Piettetech library for the DHT as it has proven to be very reliable and doesn’t hang like other libraries. Also, I suggest replacing your “blocking” delay(4000) with a non-blocking millis() based timer.

Note that the Particle.publish() rate is once per second with a BURST of up to 4 per second. So doing once per second is just fine and I believe the DHT22 max sampling rate is 1 per second as well (though it may be once per 2 secs). :wink:

@peekay123 Thanks, I’ll be sure look into that. Any other suggestions for the console issue?

@BenDLH, if your code is hanging, then the OTA will not work. Once you’ve addressed the DHT library and timing issues, let me know what happens to the OTA. :grinning:

Kudos to @peekay123, but @BenDLH about the not working OTA, you said

(which turns out it's not really) but seem to ignore some of the tips given to work around it

So you got @peekay123 to reply this

which is exactly the same hint as I gave in my post immediately before yours.

1 Like

So I’ve tried implementing the non-interrupting delay as suggested by @ScruffR but it doesn’t rectify the problem.

A couple of notes. I have tried reflashing tinker to the device via dfu-util and through the iOS app. In both cases, it seems to work fine, I can read and write to pins etc, but I continue to get the flash failed error in the dashboard. When working with my own code, I get the failed error and it will sometimes publish data for a short while, but eventually stops reporting with no error.

Another note. At one point i did have particle.variables declared in the loop. This was removed however before bringing the issue here.

My comment was aimed at your comment that you had problems flashing new code OTA (as I understood it), it does not address the wrong status report on dashboard as this seems to be generated by the cloud services and not by the device. So a change in the device firmware will not alter this.
But I see this happen a lot when reflashing code and I’ve learned to ignore it :wink:

Also there might be other reasons for your code hanging, but going non-blocking is a first step that should always be taken.

Hi @ScruffR, when you say "I see this happen a lot", do you mean you observe as well that the firmware flashes correctly on your photon but you see FAILED in the dashboard?

I wonder about the possibility of this issue (of seeing FAILED in the console after flashing) having anything to do with the firmware since I observed that flashing THE SAME firmware in a photon gives me the FAILED message, but if I use one of my cores it does NOT fail.
In both cases the firmware running is the correct one, so there seems to be something wrong when flashing a photon, hopefully just the reporting of the result.
I tried doing the same experiment from the BUILD web interface and from DEV (Atom running in Ubuntu) and both give the same results.

if you have any ideas what I might be doing wrong please let me know.
Gustavo.

It definetly is an issue with the reporting mechanism and most the time not your fault and you can't do anything about it.
It's the way how the device would report fail/success and how the cloud gets to know the outcome.

But maybe @Dave could give more background as this issue was discussed at Particle a while back already.

1 Like

Hi All!

Good question / good observation!

Some background: I made a change in the cloud to publish these flash failed / success events a while back, and that’s when we noticed the photon and cloud didn’t quite agree on the best way to cleanly exit an OTA. This caused the failed messages to appear. We’ve since fixed the issue, but we haven’t deployed the cloud change yet because we also noticed that the patch required a fix, since sometimes it would declare the OTA was done too early. So, now both of those are fixed, and it will be included in the next deploy of this service.

I apologize for the misleading events, but I’m glad you noticed them! They should be fixed during the next rollout.

Thanks,
David

2 Likes