I have a little Dell Laptop (Win 10) with IDE 1.8.19 installed that I use to load remote processors here on my homestead.
I am getting an error message on the 1.8.19 compile that is not generated on the IDE 2.1.1 on my Windows 11 PC with the very same sketch code.
I emphasized the related code lines for clarity.
Any ideas appreciated,
Ed
Error message:
Arduino: 1.8.19 (Windows 10), Board: "ESP32 Wrover Module, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), QIO, 80MHz, 921600, None, Disabled"
WARNING: library StackString claims to run on avr architecture(s) and may be incompatible with your current board which runs on esp32 architecture(s).
C:\Users\edthe\AppData\Local\Temp\arduino_modified_sketch_558916\Pump_House_Monitor_ver8M.ino: In function 'void loop()':
Pump_House_Monitor_ver8M:162:24: error: operation on 'on_off_cycle_count' may be undefined [-Werror=sequence-point]
on_off_cycle_count = (++ on_off_cycle_count);
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus.exe: some warnings being treated as errors
Multiple libraries were found for "WiFi.h"
Used: C:\Users\edthe\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.5\libraries\WiFi
Not used: C:\Users\edthe\Arduino 1.8.19 Sketches\libraries\WiFiNINA
Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
exit status 1
Main code:
#include "hashtag_includes.h" // see tabs at top
#include "constants.h"
void setTimezone(const char* timezone) {
Serial.print("Setting Timezone to ");
Serial.println(timezone);
setenv("TZ", timezone, 1);
tzset();
}
void initTime(const char* timezone) {
struct tm timeinfo;
Serial.println("Getting time from NTP server");
configTime(0, 0, "pool.ntp.org"); // First connect to NTP server, use 0 TZ offset
if (!getLocalTime(&timeinfo)) {
Serial.println(" Failed to obtain time");
return;
}
Serial.println("OK, Got the time from NTP");
setTimezone(timezone); // then set your timezone
}
void printLocalTime() { // this function monitors current time of day to initiate
// pump counter reset at midnight
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
int time_hour = timeinfo.tm_hour; // tm structure element "hour" from time.h
int time_min = timeinfo.tm_min; // "minute" " "
int time_sec = timeinfo.tm_sec; // "second"
if (time_hour == hour_trigger && time_min == min_trigger && time_sec == sec_trigger) {
Serial.println("Reset counters...");
counter_reset = true;
delay(1000); // used to avoid conflict as time rolls over to new day
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z ");
}
// ***************** VOID SETUP ***************
void setup() {
delay(2000); // allow voltage stabilization on startup
startup_Millis = millis();
pinMode(ONBOARD_LED, OUTPUT); // Blink LED function
pinMode(Alarm_Relay, OUTPUT); // Alarm relay
pinMode(Pressure_Switch, INPUT); // Alarm Input
pinMode(Pump_Run_Status, INPUT); // Spare Dry Contacts on 220v pump contactor
pinMode(System_Reset, INPUT); // Reset/clear system alarms
digitalWrite(Alarm_Relay, LOW);
Serial.begin(115200);
while (WiFi.status() != WL_CONNECTED) {
Initial_Connect_Attempts++;
Serial.println("Attempting to Connect To Local Network: ");
Serial.println(wifissid);
WiFi.begin(wifissid, wifipass);
delay(4000);
if (Initial_Connect_Attempts == 5) {
Serial.println("5 LAN connect attempts unsuccessful; going to connectToWifi()");
connectToWiFi();
}
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Attempting to connect to local WPA network...");
initTime("CST6CDT,M3.2.0,M11.1.0"); // https://sites.google.com/a/usapiens.com/opnode/time-zones
server.begin();
// you're connected now, so print out the status:
Serial.print("WiFi Status: ");
Serial.println(WiFi.status());
Serial.println();
Serial.print("ESP Board MAC Address: ");
Serial.println(WiFi.macAddress());
DS18B20.begin(); // initialize the DS18B20 space sensor
}
void loop() {
printLocalTime(); // used to determine midnight reset of "daily" pump counters
current_Millis = millis();
DS18B20.requestTemperatures(); // send the command to get temperatures
space_temp_1 = DS18B20.getTempCByIndex(0); // read temperature in °C
sp_temp_1F = (space_temp_1 * 9 / 5) + 32; // convert C to F
sp_temp_1 = sp_temp_1F + tmp_adj_1; // sensor calibration
digitalWrite(ONBOARD_LED, HIGH); // Blink for run indicator
delay(200);
digitalWrite(ONBOARD_LED, LOW);
delay(400);
// ***************** Pump Run Time Monitor & Alarm/Report Function ********
pump_run_contacts = digitalRead(Pump_Run_Status); // spare set of contacts from 220 volt contactor
if (pump_run_contacts == HIGH) {
pump_ON = true;
strcpy(Pump_Status, "ON");
} else {
pump_ON = false;
strcpy(Pump_Status, "OFF");
}
if (pump_ON == true && pump_run_state == false) {
pump_ON_Millis = current_Millis;
pump_run_state = true;
}
if (pump_ON == true) {
current_pump_cycle = (current_Millis - pump_ON_Millis);
current_pump_cycle_sec = (current_pump_cycle / 1000);
current_pump_cycle_min = (current_pump_cycle_sec / minute);
// pump_runtime_hours = (pump_runtime_minutes / hour);
if (current_pump_cycle >= max_pump_runtime) {
pump_alarm = true;
}
}
if (pump_run_state == true && pump_ON == false) { // timestamp pump turning off
pump_OFF_Millis = current_Millis;
last_pump_cycle_Millis = pump_OFF_Millis - pump_ON_Millis;
last_pump_cycle_sec = (last_pump_cycle_Millis / 1000);
daily_run_Millis = (last_pump_cycle_Millis + daily_run_Millis);
daily_run_seconds = (daily_run_Millis / 1000);
daily_run_minutes = (daily_run_seconds / minute);
on_off_cycle_count = (++on_off_cycle_count);
pump_run_state = false;
current_pump_cycle_sec = 0;
current_pump_cycle_min = 0;
}
if (counter_reset == true) { // clear daily counters at midnight
daily_run_Millis = 0;
daily_run_seconds = 0;
daily_run_minutes = 0;
on_off_cycle_count = 0;
counter_reset = false;
}
if (pump_ON == false) {
pump_alarm = false;
// pump_run_state = false;
// current_pump_cycle = 0;
//
pump_ON_Millis = 0;
}
if (pump_alarm == true && pump_alarm_state == false) // check if pump has ran too long in a cycle
{ // AND alm state "was" false;
strcpy(Pump_Alm, "ON"); // this ensures alm is not repeatedly sent to API.
pump_alarm_state = true; // ie pump alarm has been reported
sendToPushingBox(DEVID3); // sendToPushingBox(DEVID3);
}
// ***************** Low Water Pressure Alarm Function ********
pressure_switch_state = digitalRead(Pressure_Switch); //Pressure Switch Input Pin Read
if (pressure_switch_state == HIGH) {
pressure_alarm = true;
} else {
pressure_alarm = false;
}
// ********************* If pressure alarm initiate API msg; turn on audible alarm **********
if (pressure_alarm == true && press_alarm_state == false) // check if pressure switch has changed state
{ // AND alm state "was" false; this ensures alm is not repeatedly sent to API.
press_alarm_state = true;
strcpy(Pressure_Alm, "ON");
sendToPushingBox(DEVID2);
}
if (pressure_alarm == false && press_alarm_state == true) // alarm condition cleared
{
press_alarm_state = false;
strcpy(Pressure_Alm, "OFF");
}
if (temp_alarm == true || pressure_alarm == true || pump_alarm == true) {
bldg_alarm_state = true;
strcpy(Bldg_Alarm, "ON");
if (DEBUG) {
Serial.println(" Building alarm state is true!!!! ");
} else {
bldg_alarm_state = false;
strcpy(Bldg_Alarm, "OFF");
}
}
if (bldg_alarm_state == true) {
digitalWrite(Alarm_Relay, HIGH);
strcpy(Alm_Relay, "ON");
if (DEBUG) { Serial.println(" Turn Horn ON & kill pump !!! "); }
} else {
digitalWrite(Alarm_Relay, LOW);
strcpy(Alm_Relay, "OFF");
}
// ***************** System Alarm Reset/Clear **************
alarm_reset = digitalRead(System_Reset); // switch input activated by human operator
if (alarm_reset == HIGH) {
bldg_alarm_state = false; // reset flags & audibles
strcpy(Bldg_Alarm, "OFF");
strcpy(Alm_Relay, "OFF");
pump_alarm = false;
strcpy(Pump_Alm, "OFF");
pump_alarm_state = false;
pressure_alarm = false;
temp_alarm = false;
pump_run_state = false;
// current_pump_cycle = 0;
// pump_ON_Millis = 0;
digitalWrite(Alarm_Relay, LOW);
delay(2000); // wait 20 seconds to allow pump time to rebuild line pressure
}
// ***************** Low Temp Alarm Function ***************
if (sp_temp_1 <= Low_Tmp_Alm) {
temp_alarm = true;
strcpy(Temp_Alm, "ON");
} else {
temp_alarm = false;
strcpy(Temp_Alm, "OFF");
}
if ((sp_temp_1 > Low_Tmp_Alm + 2) && temp_alarm == true) {
temp_alarm = false;
}
if (temp_alarm == true && temp_alarm_state == false) {
temp_alarm_state = true;
sendToPushingBox(DEVID1); // Send request to PushingBox ONCE when temp alm is true
}
if (temp_alarm == false && temp_alarm_state == true) // Temp alarm is OFF.
{
if (DEBUG) { Serial.println(" Pump House Temp Alarm is false / No message sent."); }
temp_alarm_state = false;
}
if (WiFi.status() != WL_CONNECTED && current_Millis - startup_Millis > wait_interval) // && millis() - last_Connection_Attempt_At_Ms > 15000ul )
{
WiFi.disconnect(); // last_Connection_Attempt_At_Ms = millis();
delay(2000);
WiFi.begin(wifissid, wifipass);
delay(4000);
restart_Flag = true;
connectToWiFi();
}
if (WiFi.status() == WL_CONNECTED && restart_Flag == true) {
restart_Flag = false;
startup_Millis = millis();
server.begin();
}
// ******************** WiFiWebServer Code***********
WiFiClient client = server.available(); // listen for incoming clients
if (client) {
Serial.println("new client");
// an http request ends with a blank line
currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n') // && currentLineIsBlank)
{
client.println();
client.println();
StackString<50> AString = StackString<50>(" Pump House");
client.println(AString.c_str());
StackString<50> BString = StackString<50>(" **********");
client.println(BString.c_str());
client.println();
client.println();
StackString<50> HString = StackString<50>(" Pump Status = ");
HString.append(Pump_Status);
client.println(HString.c_str());
client.println();
StackString<50> KString = StackString<50>(" Current Pump Cycle [seconds] = ");
KString.append(current_pump_cycle_sec);
client.println(KString.c_str());
client.println();
client.println();
StackString<50> LString = StackString<50>(" Current Pump Cycle [minutes] = ");
LString.append(current_pump_cycle_min);
client.println(LString.c_str());
client.println();
client.println();
StackString<50> MString = StackString<50>(" Last Pump Cycle [seconds] = ");
MString.append(last_pump_cycle_sec);
client.println(MString.c_str());
client.println();
client.println();
StackString<50> NString = StackString<50>("Daily Total Runtime [seconds] = ");
NString.append(daily_run_seconds);
client.println(NString.c_str());
client.println();
client.println();
StackString<50> PString = StackString<50>("Daily Total Runtime [minutes] = ");
PString.append(daily_run_minutes);
client.println(PString.c_str());
client.println();
client.println();
StackString<50> OString = StackString<50>(" Daily On-Off Cycles = ");
OString.append(on_off_cycle_count);
client.println(OString.c_str());
client.println();
client.println();
StackString<50> CString = StackString<50>(" Pump House Temp = ");
CString.append(sp_temp_1);
client.println(CString.c_str());
client.println();
client.println();
StackString<50> IString = StackString<50>(" Building Alarm = ");
IString.append(Bldg_Alarm);
client.println(IString.c_str());
client.println();
client.println();
StackString<50> JString = StackString<50>(" Audible Alarm/Pump Shutdown = ");
JString.append(Alm_Relay);
client.println(JString.c_str());
client.println();
client.println();
StackString<50> DString = StackString<50>(" Temp Alarm Setpoint = ");
DString.append(Low_Tmp_Alm);
client.println(DString.c_str());
client.println();
client.println();
StackString<50> EString = StackString<50>(" Low Temp Alarm = ");
EString.append(Temp_Alm);
client.println(EString.c_str());
client.println();
client.println();
StackString<50> FString = StackString<50>(" Low Pressure Alarm = ");
FString.append(Pressure_Alm);
client.println(FString.c_str());
client.println();
client.println();
StackString<50> GString = StackString<50>(" Pump Runtime Alarm = ");
GString.append(Pump_Alm);
client.println(GString.c_str());
break;
}
}
}
delay(3000); // give the web browser time to receive the data
client.stop(); // close the connection:
Serial.println("client disonnected");
}
// this write the response from PushingBox Server.
// You should see a "200 OK"
/* if (client.available())
{
char c = client.read();
if(DEBUG){Serial.print(c);}
}
*/
// if there's no net connection, but there was one last time
// through the loop, then stop the client:
if (!client.connected() && lastConnected) {
if (DEBUG) { Serial.println(); }
if (DEBUG) { Serial.println(" disconnecting"); }
client.stop();
}
lastConnected = client.connected();
}
// **************************** END OF VOID LOOP() ****************************************
void sendToPushingBox(char devid[]) // Function for sending the request to PushingBox
{
client.stop();
delay(2000);
if (DEBUG) { Serial.println(" connecting..."); }
if (client.connect(serverName, 80)) {
if (DEBUG) { Serial.println(" connected"); }
if (DEBUG) { Serial.println(" sending request to PushingBox API"); }
client.print("GET /pushingbox?devid=");
client.print(devid);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(serverName);
client.println("User-Agent: ESP32");
client.println();
} else {
if (DEBUG) { Serial.println(" connection failed"); }
}
}
void connectToWiFi() {
Try_Count = 0;
while (WiFi.status() != WL_CONNECTED) {
Try_Count++;
WiFi.disconnect();
WiFi.begin(wifissid, wifipass);
vTaskDelay(10000);
if (Try_Count == 10) {
Serial.println("..... 10 attempts failed....rebooting processor...");
ESP.restart(); // reboot processor!!!
}
}
// WiFi.onEvent( WiFiEvent ); > define WiFiEvent to do ???
}
constants.h:
OneWire oneWire(SENSOR_PIN);
DallasTemperature DS18B20(&oneWire);
int status = WL_IDLE_STATUS; // the Wifi radio's status
WiFiClient client;
WiFiServer server(80); // added for testing 2/4
int Initial_Connect_Attempts = 0;
int Try_Count = 0;
char wifissid[18] = "*******"; // "Homestead-LAN_EXT" for in house testing
char wifipass[13] = "******"; //
char DEVID1[] = "v5A61F203ED29211"; // token/key low temp alarm [ v5A61F203ED29211 ]
char DEVID2[] = "v9072310CAE86043"; // token/key low wtr pressure alarm [ v9072310CAE86043 ]
char DEVID3[] = "va71BBE853590654"; // pump runtime alarm [ va71BBE853590654 ]
static uint32_t startup_Millis = millis(); // static uint32_t last_Connection_Attempt_At_Ms = millis();
static uint32_t current_Millis = 0;
static uint32_t wait_interval = 300000; // 5 minutes of no wifi connection
signed long hour = 3600000; // 3,600,000 millis per hr
signed long minute = 60; // 60,000 millis per minute
static uint32_t pump_ON_Millis = 0;
static uint32_t pump_OFF_Millis = 0;
signed int last_pump_cycle_Millis = 0;
signed int last_pump_cycle_sec = 0;
signed int daily_run_Millis = 0;
signed int daily_run_seconds = 0;
signed int daily_run_minutes = 0;
signed int current_pump_cycle = 0;
signed int current_pump_cycle_sec = 0;
signed int current_pump_cycle_min = 0;
int on_off_cycle_count = 0;
static uint32_t max_pump_runtime = 300000; // 5 minutes maximum run time before an alarm*emphasized text*
static bool restart_Flag = false;
boolean DEBUG = true; // Debug mode !!!!
boolean currentLineIsBlank = false; //added 10/31/22 debugging
char serverName[19] = "api.pushingbox.com"; // [ api.pushingbox.com ]
// int keyIndex = 0; WiFi Communication Parameter NEEDED????
const int Alarm_Relay = 4; // Alarm Relay output pinMode(GIOP4/D2, OUTPUT)
int hour_trigger = 23; // hour to reset pump counters to zero
int min_trigger = 59; // minute (23 : 59 : 59)
int sec_trigger = 59; // second HR MIN SEC
boolean counter_reset = false;
boolean bldg_alm_ON = false;
boolean bldg_alarm_state = false;
boolean temp_alarm = false;
boolean temp_alarm_state = false;
boolean lastConnected = false;
boolean pump_ON = false;
boolean pump_run_state = false;
boolean pump_alarm = false;
// ************* Low Water Pressure Alm Parameters ***********
const int Pressure_Switch = 25; // Board Digital Input GIOP25; pinMode(GIOP#, INPUT);
const int Pump_Run_Status = 18; // Dig Input for pump run status
const int System_Reset = 21; // Reset/clear alarms switch input; GPIO21, D21
int pressure_switch_state = 0;
int alarm_reset = 0;
int pump_run_contacts = 0;
boolean pressure_alarm = false;
boolean press_alarm_state = false;
boolean pump_alarm_state = false;
// ***************** Low Temp Alarm Parameters ***************
char Pump_Status[4] = "OFF";
char Pump_Alm[4] = "OFF";
char Temp_Alm[4] = "OFF";
char Pressure_Alm[4] = "OFF";
char Alm_Relay[4] = "OFF";
char Bldg_Alarm[4] = "OFF";
// const int B = 4275; // B value of the thermistor; +- 275 = .6 C (1.0 F)
// const uint32_t R0 = 100000; // R0 = 100k; int type uint32_t required (unsigned 32 bit)
int tmp_adj_1 = 0; // sensor 1 calibration adjustment
float space_temp_1; // Dallas DS18B20 temp sensor
int sp_temp_1;
float sp_temp_1F;
int Low_Tmp_Alm = 38.00; // Low Alarm Setpoint
hashtag_includes.h:
#include <SPI.h>
#include <WiFi.h>
#include <math.h>
#include "time.h"
#include <StackString.hpp> // save memory using this function: character arrays
using namespace Stack;
// #include <DS18B20.h>
#include <OneWireNg.h>
#include <DallasTemperature.h>
#define SENSOR_PIN 14 // ESP32 pin GPIO14; D14 silkscreen connected to DS18B20
#define ONBOARD_LED 2