Eventually I was able to reset the Electron, it is working with the webIDE and I was able to flash the tutorial “flash an LED” successfully.
I hesitate to plug it back into the “Asset Tracker” shield or flash the project I was working on before I know what the root cause is.
I was hoping someone would be kind enough to review the attached wiring diagram and the code below and help me figure out what I did wrong?
When I finished Sunday night everything was working great, Last night I made some (I thought minor) changes to my code and flashed it to the device. After that I could no longer communicate with the Electron and had the dark blue flashing LED. I hadn’t made any wiring changes, but am not sure the wiring isn’t the problem.
//================================================================================================= REQUIRED LIBRARIES
#include <AssetTracker.h>
#include <WS2812FX.h>
SYSTEM_THREAD(ENABLED); // Allows the Electron to powerup and run with no connection available
SYSTEM_MODE(AUTOMATIC); // Allows the Electron to search for and make a connection
//================================================================================================= INITIALIZATION PARAMETERS
#define PIXEL_PIN D3
#define PIXEL_COUNT 24
#define PIXEL_TYPE WS2812B
WS2812FX ws2812fx = WS2812FX(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
#define LED_TIMER_MS 10000
int MAINT_PIN = D1;
int COVER_PIN = D2;
int BEEP_PIN = B3;
Servo myservo; // create servo object to control a servo a maximum of eight servo objects can be created
FuelGauge fuel; // A FuelGauge named 'fuel' for checking on the battery state
AssetTracker t = AssetTracker(); // Creating an AssetTracker named 't' for us to reference
//================================================================================================= FUNCTIONAL PARAMETERS AND VARIABLES
//============================= TIMER TRACKING
int lastStatusUpdate = 0;
int lastMaintUpdate = 0;
int lastHazardUpdate = 0;
int activationTime = 0;
int servoHoldRetract = 0;
int StatusMsgFreq = 5 * 24 * 60 * 60 * 1000; // days*hr*min*sec*ms -- sends a battery status update every (x) days
int MaintDWELL = 1 * 60 * 1000; // min*sec*ms -- allows (x) minutes before going into hazard mode
int MaintMsgFreq = 5 * 60 * 1000; // min*sec*ms -- sends a maintenance message every (x) minutes
int HazardMsgFreq = 1 * 60 * 1000; // min*sec*ms -- sends a hazard message every (x) minutes
//============================= STATE TRACKING
bool beepOn = false;
bool enabled = false;
bool isDeployed = false;
bool maintState = false;
bool hazardState = false;
bool ledOn = false;
//============================= GENERAL VARIABLES
uint16_t LED_brightness = 1;
unsigned long last_change = 0;
unsigned long now = 0;
unsigned long startupTime = 0;
int beepdelay = 0;
int pos = 0; // variable to store the servo position
//================================================================================================= INITIALIZES THE DEVICE WHEN POWER COMES ON
void setup() {
startupTime = millis();
ws2812fx.init();
ws2812fx.setBrightness(LED_brightness);
ws2812fx.setSpeed(1000);
ws2812fx.setColor(0x007BFF);
ws2812fx.setMode(FX_MODE_CIRCUS_COMBUSTUS);
// ws2812fx.start();
Particle.function("batt", batteryStatus);
// Particle.function("null", setNull);
Particle.function("setSpeed", setSpeed);
Particle.function("setBright", setBrightness);
Particle.function("reset", resetAll);
Particle.function("enable", enableDisable);
myservo.attach(D0); // attach the servo on the D0 pin to the servo object
myservo.write(5); // test the servo by moving it to 25°
pinMode(BEEP_PIN, OUTPUT);
pinMode(COVER_PIN, INPUT_PULLDOWN);
pinMode(MAINT_PIN, INPUT_PULLDOWN);
beepOn = false;
}
//================================================================================================= MAIN LOOP; RUNS CONTINUSOUSLY WHEN POWER IS ON
void loop()
{
if (digitalRead(COVER_PIN) == HIGH && enabled)
{
if (activationTime == 0) { activationTime = millis(); }
ws2812fx.setBrightness(LED_brightness);
maintenanceMode();
}
else
{
myservo.write(5);
ws2812fx.stop();
ledOn = false;
t.gpsOff();
isDeployed = false;
maintState = false;
hazardState = false;
statusMode();
lastStatusUpdate = 0;
lastMaintUpdate = 0;
lastHazardUpdate = 0;
activationTime = 0;
servoHoldRetract = 0;
}
}
//================================================================================================= ACTIVATION MODE HANDLING
// The cover has been released
// Send a one-time activation message
// Allow time for maintenance overide
// If overide is not activated switch to hazard mode
void maintenanceMode()
{
if (digitalRead(MAINT_PIN) == HIGH) // maintenance overide enabled
{
ws2812fx.stop();
isDeployed = false;
myservo.write(5);
if (millis() - lastMaintUpdate > MaintMsgFreq)
{
sendMaintMessage();
lastMaintUpdate = millis();
}
piezo(3000, 30);
}
else
{
if (lastHazardUpdate == 0)
{
lastHazardUpdate = millis();
}
if (millis() - lastHazardUpdate > MaintDWELL)
{
hazardMode();
}
}
}
void statusMode() // The cover is depressed, send regular status updates at the preset frequency
{
if (millis() - lastStatusUpdate > StatusMsgFreq)
{
lastStatusUpdate = millis();
}
}
void hazardMode() // The cover has been released and the maintenance overide has not been enabled
{
ws2812fx.service();
if (!isDeployed)
{
myservo.write(25);
isDeployed = true;
servoHoldRetract = millis();
t.gpsOn();
t.updateGPS();
if (!ledOn)
{
ws2812fx.start();
ledOn = true;
}
}
else
{
if (isDeployed && millis() - servoHoldRetract > 15000)
{
myservo.write(5);
}
piezo(700, 150);
}
if (millis() - lastHazardUpdate > HazardMsgFreq)
{
// GPS requires a "fix" on the satellites to give good data, so we should only publish data if there's a fix
if (t.gpsFix())
{
sendHazardMessage();
lastHazardUpdate = millis();// Remember when we published
t.gpsOff(); // when publishing is complete turn the GPS off to save power
}
}
}
//================================================================================================= COMMUNICATIONS HANDLING
void sendStatusMessage()
{
Particle.publish("STATUS", "v:" + String::format("%.2f", fuel.getVCell()) + ",c:" + String::format("%.2f", fuel.getSoC()), 60, PRIVATE);
}
void sendMaintMessage()
{
Particle.publish("MAINT", "v:" + String::format("%.2f", fuel.getVCell()) + ",c:" + String::format("%.2f", fuel.getSoC()), 60, PRIVATE);
}
void sendHazardMessage()
{
Particle.publish("HAZARD", "Lat-Long: " + t.readLatLon() + " Batt v:" + String::format("%.2f", fuel.getVCell()) + " Batt c:" + String::format("%.2f", fuel.getSoC()), 60, PRIVATE);
}
void piezo(int gap, int width)
{
if (beepdelay>gap)
{
digitalWrite(BEEP_PIN, HIGH);
delay(width);
beepdelay = 0;
}
else
{
digitalWrite(BEEP_PIN, LOW);
beepdelay++;
}
}
//================================================================================================= REMOTE COMMAND HANDLING
// Lets you remotely check the battery status by calling the function "batt"
// Triggers a publish with the info (so subscribe or watch the dashboard)
// and also returns a '1' if there's >10% battery left and a '0' if below
int batteryStatus(String command)
{
// Publish the battery voltage and percentage of battery remaining
// if you want to be really efficient, just report one of these
// the String::format("%f.2") part gives us a string to publish,
// but with only 2 decimal points to save space
Particle.publish("B",
"v:" + String::format("%.2f", fuel.getVCell()) +
",c:" + String::format("%.2f", fuel.getSoC()),
60, PRIVATE
);
// if there's more than 10% of the battery left, then return 1
if (fuel.getSoC()>10) { return 1; }
// if you're running out of battery, return 0
else { return 0; }
}
int enableDisable(String command)
{
uint16_t cmd = atoi(command);
if (cmd < 0 || cmd > 1)
{
return -1;
}
enabled = cmd;
return 0;
}
int resetAll(String command)
{
myservo.write(5);
delay(100);
ws2812fx.stop();
ledOn = false;
t.gpsOff();
isDeployed = false;
activationTime = 0;
lastMaintUpdate = 0;
lastHazardUpdate = 0;
maintState = false;
hazardState = false;
statusMode();
startupTime = millis();
}
int setSpeed(String speed_str) // Override - Changes the rotation speed of the LED pattern; resets on power down/up
{
uint16_t speed = atoi(speed_str);
if (speed < 0 || speed > 65535) return -1;
ws2812fx.setSpeed(speed);
return 0;
}
int setBrightness(String brightness_str) // To save battery power during debugging you can remotely set this value to 5 or less (default is 255); resets on power down/up
{
LED_brightness = atoi(brightness_str);
if (LED_brightness < 0 || LED_brightness > 255) return -1;
ws2812fx.setBrightness(LED_brightness);
return 0;
}