After uploading apparently bad firmware to a Photon, it appears to go into some broken state that I don’t see documented in the reference manual. It appears with a solid cyan (or white, can’t really tell) LED. I can recoup the Photon by performing a manual DFU update to the original firmware, but that is getting realllly tiresome while trying to develop new firmware. Also of note, there doesn’t appear to be anything wrong with the firmware according to the complier…it gives me the all-clear.
Is there another way around this? I’m afraid of sticking thousands of Photons/Electrons out and then having to manually fix every one of them if something goes wrong…
@hagandh, you can also recover a Photon by putting it in safe mode and then OTA new firmware to it.
Having a successful compilation does not guarantee your code will actually work correctly! Adding debugging Serial.print() lines and posting your code would allow us to help you a bit more.
Ahh okay. Doesn’t safe mode have to be entered by pushing buttons though?
As for the code, the reason I’m having issues is because my C++ skills are roughly 500 times less than my python skills…
Mostly, using global variables in a way that I think should work, apparently doesn’t. i.e:
// Set up an instance of the OPCN2 class at CS
OPCN2 alpha(CS);
IntervalTimer runTimer;
int SAMPLE_FREQ = 10000 * 2;
// Set up an empty structure
PMData pm;
void setup(){
Serial.begin(9600);
while (alpha.on() != true){
alpha.on();
delay(1000);
}
if (alpha.firmware_version).toInt() >= 18){
runTimer.begin(run_new_firmware, SAMPLE_FREQ, hmSec);
}
}
void run_new_firmware(){
pm = alpha.read_pm_data();
}
void loop(){
}
That’s the basic gist of the program…trying to use a timer to take 0.1 Hz measurements of a sensor…works great if the measurements are done in loop, but breaks if in the timing function. Ideas? I know it’s a simple c++ thing, but my googling skills have let me down.
@hagandh, can you point to code for the “OPCN2” class definition. Also, I believe you are using the (Arduino) IntervalTimer class which requires a call in loop() to refresh and operate correctly. You could possibly be using a Software Timer instead, depending on what alpah.read_pm_data() is doing. Can you post more of your code so I can look at your #include statements and the referred libraries?
Oh, and yes, safe mode requires that you push buttons.
Also, I’d consider using SYSTEM_THREAD(ENABLED). In the default system threading mode (disabled), anything in your code or libraries that you use that prevents the Particle cloud from being serviced will cause problems. The status LED will stop breathing cyan, cloud functions and variables will stop working, and over-the-air (OTA) firmware updates will fail. By enabling system thread mode, there’s less of a chance of interrupting cloud servicing, which makes it more likely you’ll be able to remotely flash new code. https://docs.particle.io/reference/firmware/photon/#system-thread
@hagandh, you are using SparkIntervalTimer to create you timed events I see. However, this library requires callback functions which are simple and quick since they are interrupt service routines. In your code, you call Particle.publish() ans Serial.print() which are not recommended for use in an ISR.
I suggest you consider using a non-blocking timer in loop() instead, which can then call the appropriate code without the constraints of an ISR. I would look like this:
//globals
// Set up the sampling frequency in ms
int SAMPLE_FREQ = 10000;
unsigned long runTimer;
setup() {
... other code
runTimer = millis() + SAMPLE_FREQ;
}
loop() {
if (millis() >= runTimer) {
// timer is up, run your sampling code here
run_new_firmware();
runTimer = millis() + SAMPLE_FREQ; // reset timer
}
... other loop code
}
Adding the code @rickkas7 recommended is also a great idea!
Awesome. Thanks for the recommendations. Do you know of another library that would work like this? I used to use the SimpleTimer library on an Arduino that worked great. Otherwise, I could of course roll out my own solution…
@hagandh, I thought someone had ported the SimpleTimer library but it isn’t on the web IDE. I have another timer library you could use here. I’ll look at porting the SimpleTimer library later today.
Hey @peekay123 I was going to try to use the SimpleTimer library for the Photon. Since it has been a while since your last post, I wonder if there is something better more up to date for the Photon? Thanks for all your hard work and encouragement!!
@squeakywheel, you now have a choice of Software Timers (which use FreeRTOS timers), millis() timers (which is what SimpleTimer uses) or the SparkIntervalTimer library which uses hardware timers to generate timed interrupts.
Choices! I really just want to use something that will work out of the box with the least amount of configuration. Ideally, I could call it with a single line of code similar to timer.setInterval(100L, checkPhysicalButton);
What is your recommendation for something like that?
You may be better served by:
a) Use a millis() timer in loop() which runs the sampling code every 200ms, or
b) Use SimpleTimer which is essentially a millis() timer with a callback, or
c) Use an interrupt to read/debounce your button and set a flag to read in loop() and do the Blynk stuff which shouldn’t go in the interrupt service routine.
@squeakywheel, SoftwareTimers may not be the best thing to use for the code you’ve posted above.
Since they are running on a FreeRTOS thread with very limited stack, the Blynk calls might cause issues.
Hence @peekay123 asked for your code after he mentioned them earlier but didn’t repeat this suggestion (I think)
But you may use his suggestion given for interrupts for SoftwareTimers just the same