Skip to content

Instantly share code, notes, and snippets.

@kikolobo
Last active October 17, 2015 07:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kikolobo/51cd18987f8d7c949c43 to your computer and use it in GitHub Desktop.
Save kikolobo/51cd18987f8d7c949c43 to your computer and use it in GitHub Desktop.
WXMAN
// 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