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.
What does flashing white mean?
In general, what code changes should I make moving at the same deviceOS@1.3.1 from Electron to Boron?
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?
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
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.
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:
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.
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.
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?
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
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.
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.
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.
OK, I am making progress. Here is what I have done so far:
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;
}
I pulled the Argon and Boron off the carrier board and built a simple circuit with just the watchdog and the device.
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!