All,
I have a situation where the electron does not wake from sleep if it misses the time to wake up. What I have noticed is that if the battery voltage drops below a certain value as it goes to sleep, it will not have enough juice to wake up on.
I am using a solar panel connected to a battery, the battery in in turn connected to the USB power input of the electron. This solution is based on the blog at Build Solar Powered & Connected Devices With Particle
The surprise is that even after the battery charges enough, the electron stays asleep. Trying to reset it manually takes several tries of plugging power in and out.
The code below is what I have running. Is there any way to solve this lack of awakening due to battery power being low at time of scheduled awakening?
// This #include statement was automatically added by the Particle IDE.
#include "ThingSpeak/ThingSpeak.h"
#include "application.h"
#define MONITOR_PIN D0
#define MODE_CONTROL_PIN D2
#define LEDPin D1
#define publish_cycle 30000 // Only publish every 10 minutes
SYSTEM_THREAD(ENABLED);
/* Thingspeak */
TCPClient client;
unsigned long myChannelNumber = 123913;
const char * myWriteAPIKey = "XXXXXXXXXXXX";
//
unsigned int lastPublish = 0;
FuelGauge fuel;
float distance;
char publishStr[20];
float timeZone = +2.0; // my local time offset
uint32_t _TheHour;
uint32_t Sleep_Hour;
uint32_t _now;
uint32_t _hour;
unsigned long pulse;
void setup() {
// Connect to ThingSpeak
ThingSpeak.begin(client);
// Give power to the sensor
pinMode(MODE_CONTROL_PIN, OUTPUT); // Set pin 0 as trigger pin
digitalWrite(MODE_CONTROL_PIN, LOW); // Set trigger LOW for continuous read
pinMode(MONITOR_PIN, INPUT); // Set pin 4 as monitor pin
pinMode(LEDPin,OUTPUT);
// Connect variables to particle cloud
// This allows you to save data to particle.io, and run commands against it such as "particle variable Photon get light"
Particle.variable("dist", double(distance));
Particle.function("batt", batteryStatus);
Serial.begin(115200);
Time.zone(timeZone);
if (Time.year() <= 1970) Particle.syncTime();
}
void loop() {
unsigned long now = millis();
// Read value from sensor Pin
distance = float(get_distance());
Sleep_Hour = Time.hour();
if (Sleep_Hour >= 6 && Sleep_Hour <= 18 ) {
if (distance < 250.00 ) {
//Turn on visual LED so we can have visual clue when it 'sees' something
digitalWrite(LEDPin, HIGH);
}
else {
digitalWrite(LEDPin, LOW);
}
// Update the ThingSpeak fields with the new data
ThingSpeak.setField(1, distance );
// Write the fields that you've set all at once.
// Publish to thinkspeak. We only publish if it has been 60 seconds since the last time we published
if ((now - lastPublish) > publish_cycle) {
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
lastPublish = now; // update the last time we published to current time
Serial.println(" - Published!");
Serial.println(String(distance));
// I would like to see battery status as well when the distance is updated
Particle.publish(
"B","v:" + String::format("%.2f",fuel.getVCell()),60, PRIVATE
);
// as well as the distance that was recorded
Particle.publish("D",
"d:" + String::format("%.2f",distance,60,PRIVATE));
//Particle.process(); // Looks like this helps with OTA updates
}
}
else {
_now = Time.now();
_hour = Time.hour();
// ( till midnight UTC ) and ( time to wake but UTC ) and ( make local )
//int _secs2sleep = (86400 - _now % 86400) + (4 * 3600 + 00 * 60 + 00) + (timeZone * 3600);
int _secs2sleep = (86400 - _now % 86400) + (4 * 3600 + 00 * 60 + 00);
Particle.publish("After Hours - We are sleeping", Time.format(_now + _secs2sleep));
//Particle.publish("Current time by the hour",String(Sleep_Hour));
//delay(1000);
Particle.publish("Current Hour is:", Time.format(_now ));
System.sleep(SLEEP_MODE_DEEP, _secs2sleep);
}
Particle.process(); // looks like this helps with OTA updates
}
//get the distance from the lidar sensor
int get_distance() {
// read the input on pin 4:
pulse = pulseIn(MONITOR_PIN, HIGH);
if(pulse != 0) {
pulse = pulse / 10; // 10usec = 1 cm of distance
}
return pulse;
}
// 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()>50){ return 1;}
// if you're running out of battery, return 0
else { return 0;}
}