#include <SPI.h> #include <WiFi.h> #include <HTTPClient.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_ADS1X15.h> #include <EEPROM.h> #include "anniebitmap.h"
int activeConnection = 1;
// hansen const String ssid1 = "chewme2g"; const String password1 = "1355311355";
// silo const String ssid2 = "asus2G"; const String password2 = "iqpqw41396";
const String heartbeatUrl = "https://homelab.impressto.ca/silopower/heartbeat.php"; const String pressureUrl = "https://homelab.impressto.ca/silopower/set_water_pressure.php?data=";
#define EEPROM_SIZE 4 int eepromPingsAddress = 0; float totalServerPings = 0; int eepromFailedPingsAddress = 1; float totalServerPingFails = 0; int eepromActiveConnection = 1;
#define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define LOGO_HEIGHT 128 #define LOGO_WIDTH 64
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET - 1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, & Wire, OLED_RESET);
Adafruit_ADS1115 ads;
long secondsOfHour = 0;
const int secondsPerHour = 3600; // set to 60 for debugging const int pulseRate = 1000; // loop runs once per second
const int serverSendInterval = 10; // 10 minutes between sending a voltage update to the server const int samplesPerReading = 60 * serverSendInterval; // every x minutes send a sample to the server
int loopCount = 0;
String payload = ""; int httpCode = 0; bool wifiConnected = false; bool wifiPaused = false; int wifiPausedTick = 0; bool wifiSleeping = false; bool debug = false; // when true server does not update bool serverFailed = false; int wifiConnectionAttempts = 0;
float basePressureVoltage = 0.46; float totalledAveragePressure = 0; float averagePressure = 0;
HTTPClient http;
void setup() { Serial.begin(115200);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever }
if (!ads.begin()) { Serial.println("Failed to initialize ADS."); while (1); }
display.clearDisplay(); display.drawBitmap(0, 0, epd_bitmap_annie, 128, 64, 1); display.display(); delay(3000);
//Init EEPROM EEPROM.begin(EEPROM_SIZE);
activeConnection = EEPROM.read(eepromActiveConnection);
Serial.print("eepromActiveConnection :"); Serial.println(activeConnection);
if (isnan(activeConnection)) { activeConnection = 1; }
if (activeConnection == 0) { activeConnection = 1; }
Serial.print("activeConnection: "); Serial.println(activeConnection);
float pingData = EEPROM.readFloat(eepromPingsAddress); if (isnan(pingData)) { pingData = 0; } totalServerPings = pingData; EEPROM.end(); EEPROM.begin(EEPROM_SIZE); float pingFailData = EEPROM.readFloat(eepromFailedPingsAddress); if (isnan(pingFailData)) { pingFailData = 0; } totalServerPingFails = pingFailData; EEPROM.end();
if (!connectToWiFi()) { delay(2000); WiFi.disconnect(); delay(1000); if (activeConnection == 1) { activeConnection = 2; } else { activeConnection = 1; } connectToWiFi(); }
delay(2000); // Pause for 2 seconds
}
void loop() {
secondsOfHour++;
// after 24 hours reset this integer if (secondsOfHour > 86400) { secondsOfHour = 1; // Serial.println("restarting :"); ESP.restart(); }
int16_t adc0;
adc0 = ads.readADC_SingleEnded(0); float voltage = (adc0 * 0.1875) / 1000; //- basePressureVoltage);
float normalizedVolatage = voltage - basePressureVoltage;
if (normalizedVolatage < 0) { normalizedVolatage = 0; }
float pressure = normalizedVolatage * (30 - (normalizedVolatage * 3));
if (pressure < 0) {
pressure = 0; }
totalledAveragePressure += pressure;
averagePressure = totalledAveragePressure / loopCount;
Serial.println("averagePressure: "); Serial.println(averagePressure); display.clearDisplay(); display.setTextSize(3); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("PSI: "); display.println(pressure, 0); display.println(""); display.setTextSize(1); display.print("sensor volts: "); display.println(normalizedVolatage, 2); display.display();
///////////////////// // SERVER RELAY if (!debug && (loopCount >= samplesPerReading) || serverFailed) {
loopCount = 0;
setWifiSleepMode(false);
delay(2000);
// do a heartbeat check to see if we are online... http.begin(heartbeatUrl); httpCode = http.GET(); if (!httpCode > 0) { // wifi may not be alive yet so wait 3 seconds delay(3000); }
String recordedPressure = String(averagePressure, 1);
recordedPressure.trim();
loopCount = 0;
http.begin(pressureUrl + recordedPressure); httpCode = http.GET(); if (httpCode > 0) { payload = http.getString(); Serial.println("HTTP Response: " + payload); recordPingSucces(); } else { recordPingFailure(); } http.end();
setWifiSleepMode(true); }
loopCount++;
delay(1000);
}
void testdrawbitmap(void) { display.clearDisplay(); display.drawBitmap(0, 0, epd_bitmap_annie, 128, 64, 1); display.display(); delay(3000); }
bool connectToWiFi() {
String activeSsid = ""; String activePassword = "";
if (activeConnection == 1) { activeSsid = ssid1; activePassword = password1; } else if (activeConnection == 2) { activeSsid = ssid2; activePassword = password2; }
Serial.print("Connecting to WiFi: "); Serial.println(activeSsid);
WiFi.begin(activeSsid, activePassword);
while (WiFi.status() != WL_CONNECTED && wifiConnectionAttempts < 20) { delay(500); Serial.print("."); wifiConnectionAttempts++; }
wifiConnectionAttempts = 0;
if (WiFi.status() == WL_CONNECTED) { Serial.println("\nConnected to WiFi"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); wifiConnected = true;
EEPROM.begin(EEPROM_SIZE); EEPROM.write(eepromActiveConnection, activeConnection); EEPROM.commit(); EEPROM.end();
Serial.print("set activeConnection to : "); Serial.println(activeConnection);
return true;
} else { Serial.print("Connection to "); Serial.print(activeSsid); Serial.println(" failed. Trying alternative"); return false; } }
/** * set wifi sleep mode between data relays to conserve energy * @param sleepMode - if true set wifi card to sleep to conserve energy */ void setWifiSleepMode(bool sleepMode) {
wifiSleeping = sleepMode;
if (sleepMode) { WiFi.disconnect(); WiFi.setSleep(true); delay(1000); Serial.print("sleep wifi status: "); Serial.println(wl_status_to_string(WiFi.status())); } else { WiFi.setSleep(false); WiFi.reconnect(); delay(1000); Serial.print("awaken wifi status: "); Serial.println(wl_status_to_string(WiFi.status())); // Check if the connection is still active. if not trigger wait for it to come back online if (WiFi.status() != WL_CONNECTED && !wifiPaused) { Serial.println("Connection lost. Attempting to reconnect in 1 minute ..."); WiFi.disconnect(); wifiPaused = true; wifiConnected = false; connectToWiFi(); } } }
/** * record server ping success in long term memory */ void recordPingSucces() { totalServerPings++; EEPROM.begin(EEPROM_SIZE); EEPROM.writeFloat(eepromPingsAddress, totalServerPings); EEPROM.commit(); EEPROM.end(); wifiConnected = true; serverFailed = false; }
/** * record server ping fails in long term memory */ void recordPingFailure() { totalServerPingFails++; EEPROM.begin(EEPROM_SIZE); EEPROM.writeFloat(eepromFailedPingsAddress, totalServerPingFails); EEPROM.commit(); EEPROM.end(); wifiConnected = false; serverFailed = true; }
/** * ESP32 wifi card statuses * @param status * @return string */ String wl_status_to_string(wl_status_t status) {
String response = "";
switch (status) { case WL_NO_SHIELD: response = "WL_NO_SHIELD"; break; case WL_IDLE_STATUS: response = "WL_IDLE_STATUS"; break; case WL_NO_SSID_AVAIL: response = "WL_NO_SSID_AVAIL"; break; case WL_SCAN_COMPLETED: response = "WL_SCAN_COMPLETED"; break; case WL_CONNECTED: response = "WL_CONNECTED"; break; case WL_CONNECT_FAILED: response = "WL_CONNECT_FAILED"; break; case WL_CONNECTION_LOST: response = "WL_CONNECTION_LOST"; break; case WL_DISCONNECTED: response = "WL_DISCONNECTED"; break; }
return response; }
|