[Flashing]
Hello there fellow hobbyists!
I've reached my wits end trying to develop strategies to detect--let alone prevent--bus errors occurring while trying to flash my code. main_prog.cpp is where the primary loop() and setup() functions reside, and I'm using header files to keep function prototypes and definitions cleanly distinguished.
Here is the sequence of events I followed to get to this post:
flashing the code resulted in the P2 failing SOS mode followed by 4 flashes, indicating a Bus Error
Added robust log statements at function entrypoints, re-flashed
computer endlessly disconnects for 5-10 seconds, then reconnects for up to 5 before repeating
flashing 5.7.0 via the Web doctor didn't work initially
had to force into DFU mode with the setup process to break this cycle
After following a particle member's advice of running particle flash tinker --local, particle update, then particle flash tinker --local, I was able to see my device on the cloud with default firmware.
I compile the application to make sure it's sound, no errors and problems. Worst offender seems to be printing a double as an int. From Visual Studio Code, I ran Particle: Flash application and DeviceOS(local) and wasn't able to get anywhere.
I'm more than happy to provide my sanitized code, but I want to refrain from doing so in the initial post as it feels messy, and for all I know there may be better information I could be posting. (this is my first time reaching out directly for help beyond old reddit posts)
Any suggestions? Got a slowly growing pile of assignments that rely on this device working. Debugging these bus errors has been very trick given that I can't reach any of my debug statements that would otherwise help narrow down where the erroneous code resides (if any).
ADDENDUM
Here is the relevant code I'm attempting to flash: main_prog.cpp
// Include Particle Device OS APIs
#include "main_prog.h"
#include "thermin_buzzer.h"
/* [ CONSTS AND PINS ] */
const int pin_photo = A0; // pin designated for output of photoresistor
const int pin_temp = A1; // pin designated for the analog input from the TMP36
const int pin_btn = D0;
const int pin_piezo = D1; // pin leading to the piezo, make sure we have pwm
const int LED_RED = D2; // pin for the digitally driven red LED
const int LED_GREEN = D3; // pin for the digitally driven green LED
const int LED_BLUE = D4; // pin for the digitally driven blue LED
double volts = 0;
int msSinceLastPress = 0;
// const int DEBOUNCE_DELTA = 500; //
// Let Device OS manage the connection to the Particle Cloud
SYSTEM_MODE(AUTOMATIC);
// Run the application and system concurrently in separate threads
SYSTEM_THREAD(ENABLED);
// Show system, cloud connectivity, and application logs over USB
// View logs with CLI using 'particle serial monitor --follow'
SerialLogHandler logHandler(LOG_LEVEL_INFO);
// setup() runs once, when the device is first turned on
void setup() {
initPins(); // prepare program-specific pins
Log.info("Entering setup...");
Serial.begin(9600);
}
void loop() {
// this should be used as the entrypoint to leverage other
// functions from the sibling files
checkLight();
onButtonPress(); // from thermipn_buzzer.cpp
Log.info("End of loop()");
}
main_prog.h
#ifndef MAIN_PROG_H
#define MAIN_PROG_H
#include "Particle.h"
/* [ CONSTS AND PINS ] */
extern const int pin_photo; // pin designated for voltage divider/photoresistor
extern const int pin_temp; // pin designated for the analog input from the TMP36
extern const int pin_btn; // pin designated for the button
extern const int pin_piezo; // pin leading to the piezo, make sure we have pwm
extern const int LED_RED; // pin for the digitally driven red LED
extern const int LED_GREEN; // pin for the digitally driven green LED
extern const int LED_BLUE; // pin for the digitally driven blue LED
/// @brief stores the voltage, which we'll be reading on [pin_divider]
extern double volts;
/// @brief number of milliseconds since the last press
extern int msSinceLastPress;
/// @brief Code that should run when [pin_btn] is depressed
void onButtonPress();
/// @brief handles pin-related setup code like I/O changes
void initPins();
/// @brief defines what should happen when checking the photoresistor's V_out
void onCheckLight();
#endif
thermin_buzzer.h
#ifndef THERMIN_BUZZER_H
#define THERMIN_BUZZER_H
// Include Particle Device OS APIs
#include "main_prog.h"
// Function prototypes
void initPins();
void onButtonPress();
void checkLight();
#endif // THERMIN_BUZZER_H
thermin_buzzer.cpp
#include "main_prog.h"
bool isMuted = false; // manages whether or not we're muting the piezo
/// @brief Configures the modes of the pins involved in the circuit:
/// in our thermin device, we use a piezoelectric buzzer, photoresistor,
/// and a button.
void initPins() {
pinMode(pin_piezo, AN_OUTPUT); // our piezo relies on PWM capability
pinMode(pin_photo, INPUT); // reading photoresistor output * (N/2)
pinMode(pin_btn, INPUT_PULLUP); // responsible for button presses
}
/// @brief handles the small functionality for checking the state of the button
void onButtonPress() {
// first and foremost: are we *really* pressing the button...
Log.info("Entering onButtonPress");
if(digitalRead(pin_btn) == LOW) { // sanity check
Log.info("Button pressed");
Log.info("volts: %.1f", volts); // log voltage
msSinceLastPress = millis(); // reset time of press
}
Log.info("Exiting onButtonPress");
// if(digitalRead(button) == LOW && millis() - timeLastPressed > DEBOUNCE_DELTA){
// Log.info("volts: %.1f", volts);
// timeLastPressed = millis();
// }
}
/// @brief Checks the light level via the analog input provided through
/// the V-divider and photoresistor combo
void checkLight() {
int reading = analogRead(pin_photo); // get the analog value
Log.info("Resistance: %.1n", reading);
volts = reading * 3.3 / 4095.0; // convert it to volts
// TODO: map to a frequency so we can modulate it over the PWM pin
Log.info("Exiting checkLight");
// Serial.begin(9600);
}
The only thing I see that could be an issue is Serial.begin() being called in your setup(), since it is also called when SerialLogHandler() is instantiated. Maybe try removing that?
Thanks for the advice, I've commented out Serial.begin(9600);.
In the meantime, is it possible this is something else? I just ordered the thing and have been careful not to supply more than 3.3V anywhere. I tried:
particle usb start-listener: resulted in Unable to get serial number descriptor
particle flash --usb tinker
holding MODE until (1. listening mode supposedly becomes enabled and 2. factory reset)
running the web setup and device doctor
I'm stumped!
EDIT:
I was able to put it into safe mode, and now it's back to flashing blue. Pardon my clumsiness, guess that portion was at least user error
False alarm. Pardon the frequency, not an avid forum user
Here's a rundown of the sequence of events that occur when I attempt to flash it.
0. caught in loop of white-->red(sos, then x4)
entered safe mode to verify communication with device
per troubleshooting guides, ran particle usb dfu
after entering DFU mode, ran particle update
At about 58% progress, the device jumps back to (0) above.
UPDATE: Got so deep in the muck, I forgot to try the basics again. After switching to safe mode, running the web setup worked as expected.
To my dismay, flashing the application and deviceOS through Visual Studio's Particle Workbench and--after a FULLY completed flash--it happened again.
To try and get some more insight, I opened a new terminal with particle serial monitor --follow, then flasing JUST the firmware, not the OS too.
Output
Polling for available serial device...Opening serial monitor for com port: " COM8 "
Serial monitor opened successfully:
Serial connection closed. Attempting to reconnect...
Serial monitor opened successfully:
INFO: WiFi on
0000001564 [net.lwip_rltk] INFO: promisc_deinit TODO
0000001569 [hal] INFO: WiFi off
0000001574 [system.nm] INFO: State changed: NONE -> DISABLED
0000001602 [comm] INFO: channel inited
0000001606 [app] INFO: Entering setup...
0
Serial connection closed. Attempting to reconnect...
Serial monitor opened successfully:
0000001318 [hal] INFO: WiFi on
0000001556 [net.lwip_rltk] INFO: promisc_deinit TODO
0000001561 [hal] INFO: WiFi off
0000001565 [system.nm] INFO: State changed: NONE -> DISABLED
0000001593 [comm] INFO: channel inited
0000001598 [app] INFO: Entering setup...
Turns out I need to brush up on C++ again. A peer pointed out that I was using the wrong formatting string to print an int. By changing %.1n to %.1d on Log.info("Resistance: %.1n", reading), the bus error went away.