I have a Boron that is on 4.0.0
I am trying to wake on RTC or 4 DI’s on Falling
I have not been able to make sense of the examples for sleep along with the RTC.
Does anyone have any examples that may help or tips on how to get this going ?
The goal is to have it wake at 0400 and 1200, publish the states of the sensors, stay awake for 15-20 minutes and go back to ULP mode, no cellular connection. Which will also makes digital output 2 and 3 go low, turning off the pressure transmitter and the LCD. Displaying my information to the LCD is working well except for the bug that scrambles or blanks the LCD after a indeterminate amount of time.
Nothing with this system needs to operate quickly, I am sending the water level and door status, along with bottle pressure and temperature 2x a day
Thank you !
/* SHOWER TRAILER MONITOR
* Monitor door position, water level low and LOWLOW switches
* Monitor temperature via I2C sendor and gas bottle pressure via analog input
* Send information to cloud 2 times a day at 0400, 1200
* Board to sleep mode between transmissions turning off LCD and cellular. Will wake on door switch or wake button
* When board has been woken up it is to stay awake for 20 minutes, transmit status when woken up and prior to returning to sleep.
* THINGS TO DO: Sleep mode, debounce DI's,
* Sleep mode, will go to sleep after 20 minutes, can be woken up by wake button, low & low low water, and door switch.
* Sleep mode ULP with only pins active will be the pins that can wake. Cellular off.
*/
#include "AnalogSmoother.h"
#include "Arduino.h"
#include "Debounce.h"
#include <Wire.h>
#include "LiquidCrystal_I2C_Spark.h"
#include <SparkFun_Qwiic_Humidity_AHT20.h>
AHT20 humiditySensor;
// WAKE BUTTON
const int wake_sw = 8;
int last_wake_sw;
bool wake_new_value = false;
// DOOR SWITCHES
const int door_sw = 6;
int last_door_pos;
bool door_new_value = false;
// WATER LEVEL SWITCHES
const int water_low_sw = 4;
const int water_LOWLOW_sw = 5;
int last_water_level;
bool water_low_new_value = false;
bool water_LOWLOW_new_value = false;
// LCD
int lcd_power = D3;
LiquidCrystal_I2C *lcd;
// ON BOARD LED
int led = D7;
// BATTERY MONITORING
AnalogSmoother battery(A1, 10);
int batteryPin = A1;
int batteryValue = 0;
int batteryScaled = 0;
// GAS PRESSURE
AnalogSmoother gas_pressure(A0, 10);
int gas_pressure_power = D2;
int gas_pressurePin = A0;
int gas_pressureValue = 0;
int gas_pressureScaled = 0;
// TEMPERATURE
// CLOUD CONNECTION
int last_cloud_connected;
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);
// SLEEP CONFIGURATION
SystemSleepConfiguration& gpio(pin_t pin, InterruptMode mode)
SystemSleepConfiguration config;
config.mode(SystemSleepMode::ULTRA_LOW_POWER)
.gpio(D4, FALLING);
.gpio(D5, FALLING);
.gpio(D6, FALLING);
.gpio(D8, FALLING);
// TIME
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();
void setup()
{
// PINS AND PIN MODES
pinMode(door_sw, INPUT_PULLDOWN);
pinMode(water_low_sw, INPUT_PULLDOWN);
pinMode(water_LOWLOW_sw, INPUT_PULLDOWN);
pinMode(wake_sw, INPUT_PULLDOWN);
pinMode(led, OUTPUT);
pinMode(lcd_power, OUTPUT);
pinMode(gas_pressure_power, OUTPUT);
digitalWrite(lcd_power, HIGH);
digitalWrite(gas_pressure_power, HIGH);
Serial.begin(115200);
gas_pressure.fill();
battery.fill();
lcd = new LiquidCrystal_I2C(0x3f, 20, 4);
lcd->init();
lcd->backlight();
lcd->clear();
lcd->setCursor(0,0);
lcd->print("SHOWER TRAILER 0000");
lcd->setCursor(0,1);
lcd->print("STARTING UP");
delay(2000);
Wire.begin();
//Check if the AHT20 will acknowledge
if (humiditySensor.begin() == false)
{
Serial.println("AHT20 not detected. Please check wiring. Freezing.");
while (1);
}
Serial.println("AHT20 acknowledged.");
// Turning on cellular and connecting to the cloud
if(Cellular.isOff() == true)
{
Cellular.on();
waitFor(Cellular.isOn, 30000);
}
Cellular.connect();
if(Particle.connected() == false)
{
Particle.connect();
waitFor(Particle.connected, 30000);
lcd->setCursor(0,3);
lcd->print("CLOUD STATUS");
lcd->print(Particle.connected());
delay(10000);
}
// CLOCK
if (millis() - lastSync > ONE_DAY_MILLIS)
{
// Request time synchronization from the Particle Device Cloud
Particle.syncTime();
lastSync = millis();
}
// Send field status to cloud upon startup
if(Particle.connected() == true)
{
Particle.publish("Ftemp","Ftemp()",60,PRIVATE);
Particle.publish("batteryScaled","batteryScaled()",60,PRIVATE);
Particle.publish("Water_Level","Water_Level()",60,PRIVATE);
delay(30000);
Particle.publish("door_pos","door_pos()",60,PRIVATE);
Particle.publish("gas_pressureScaled","gas_pressureScaled()",60,PRIVATE);
delay(30000);
// LCD print successful transmission of data {{{{{{{NEED TO COMPLETE}}}}}
lcd->setCursor(0,4);
lcd->print("SENSORS PUBLISHED");
delay(30000);
}
lcd->clear();
}
void loop()
{
if (humiditySensor.available() == true)
{
Serial.println("SHOWER TRAILER 0000");
lcd->setCursor(0,0);
lcd->print("SHOWER TRAILER 0000");
// Temperature and Battery
float temperature = humiditySensor.getTemperature();
float Ftemp = round(((temperature * 9/5)+32));
Serial.print("Temp: ");
Serial.print(Ftemp);
Serial.print(" F\t");
batteryValue = battery.read();
float batteryScaled = map(batteryValue,1163,3721,5,16);
Serial.print("BATT: ");
Serial.print(batteryScaled);
Serial.print(" V " );
Serial.print("Battery AI:");
Serial.print(batteryValue);
Serial.println();
lcd->setCursor(0,1);
lcd->print("TEMP:");
lcd->print(Ftemp, 0);
lcd->print("F");
lcd->print(" Batt:");
lcd->print(batteryScaled);
lcd->print("V");
// WATER LEVEL SWITCHES
int Water_Level = digitalRead(water_low_sw) + digitalRead(water_LOWLOW_sw);
lcd->setCursor(0,2);
{
switch (Water_Level)
{
case 0:
Serial.print("WTR:MIN! ");
lcd->print("WTR:MIN!");
break;
case 1:
Serial.print("WTR:LOW ");
lcd->print("WTR:LOW ");
break;
case 2:
Serial.print("WTR:GOOD ");
lcd->print("WTR:GOOD");
break;
default:
Serial.println("WTR:ERR! ");
lcd->print("WTR:ERR!");
break;
}
last_water_level = Water_Level;
}
// DOOR POSITION SWITCHES
int door_pos = digitalRead(door_sw);
lcd->setCursor(10,2);
{
switch (door_pos)
{
case 0:
Serial.print("DOOR:OPEN");
lcd->print("DOOR:OPEN");
break;
case 1:
Serial.print("DOOR:CLSD");
lcd->print("DOOR:CLSD");
break;
}
last_door_pos = door_pos;
Serial.println();
}
// WAKE BUTTON
int wake_sw_lvl = digitalRead(wake_sw);
{
switch (wake_sw_lvl)
{
case 0:
Serial.print("WAKE SWITCH:");
Serial.print("NOT");
break;
case 1:
Serial.print("WAKE SWITCH:");
Serial.print("AWAKEN");
break;
}
last_wake_sw = wake_sw_lvl;
}
// GAS PRESSURE TROUBLE and PRESSURE VALUES
if(gas_pressureValue < 500)
{
Serial.println();
Serial.print("GAS:");
Serial.print("TRBL ");
Serial.print("Gas P AI:");
gas_pressureValue = gas_pressure.read();
float gas_pressureScaled = map(gas_pressureValue,600,3000,1,3000);
Serial.print(gas_pressureValue);
lcd->setCursor(0,3);
lcd->print("GAS:");
lcd->print("TRBL ");
}
else
{
Serial.println();
Serial.print("GAS:");
Serial.print(gas_pressureScaled);
Serial.print(" PSIG");
Serial.print("Gas P AI:");
Serial.print(gas_pressureValue);
lcd->setCursor(0,3);
lcd->print("GAS:");
lcd->print(gas_pressureScaled);
lcd->print("PSI");
}
Serial.println();
// CLOUD CONNECTED
int cloud_connected = Particle.connected();
lcd->setCursor(12,3);
{
switch (cloud_connected)
{
case 0:
Serial.print("CLOUD NOT CONNECTED");
lcd->print("CLD:NOT");
break;
case 1:
Serial.print("CLOUD CONNECTED");
lcd->print("CLD:CON");
break;
}
last_cloud_connected = cloud_connected;
}
// just a idiot light to see if it is running.
digitalWrite(led, HIGH);
delay(5000);
digitalWrite(led, LOW);
delay(1000);
Serial.println();
delay(5000);
}
delay(2000);
}