Boron Flashes red 10 times

So I’ve been testing code on my Boron for the last few days. Last night I set it out to run and I wakeup this morning and it’s flashing red. sos 10X flash. I tried flashing new code but its unsuccessful. Any ideas why?

Ten total times flash before repeating? You should read the docs on SOS codes.

I did… are the numbers the # of blinks? Or are they just a list of possible errors?

These are the numbers of slow blinks between the SOS flashes (… - - - …)

If it’s in fact an SOS+1 (… - - - … —) then I’d first suspect a missing return statement in a Particle.function()

But to be sure we need to see your code.

Here’s the code.
It’s a lot of piecing things together from question I’ve asked, so I’m sure there’s probably some interference somewhere.

I’m using it for 2 purposes. I have a solar charger charging the system so I have 2 current sensors (1 for boron battery and other for LED battery) monitoring the battery voltage and sending details to me every 30 minutes.

I also have the system turning on a series of leds via pinSwitch. The “sig” (signal) led is linked directly to the boron. And the main leds are connect to a latching relay( which is why I have 2 pins “led” & “ledoff”). There is also an event publish for me to track when the leds have been turned on.

The numerous // are there for me to more easily switch one and off new code while testing. //battery code & //end battery code are there to bracket the addition of my current sensor code that’s been added to the existing ledSwitch code


// This #include statement was automatically added by the Particle IDE.
#include <adafruit-ina219.h>  // Call the current sensor library
//Adafruit_INA219 ina219;
//Adafruit_INA219 ina219_0x40 = Adafruit_INA219();
//Adafruit_INA219 ina219_0x41 = Adafruit_INA219();

int led = D2; 
int ledoff = D3;              
//int sig = D4;
//int  = D5;               // Signal LED
//int  = D6;               
int sig = D7;           // OnBoardLED (obd)
//int  = D8; 
//char voltageStr40[30];        // New String for voltage
//char voltageStr41[30];        // New String for voltage


// start battery code
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

// Settings
const int VOLTAGE_LEN = 30;
const size_t SENSOR_COUNT = 2;

// Addresses of sensors
const size_t SENSOR_ADDRS[SENSOR_COUNT] = {0x40, 0x41};

// Sensor array
Adafruit_INA219* sensors[SENSOR_COUNT];

// Data gathered from sensors
struct INA219Data {
  float shuntVoltage;
  float busVoltage;
  float loadVoltage;
  char voltageStr[VOLTAGE_LEN];
} readings[SENSOR_COUNT];

// Forward declarations
const char* voltageStr40();
const char* voltageStr41();
void takeReadings();
// end battery code

void setup(void) {

    uint32_t currentFrequency;
    Adafruit_INA219 ina219_0x40 = Adafruit_INA219();
    Adafruit_INA219 ina219_0x41 = Adafruit_INA219();
    Serial.begin(115200);
    pinMode(led, OUTPUT);       
    pinMode(ledoff, OUTPUT);      
    pinMode(sig, OUTPUT);      
    Particle.function("switch", pinSwitch);         // Register a cloud function named "switch"

    Particle.variable("voltageStr40", voltageStr40);
    Particle.variable("voltageStr41", voltageStr41);
    //ina219.begin();             
    ina219_0x40.begin();
    ina219_0x41.begin();
    
    
      // start battery code
      for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    sensors[i] = new Adafruit_INA219(SENSOR_ADDRS[i]);
    sensors[i]->begin();
  }

  // Connect to Particle cloud
  Particle.connect();
  // end battery code
   
}
void loop(void) 
{
      
    // start battery code
    // Update readings
  takeReadings();

  // Print readings to serial
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    Serial.printlnf("D%X-Voltage: %s", SENSOR_ADDRS[i], readings[i].voltageStr);
   }
 // Publish
  char payload[30];
  snprintf(payload, sizeof(payload), "%s and %s", readings[0].voltageStr, readings[1].voltageStr);
 delay(1000);
 Particle.publish("loadMe", payload);
 delay(1800000);
// end battery code
//  float shuntvoltage40 = 0;
//  float busvoltage40 = 0;
//  float current_mA40 = 0;
// float loadvoltage40 = 0;
//  char voltageStr40[30];  
  
//  float shuntvoltage41 = 0;
//  float busvoltage41 = 0;
//  float current_mA41 = 0;
//  float loadvoltage41 = 0;
//  char voltageStr41[30];  

//  shuntvoltage40 = ina219_0x40.getShuntVoltage_mV();
//  busvoltage40 = ina219_0x40.getBusVoltage_V();
//  current_mA40 = ina219_0x40.getCurrent_mA();
//  loadvoltage40 =((busvoltage40 + (shuntvoltage40 / 1000))*(3.3/1.32));
  
//  shuntvoltage41 = ina219_0x41.getShuntVoltage_mV();
//  busvoltage41 = ina219_0x41.getBusVoltage_V();
//  current_mA41 = ina219_0x41.getCurrent_mA();
//  loadvoltage41 =((busvoltage41 + (shuntvoltage41 / 1000))*(3.3/1.32));
  
//    sprintf(voltageStr40, "%f", loadvoltage40);         // Convert loadvoltage (float) to a string voltageStr using function("%f")
//    sprintf(voltageStr41, "%f", loadvoltage41);         // Convert loadvoltage (float) to a string voltageStr using function("%f")

// Particle.publish("loadMe",voltageStr40);          // Publish voltageStr with publish event name "loadMe"
//    Serial.println("D40-Voltage: ");Serial.print(voltageStr40);
//   delay(1000);
//   Serial.println("D41-Voltage: ");Serial.print(voltageStr41);
//   delay(1000);
}
 

// start battery code
// Voltage of first sensor
const char* voltageStr40() {
  return readings[0].voltageStr;
}
// Voltage of second sensor
const char* voltageStr41() {
  return readings[1].voltageStr;
}
// Populate reading data
void takeReadings() {
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    INA219Data* reading = &readings[i];
    float shunt = sensors[i]->getShuntVoltage_mV();
    float bus = sensors[i]->getBusVoltage_V();
    reading->loadVoltage = ((bus + (shunt / 1000))*(3.3/1.32));
    reading->shuntVoltage = shunt;
    reading->busVoltage = bus;
    snprintf(reading->voltageStr, VOLTAGE_LEN, "%f", reading->loadVoltage);
  }
}
// end battery code


int pinSwitch(String state) {
   
//    float loadvoltage40 = 0;      /// Designate as float
//    char voltageStr40[30];        /// Designate as string
//    float shuntvoltage40 = 0;     /// Designate as float
//    float busvoltage40 = 0;         /// Designate as float
//    float current_mA40 = 0;         /// Designate as float
   
//    shuntvoltage40 = ina219_0x40.getShuntVoltage_mV();       // Define 
//    busvoltage40 = ina219_0x40.getBusVoltage_V();           
//    current_mA40 = ina219_0x40.getCurrent_mA();             
//    loadvoltage40 =((busvoltage40 + (shuntvoltage40 / 1000))*(3.3/1.32));   
    
//    sprintf(voltageStr40, "%f", loadvoltage40);         // Convert loadvoltage (float) to a string voltageStr using function("%f")
//    Particle.publish("loadMe",voltageStr40);          // Publish voltageStr with publish event name "loadMe"
//    Serial.println("40Voltage: ");Serial.print(voltageStr40);
//    delay(1000);
    
    if ( state == "on" ) {          // Set pin state based on given parameters
        
        Serial.println("TURND ONNN ");
        digitalWrite(sig, HIGH);        /// Signal flash on 5 time
        delay(500);
        digitalWrite(sig, LOW);
        delay(500);
        digitalWrite(sig, HIGH);        /// Signal flash on 5 time
        delay(500);
        digitalWrite(sig, LOW);
        delay(500);        
     
        digitalWrite(led, HIGH);
        digitalWrite(ledoff,LOW);   /// Signal flash on 5 time
        delay(30000);
        digitalWrite(led, LOW);
        digitalWrite(ledoff,HIGH); 
        delay(200);
        
        digitalWrite(sig, HIGH);        /// Signal flash on 5 time
        delay(500);
        digitalWrite(sig, LOW);
        delay(500);
        digitalWrite(sig, HIGH);        /// Signal flash on 5 time
        delay(500);
        digitalWrite(sig, LOW);
        delay(500);  
        
        Particle.publish("playtime","He Turned Me On",PRIVATE); 
       
    } else if ( state == "off" ) {
        digitalWrite(sig, LOW);
    } else {
        return -1;
    }
    
    return 0;
}

Not sure why you use size_t as type here. It should rather be uint8_t.
You may also want to make your pin variables const int so that they don't take up RAM space.

You are declaring this

But then use some intermediate ina219_0x40 and ina219_0x40 where it would be better to use the sensors[] fields directly.
Doing it your way means you are creating two instances per sensor resulting in four objects where you only have two sensors.

You also use a lot of excessively long delay() calls I'd do away with.


This could be a "streamlined" version of your code where I wouldn't see a reason for an SOS panic crash

#include <adafruit-ina219.h>

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

const int      LED_ON         = D2; 
const int      LED_OFF        = D3;              
const int      LED_SIG        = D7;           			// OnBoardLED (obd)
const int      LEN_VOLT       = 12;
const uint32_t LOOP_DELAY     = 1800000;
const uint8_t  SENSOR_ADDRS[] = { 0x40, 0x41 };
const size_t   SENSOR_COUNT   = sizeof(SENSOR_ADDRS) / sizeof(SENSOR_ADDRS[0]);

struct INA219Data {										// Data gathered from sensors
  float shuntVoltage;
  float busVoltage;
  float loadVoltage;
  char voltageStr[LEN_VOLT];
} readings[SENSOR_COUNT];

Adafruit_INA219* sensors[SENSOR_COUNT];

// Forward declarations
int  pinSwitch(const char*);
void takeReadings();
void blink();

int   blinkStep = 0;
Timer timerBlink(500, blink);

void setup(void) {
  Serial.begin(115200);
  pinMode(LED_ON , OUTPUT);       
  pinMode(LED_OFF, OUTPUT);      
  pinMode(LED_SIG, OUTPUT);      

  Particle.variable("voltageStr40", readings[0].voltageStr);
  Particle.variable("voltageStr41", readings[1].voltageStr);
  Particle.function("switch", pinSwitch);         		// Register a cloud function named "switch"

  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    sensors[i] = new Adafruit_INA219(SENSOR_ADDRS[i]);
    sensors[i]->begin();
  }
  Particle.connect();
}

void loop(void) {
  static uint32_t msDelay = 0;
  if (millis() - msDelay < LOOP_DELAY) return;			// non-blocking delay - while not due for next action, bail out
  msDelay = millis();
  
  takeReadings();    									// Update readings
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {			// Print readings to serial
    Serial.printlnf("D%02X-Voltage: %s", SENSOR_ADDRS[i], readings[i].voltageStr);
  }

  char payload[30];
  snprintf(payload, sizeof(payload), "%s and %s", readings[0].voltageStr, readings[1].voltageStr);
  Particle.publish("loadMe", payload);
}
 
void takeReadings() {									// Populate reading data
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    float shunt = sensors[i]->getShuntVoltage_mV();
    float bus   = sensors[i]->getBusVoltage_V();
    readings[i].loadVoltage  = 3.3 * (1000 * bus + shunt) / 1320.0;
    readings[i].shuntVoltage = shunt;
    readings[i].busVoltage   = bus;
    snprintf(readings[i].voltageStr, LEN_VOLT, "%.3f", readings[i].loadVoltage);
  }
}

int pinSwitch(const char* state) {
  int retVal = -1;
  if (!strcmp(state, "on")) {							// Set pin state based on given parameters      
    retVal = 1;
    Serial.println("TURND ONNN "); 
    blinkStep = 0;	
    timerBlink.start();
    Particle.publish("playtime", "He Turned Me On"); 
  } 
  else if (!strcmp(state, "off")) {
    retVal = 0;
    digitalWrite(LED_SIG, LOW);
  } 
  
  return retVal;
}

void blink() {											// FSM for blink pattern 500ms per step
  switch(blinkStep++) {
    case  0:
    case  2:
    case 66:
    case 68:
      digitalWrite(LED_SIG, HIGH);       
      break;

    case  1:
    case  3:
    case 67:
    case 69:
      digitalWrite(LED_SIG, LOW);
      break;

    case  4:
      digitalWrite(LED_ON , HIGH);
      digitalWrite(LED_OFF, LOW);   
      break;

    case 5 ... 64:                                      // 30 seconds do nothing
      break;
      
    case 65:
      digitalWrite(LED_ON , LOW);
      digitalWrite(LED_OFF, HIGH);
      break;

    case 70:
      blinkStep = 0;
      timerBlink.stop();
      break;
	  
    default:
      break;
  }
}
3 Likes

Are you driving these relays directly from a GPIO pin or through a driving transistor?

Directly from the pin, but as soon as I get everything working I’ll be flashing the signal for (200) to latch instead of constantly holding it on.

@LADD, is the relay on a breakout board? If you are really driving the relay coil directly, you will most likely damage your processor to due something called "flyback". Look here:

@peekay123 Im using one on a breakout board from adafruit.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.