-
-
Save kikolobo/51cd18987f8d7c949c43 to your computer and use it in GitHub Desktop.
WXMAN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This #include statement was automatically added by the Particle IDE. | |
#include "SparkFun_Photon_Weather_Shield_Library/SparkFun_Photon_Weather_Shield_Library.h" | |
#include "SparkFunMAX17043/SparkFunMAX17043.h" | |
//Chip Config | |
#define PIN_SOLARNRG A2 | |
#define PIN_POWERALERT_ISR D6 | |
//Settings | |
#define version "0.2c" | |
#define lowPowerAlert 27 | |
#define lowPowerInterlock 17 | |
#define minKeepAliveReportPeriod 20*1*1000 //Every 20 Seconds. Anything above will require a sleep. | |
//Battery Shield | |
float voltage = 0.0; | |
float soc = 0.0; | |
bool alert = false; | |
retained int alertCount = 0; | |
float solarNrg = 0.0; | |
float solarNrgRaw = 0.0; | |
//Weather shield | |
Weather sensor; | |
//Weather Shield | |
float humidity = 0; | |
float tempc = 0; | |
float pascals = 0; | |
float baroTemp = 0; | |
float mercury = 0; | |
//System Flags | |
long lastMillis = 0; | |
retained bool wasInDeepSleep = false; | |
retained int rebootCount=0; | |
long reportPeriod = minKeepAliveReportPeriod; | |
bool enableSleep = true; | |
bool firstBoot = true; | |
void setup() | |
{ | |
pinMode(PIN_SOLARNRG, INPUT); | |
Time.zone(-5); | |
Particle.function("sleepEnable", sleepEnable); | |
Particle.function("resetNow", resetNow); | |
Particle.function("getAlrtCnt", getAlertCount); | |
Serial.begin(9600); | |
////////////////// | |
alert = false; | |
firstBoot = true; | |
lastMillis = millis(); | |
//PowerShield | |
lipo.begin(); | |
lipo.quickStart(); | |
lipo.setThreshold(lowPowerAlert); | |
//WeatherShield | |
sensor.begin(); | |
sensor.setModeBarometer(); | |
sensor.setOversampleRate(100); | |
sensor.enableEventFlags(); | |
String bootStatusString; | |
String ip = WiFi.localIP(); | |
bootStatusString = bootStatusString.format("V= %s, RSSI= %d, SSID= '%s', IP=%s", version, WiFi.RSSI(), WiFi.SSID(), ip.c_str()); | |
Particle.publish("BOOT", bootStatusString); | |
Serial.println("*************************"); | |
Serial.println(" WXMAN"); | |
Serial.print("Version: "); | |
Serial.println(version); | |
Serial.println("By Lobo:Labs 2015"); | |
Serial.println("System Ready......"); | |
Serial.println("Stabilization Period....."); | |
Serial.println("*************************"); | |
delay(8000); | |
Particle.publish("ENTLP", "AT=" + String(millis()) + ", RBTS=" + String(rebootCount)); | |
Serial.println("Running Firmware...."); | |
} | |
void loop() | |
{ | |
getBatteryVitals(); | |
checkInterlock(); | |
getWeather(); | |
pulse(); | |
} | |
void pulse() | |
{ | |
calculateReportPeriod(); | |
Serial.println("♡ ♡ [" + String((reportPeriod - (millis()-lastMillis)) /1000) + " s]"); | |
if (wasInDeepSleep==true) { | |
Particle.publish("RECVR"); | |
delay(1000); | |
} | |
if ((millis()-lastMillis>reportPeriod) || firstBoot == true) { | |
Serial.println("♥ ♥"); | |
RGB.control(true); | |
RGB.color(255, 224, 13); | |
firstBoot = false; | |
startWiFiIfNeeded(); | |
waitForWiFiOrResetIfTimeOut(); | |
delay(1000); | |
publishBatteryEvents(); | |
delay(1000); | |
publishWXEvents(); | |
delay(1000); | |
RGB.control(false); | |
delay(200); | |
lastMillis = millis(); | |
if (enableSleep==true &&(reportPeriod > minKeepAliveReportPeriod)) { WiFi.off(); } | |
} | |
if (alert) { | |
Serial.println(">>>>>>> [--//--] <<<<<<<"); | |
RGB.control(true); | |
RGB.color(195, 0, 0); | |
delay(700); | |
RGB.brightness(10); | |
//alertCount++; | |
startWiFiIfNeeded(); | |
waitForWiFiOrResetIfTimeOut(); | |
//wasInDeepSleep = true; | |
Particle.publish("LOWP"); | |
publishBatteryEvents(); | |
delay(3000); | |
int sleepTime = 60*2; // 2 Hours | |
if (solarNrg <= 50) { //Sun & power is Low, so let's leep a little longer. | |
sleepTime = 60*4; //4 Hours | |
} | |
lipo.sleep(); | |
// System.sleep(SLEEP_MODE_DEEP, 60*sleepTime); | |
deepSleepFor(60*sleepTime); | |
delay(1000); | |
RGB.control(false); | |
} | |
} | |
void checkInterlock() | |
{ | |
if (alert && soc <= lowPowerInterlock) { | |
Serial.println(">>>>>>> [---////---] <<<<<<<"); | |
deepSleepFor(60*1); | |
} | |
} | |
void deepSleepFor(int seconds) { | |
alertCount++; | |
wasInDeepSleep = true; | |
RGB.control(true); | |
RGB.color(195, 0, 0); | |
RGB.brightness(10); | |
delay(1000); | |
System.sleep(SLEEP_MODE_DEEP, seconds); //One hour Emergency Shutdown. | |
} | |
void startWiFiIfNeeded() { | |
if (WiFi.ready() == false) { | |
Serial.println(">>>>>>> WIFI CONNECTING"); | |
WiFi.on(); | |
delay(1500); | |
} | |
} | |
void waitForWiFiOrResetIfTimeOut() { | |
if (waitFor(Particle.connected, 60000)) { | |
delay(50); | |
} else { | |
Serial.println("<<<< WIFI NO JOY <<<<< REBOOTING "); | |
rebootCount++; | |
System.reset(); | |
} | |
} | |
//Helper Methods | |
void getBatteryVitals() | |
{ | |
lipo.wake(); | |
delay(100); | |
voltage = lipo.getVoltage(); | |
soc = lipo.getSOC(); | |
alert = lipo.getAlert(true); | |
solarNrgRaw = ((analogRead(PIN_SOLARNRG) * 3.0)/4095); | |
solarNrg = (100 / 3) * solarNrgRaw; | |
String powerSupStr = "RPP=" + String(reportPeriod) + ", SOLNRG=" + String(solarNrg); | |
String powerStatStr = ", VTS=" + String(voltage) + ", SOC=" + String(soc,2) + ", LOWP=" + String(alert) + ", DPSL=" + String(wasInDeepSleep); | |
Serial.print("BATT: "); | |
Serial.println(powerSupStr + powerStatStr); | |
} | |
void calculateReportPeriod() { | |
reportPeriod = 5000; | |
if (soc<=93) reportPeriod = minKeepAliveReportPeriod; | |
if (soc<=60) reportPeriod = 60*1*1000; | |
if (soc<=50) reportPeriod = 60*2*1000; | |
if (soc<=35) reportPeriod = 60*5*1000; | |
//if (soc<=30) reportPeriod = 60*10*1000; | |
//if (soc<=29) reportPeriod = 60*10*1000; | |
if (enableSleep == false) { reportPeriod = 5000; } | |
} | |
//EVENT PUBLISHING | |
void publishBatteryEvents() | |
{ | |
String powerSupStr = "RPP=" + String(reportPeriod) + ", SOLNRG=" + String(solarNrg); | |
String powerStatStr = ", VTS=" + String(voltage) + ", SOC=" + String(soc,2) + ", LOWP=" + String(alert) + ", DPSL=" + String(wasInDeepSleep); | |
Particle.publish("POWSTAT", powerSupStr + powerStatStr); | |
wasInDeepSleep = false; | |
} | |
void publishWXEvents() | |
{ | |
String wxAtmosStr = "RHUM=" + String(humidity, 2) + ", TMP=" + String(tempc) + ", BARO=" + String(mercury) + ", WDIR=000, WSPD=000"; | |
Particle.publish("WXATMOS", wxAtmosStr); | |
} | |
//Cloud Functions | |
bool sleepEnable(String args) { | |
enableSleep = !enableSleep; | |
return enableSleep; | |
} | |
bool resetNow(String args) { | |
System.reset(); | |
return true; | |
} | |
bool getAlertCount(String args) { | |
return alertCount; | |
} | |
////////////////////// | |
//Create Instance of HTU21D or SI7021 temp and humidity sensor and MPL3115A2 barrometric sensor | |
//--------------------------------------------------------------- | |
//--------------------------------------------------------------- | |
//--------------------------------------------------------------- | |
void getWeather() | |
{ | |
humidity = sensor.getRH(); | |
tempc = sensor.getTemp(); | |
baroTemp = sensor.readBaroTemp(); | |
pascals = sensor.readPressure(); | |
mercury = (pascals/100) * 0.0295300; | |
String powerSupStr = "RPP=" + String(reportPeriod) + ", SOLNRG=" + String(solarNrg); | |
String powerStatStr = ", VTS=" + String(voltage) + ", SOC=" + String(soc,2) + ", LOWP=" + String(alert) + ", DPSL=" + String(wasInDeepSleep); | |
Serial.print("WX: "); | |
String wxAtmosStr = "RHUM=" + String(humidity, 2) + ", TMP=" + String(tempc) + ", BARO=" + String(mercury) + ", WDIR=000, WSPD=000"; | |
Serial.println(wxAtmosStr); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment