Boron - RGB Led Flashing White - Fixed


#1

I am looking at - finally - making the transition from Electron to Boron. I have been working on a new carrier board (see Boron / Xenon / Argon Carrier for Outdoor Applications). And I am testing to see if the code that works well on the Electron can work on the Boron.

I was able to flash the code to the Boron which started flashing (not breathing) white. This is not one of the RGB states defined on the documentation so I am not sure what to make of it.

My code is here but it is quite long and I can’t realistically ask anyone to wade through it. What I am looking for are some clues to get me started.

  1. What does flashing white mean?
  2. In general, what code changes should I make moving at the same deviceOS@1.3.1 from Electron to Boron?
  3. I know some hardware changes are important (if it was a Xenon for example, there is no fuel gauge but this is the Boron) but, I make calls to the Power Management IC for example. Anything I need to watch out for here?

As always, any help is appreciated.

Thanks, Chip


PMIC calls now catastrophically crash Boron due to Particle software update
#2

Something that I wasn’t aware of until recently:
System Power Manager will override the application’s PMIC settings, impacting a Solar Install’s performance, see Thread


#3

Can you share a video (~30sec) of that white flashing?
Could it be a power issue which just causes the Boron to get stuck in a permanent reset cycle?


#4

@ScruffR,

Sure,here is the video. There is some interaction between the Boron and the carrier board that is not an issue with the Argon. Will go pin by pin to figure it out and report back. If I take the Boron out of the carrier board, it boots normally so this is a hardware not a software issue.

Thanks for the suggestion,

Chip


#5

Probably not causing the issue but,

Cellular.command(30000, "AT+CFUN=16\r\n");

Does not work for the Boron. 16 is not supported and you need to reset it with 15.

Cellular.command(30000, "AT+CFUN=15\r\n");

#6

@ric_hard,

Will the “16” command work for both? Trying not to have two code bases here.

Thank you!

Chip


#7

16 won’t but 15 will.
The difference with the electron is 16 it will reset including the SIM card where as 15 will reset but NOT reset the SIM card.

If you want the same code to work on both then it will have to be

Cellular.command(30000, "AT+CFUN=15\r\n");

#8

@ScruffR,

OK, narrowed it down a bit but still a bit flummoxed by this issue. By isolating the pins I connected between the Boron and the Carrier, I was able to narrow this down to the A3 pin. Here is the circuit this pin is connected to:

44%20AM

Pins are:
Reset to Reset
A3 to Done
D8 to Wake

Here is what I have tested so far:
A3 not connected, Done connected to GND or Vcc- device starts normally
A3 initialized as OUTPUT - Flashing White
A3 initialized as OUTPUT - Watchdog connection to Reset disconnected - device starts normally
A3 initialized in INTPU - device starts normally

Not sure what is going on but next step is to isolate and ensure the watchdog is working correctly - but again - this worked for the Argon.

Any more suggestions welcomed.

Chip


#9

Hey Chip, in case it helps in the future, this may be one way one can avoid having two code bases for different Particle devices:

#if PLATFORM_ID == PLATFORM_BORON
  Cellular.command(30000, "AT+CFUN=15\r\n");
#endif

#if PLATFORM_ID == PLATFORM_ELECTRON
  Cellular.command(30000, "AT+CFUN=16\r\n");
#endif

I am not sure now if it has to be PLATFORM_ELECTRON_PRODUCTION or PLATFORM_ELECTRON.

Cheers,
Gustavo.


#10

You could try pinSetFast(A3) or pinResetFast(A3) before pinMode(A3, OUTPUT) and see whether that changes anything?
It might be that the nRF behaves slightly different when transitioning from default hi-Z (INPUT) to OUTPUT.
The STM32F devices transitioned perfectly clean from hi-Z to LOW (unless preset HIGH e.g. via pinSetFast() - then it did that in a clean manner).

You could also check with an oscilloscope whether an initial pinMode(x, OUTPUT) causes a “spike” on the pin.


#11

@ScruffR,

Genius!

OK, so it turns out that you are on to something here! Your suggestion did not work until I took the next step and avoided using pinMode entirely. As long as I only use pinReset and digitalWriteFast for the donePin, this seems to work!

So, is this an issue that might be addressed in Boron firmware? Wonder why this is not an issue for the Argon?

Thanks again! Chip


#12

This might be something @rickkas7 or @oddwires1 might want to assess.
I’d think this is definetly not the intended behaviour and this kind of incompatibility on that front between Gen2 and Gen3 and even more so within Gen3 should raise eyebrows :flushed:


#13

I use the TPL5000 instead of the TPL5010, but I’ve found it necessary to add a pull-down on the DONE line. If DONE is allowed to float the TPL5000 can behave erratically in my experience.


#14

@rickkas7,

Great suggestion but I tried 4.7k and 10k pull-downs and neither would stop the white flashing.

Also, there is no mention int he TPL5010 data sheet that a pull-down on DONE is needed.

It seems that commenting out pinMode(A3, OUTPUT) and using the “Fast” commands is the only fix.

Thanks, Chip


#15

So you see the pinSetFast() and pinResetFast() work on A3 even without pinMode() being set?
This should not be the case since the default mode should be hi-Z (INPUT).
If that is not the case then this seems to go against common expectation and should be addressed in device OS IMO.


#16

@ScruffR,

Actually, I am not sure wether the watchdog works but the Boron will boot up. I am going to try to isolate the issue using a simplified sketch and circuit. I will try to get to root cause or at least make it easier for folks to look at what is happening.

Thanks,

Chip


#17

@ScruffR,

OK, I am making progress. Here is what I have done so far:

  1. Simplified the code, I wrote a sketch specifically to exercise the watchdog timer.
// Test program for Gen3 devices - watchdog for example

#include "Particle.h"

const int wakeUpPin =     D8;                       // This is the Particle Electron WKP pin
const int donePin =       A3;                       // Pin the Electron uses to "pet" the watchdog
const int blueLED =       D7;                       // This LED is on the Electron itself

volatile bool watchdogFlag;                         // Flag to let us know we need to pet the dog

void setup() {
  pinMode(wakeUpPin,INPUT);                         // This pin is active HIGH
  pinMode(blueLED, OUTPUT);                         // declare the Blue LED Pin as an output
  pinResetFast(donePin);
  pinMode(donePin,OUTPUT);                          // On the Boron, commenting out this line puts the device into endless reset cycles

  attachInterrupt(wakeUpPin, watchdogISR, RISING);  // The watchdog timer will signal us and we have to respond

  waitUntil(Particle.connected);

  Particle.publish("Startup", "Complete will publish watchdog events",PRIVATE);
}

void loop() {
  if (watchdogFlag) {
    petWatchdog();                                                  // Watchdog flag is raised - time to pet the watchdog
    if (Particle.connected()) {
      waitUntil(meterParticlePublish);
      Particle.publish("Watchdog","Received Wake Interrupt Petting Now",PRIVATE);
    }
  }  
  nonBlockingBlink(500, blueLED);

}

bool meterParticlePublish(void)
{
  static unsigned long lastPublish=0;                                   // Initialize and store value here
  if(millis() - lastPublish >= 1000) {                                  // Particle rate limits at 1 publish per second
    lastPublish = millis();
    return 1;
  }
  else return 0;
}

void petWatchdog()
{
  digitalWriteFast(donePin, HIGH);                                        // Pet the watchdog
  digitalWriteFast(donePin, LOW);
  watchdogFlag = false;
}

void watchdogISR()
{
  watchdogFlag = true;
}

// Non-blocking blink function
void nonBlockingBlink(unsigned int period, int pin) {
  static unsigned long startTimer = millis();
  static bool pinState = false;
  if (millis() - startTimer > period) {
      pinState = !pinState;
      startTimer = millis();
      digitalWrite(pin, pinState);
  }
  return;
}
  1. I pulled the Argon and Boron off the carrier board and built a simple circuit with just the watchdog and the device.

  2. I was able to get the watchdog to work as expected using this setup. So, I went back to the carrier board and discovered that the ground pour for GND and the timing resistors was floating. Fixing that solved the issue with the constant resets.

Which brings me to the present. I am going to test this for a few days but it seems that the core issue was my screwup on the PCB. Sorry to have wasted your collective time on this.

I did pick up on a code change for the Boron cellular modem so, thank you @ric_hard for that!

Chip


#18

I think you getting to the bottom of this contributed to the collective knowledge of this community, or at least to mine.
Thanks!


#19

@rickkas7 Hey Rick, can you take a look at this stream please. Thanks, Ian.