Panic, usage_fault

I cant seem to figure this one out my code has been installed on a photon and been succesfully sending data for a few weeks now… I just noticed it hasn’t updated in a couple of days and so I went out and noticed a dead battery it shouldn’t have died that fast… I slapped a new battery in and immediately my photon goes into panic mode sends a useage fault message… I figured the photon may have had something go bad and got stuck in this loop and drained the battery I tried reflashing and even slapping a spare photon I had laying about into my project instead and it does the same thing when flashed with this code… I suspect the VL53L0X.h sensor code library as this is the only project that I have with this sensor. I have the temp sensor in other projects without an issue running the same code. Also I cant figure out why the photon would run with this code just fine for several weeks and now it will not?

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


#include "VL53L0X.h"

VL53L0X sensor;


#define HIGH_ACCURACY  // for lidar high accuracy mode
// Define pins
#define ppin       D2
#define tppin      D3
#define tground    D4

// global variables
int mm = -777;
int tries = 0;

// one wire temp variables
OneWire ds = OneWire(D5);  //** 1-wire signal on pin D5
unsigned long lastUpdate = 0;
float lastTemp;

void setup()
{
  
  RGB.control(true);  // take control of the LED
  RGB.color(0, 0, 0);  // the following sets the RGB LED off:
  // pinmode
  pinMode(ppin, OUTPUT);
  pinMode(tppin, OUTPUT);
  pinMode(tground, OUTPUT);
  // turn on the sensors
  digitalWrite(ppin, HIGH);
  digitalWrite(tppin, HIGH);
  // temp sensor ground
  digitalWrite(tground, LOW);
  //  Lidar setup
  Serial.begin(9600);
  Wire.begin();
  sensor.init();
  sensor.setTimeout(500);
 
#if defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif
}

void loop()
{
  //** Temp Probe loop basically all the temperature code copy pasted from the example code from the library
  delay(1000); // delay one second to allow sensor time to boot before taking a reading this is to eliminate the 185 temp error
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
  }
  switch (addr[0]) {
    case 0x10:
      type_s = 1;
      break;
    case 0x28:
      type_s = 0;
      break;
    case 0x22:
      type_s = 0;
      break;
    case 0x26:
      type_s = 2;
      break;
    default:
      return;
  }
  ds.reset();               
  ds.select(addr);          
  ds.write(0x44, 0);        
  delay(1000);     
  present = ds.reset();
  ds.select(addr);
  ds.write(0xB8,0);         
  ds.write(0x00,0);         
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE,0);         
  if (type_s == 2) {
    ds.write(0x00,0);       
  }
  for ( i = 0; i < 9; i++) {           
    data[i] = ds.read();
    }
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s == 2) raw = (data[2] << 8) | data[1];
  byte cfg = (data[4] & 0x60);
  switch (type_s) {
    case 1:
      raw = raw << 3; 
      if (data[7] == 0x10) {
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
      celsius = (float)raw * 0.0625;
      break;
    case 0:
      
      if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
      if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
      celsius = (float)raw * 0.0625;
      break;
    case 2:
      data[1] = (data[1] >> 3) & 0x1f;
      if (data[2] > 127) {
        celsius = (float)data[2] - ((float)data[1] * .03125);
      }else{
        celsius = (float)data[2] + ((float)data[1] * .03125);
      }
  }
  if((((celsius <= 0 && celsius > -1) && lastTemp > 5)) || celsius > 125) {
      celsius = lastTemp;
  }
  fahrenheit = celsius * 1.8 + 32.0;
  lastTemp = celsius;
  String ptemp = String(fahrenheit);
 
 // LIDAR take a reading
  mm = sensor.readRangeSingleMillimeters();

 // Publish the results and shutoff sensors if you get good data
  if(mm > 75 && mm < 2000 && fahrenheit != 185)
  {
  digitalWrite(ppin, LOW);
  digitalWrite(tppin, LOW);
  Particle.publish("CurrentTemperature", ptemp, PRIVATE);
  delay (2000);
  Particle.publish("waterlevel" , String(mm), PRIVATE);
  delay (2000);
  System.sleep(SLEEP_MODE_DEEP, 14400);
  }
  else
  {
  tries++;  // track failed attempts
  }
  // if it fails to get a good level after 4 tries send an error message and sleep anyways
  if (tries == 4)
  {
  digitalWrite(ppin, LOW);
  digitalWrite(tppin, LOW);
  Particle.publish("failwaterlevel" , "true", PRIVATE);
  delay (2000);
  System.sleep(SLEEP_MODE_DEEP, 14400);
  }
}

I have tried isolating and running the temperature code only and it works just fine. I have also tried just the vl53Lox code only and it goes into panic mode. I have attached the isolated code that goes into panic mode.

// This #include statement was automatically added by the Particle IDE.
#include <VL53L0X.h>

VL53L0X sensor;


#define HIGH_ACCURACY  // for lidar high accuracy mode

// Define pins
#define ppin       D2

int mm = 666;

void setup() {
 pinMode(ppin, OUTPUT);
 digitalWrite(ppin, HIGH);
 
 Wire.begin();
 sensor.init();
 sensor.setTimeout(500);
 #if defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
 #endif
}

void loop() {
delay (1000);
mm = sensor.readRangeSingleMillimeters();
Particle.publish("waterlevel" , String(mm), PRIVATE);
 delay (9000);
}

So the only think that I noticed was that sensor.readRangeSingleMillimeters() returns a uint16_t, not an int type. That shouldn't matter since int is a 32-bit type here but you should clean it up at some point.

I would also get rid of your #define just in case your are stepping on some other macro definition. Just use D2 directly or define an int variable or const.

okay I changed it to this which is what I think you were getting at..

// This #include statement was automatically added by the Particle IDE.
#include <VL53L0X.h>

VL53L0X sensor;


#define HIGH_ACCURACY  // for lidar high accuracy mode


unsigned short mm = 666;

void setup() {
 pinMode(D2, OUTPUT);
 digitalWrite(D2, HIGH);
 
 Wire.begin();
 sensor.init();
 sensor.setTimeout(500);
 #if defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
 #endif
}

void loop() {
delay (1000);
mm = sensor.readRangeSingleMillimeters();
Particle.publish("waterlevel" , String(mm), PRIVATE);
 delay (9000);
}

However, it still goes into panic mode. I have tried the new firmware version 7.0 rc4 and it also doesn't work. I cant figure out how to go back to a previous version. Do you think this may be firmware related? Im not exactly sure when 0.6.3 became the default but maybe my device was running 0.6.2 the firmware updated then it crashed? I cant think of why the code would have worked for several weeks with no issue..

Alright thanks for the recommendations. I was able to figure out how to go back in firmware manually. Ultimately my problem wasn’t that. Problem was that I had a wire had one stray strand of copper wire that didn’t get covered in solder… gravity must have done what it does best and it slowly settled until it shorted out two pins on my sensor. I broke that bridge and now its working flawlessly.I guess that explains why it worked perfectly for a while then stopped. :slight_smile: it was so minuscule it was hard to pick out with the naked eye. It a lot looks like one wire might not have been soldered on good and could have popped loose. I didn’t think to look at the device that hard cause that error code lead me to think the code had an error.

2 Likes