diff --git a/.pioenvs/.sconsign.dblite b/.pioenvs/.sconsign.dblite
index e53a203..a79c2f7 100644
Binary files a/.pioenvs/.sconsign.dblite and b/.pioenvs/.sconsign.dblite differ
diff --git a/.pioenvs/structure.hash b/.pioenvs/structure.hash
index 1f5e1ae..205dda6 100644
--- a/.pioenvs/structure.hash
+++ b/.pioenvs/structure.hash
@@ -1 +1 @@
-48395daee54e3878fbc0131b4ad59e5b91fe6378
\ No newline at end of file
+d0b2a87cf0a77e923379f54bea377ed7b8197882
\ No newline at end of file
diff --git a/data/index.html b/data/index.html
index 325a59d..2cab514 100644
--- a/data/index.html
+++ b/data/index.html
@@ -59,7 +59,7 @@
V
- /
+ V / V
|
@@ -73,7 +73,7 @@
A
- /
+ A / A
|
@@ -87,7 +87,7 @@
W
- /
+ W / W
|
diff --git a/src/PowerAnalyzer.ino b/src/PowerAnalyzer.ino
index 42606f8..a4796a3 100644
--- a/src/PowerAnalyzer.ino
+++ b/src/PowerAnalyzer.ino
@@ -28,6 +28,7 @@ Scheduler task;
Preferences nvs;
//Konstanten
+#define debug_serial
//Shunt Config - 60A / 60mV
#define R_SHUNT 0.001
#define V_SHUNT_MAX 0.060
@@ -49,7 +50,6 @@ Preferences nvs;
void lcd_print();
void lcd_init();
void lcd_header();
-void eeprom_save();
void i2c_receive();
void i2c_respond();
void readCurrent();
@@ -58,6 +58,7 @@ void read_button();
void web_measuring_stop(AsyncWebServerRequest *request);
void web_measuring_run(AsyncWebServerRequest *request);
void web_measuring_reset(AsyncWebServerRequest *request);
+void web_measuring_delete(AsyncWebServerRequest *request);
void web_get_values(AsyncWebServerRequest *request);
void data_logging();
@@ -73,9 +74,9 @@ float shuntvoltage_V = 0, shuntvoltage_mV = 0, busvoltage_V = 0, busvoltage_mV =
float busvoltage_V_max = 0, current_A_max = 0, power_W_max = 0, busvoltage_V_min = 0, current_A_min = 0, power_W_min = 0;
float Ah = 0, mAh = 0, Wh = 0, mWh = 0;
float battery_voltage, battery_average;
-int i_header = 0;
+int i_header = 0, battery_meas_init;
bool button1, button2, button3, button3long;
-bool lcd_light = true, lcd_minmax = false, lcd_cleared = true, wifi_enabled = true, test_mode = false;
+bool lcd_light = true, lcd_minmax = false, lcd_cleared = true, lcd_header_run = false, wifi_enabled = true, test_mode = false;
bool measuring_run = false, measuring_init = false, reset_actual = false, reset_minmax = false, battery_low = false, errorID = false;
unsigned long lastread = 0, tick, previousMillisReadData = 0, previousMillisDisplay = 0, data_timestamp = 0, button3timer = 0;
@@ -86,11 +87,12 @@ void setup() {
pinMode(button1_pin, INPUT_PULLUP);
pinMode(button2_pin, INPUT_PULLUP);
pinMode(button3_pin, INPUT_PULLUP);
- battery_average = analogRead(adc_battery_pin);
- //Setup Debug Serial
- Serial.begin(115200);
- Serial.println("Power Analyzer by Carsten Schmiemann (C) 2018");
+#ifdef debug_serial
+ //Setup Debug Serial
+ Serial.begin(115200);
+ Serial.println("Power Analyzer by Carsten Schmiemann (C) 2018");
+#endif
//Setup Over The Air - Update
ArduinoOTA
@@ -106,35 +108,71 @@ void setup() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("OTA Firmware Update");
- Serial.println("OTA Firmware Update");
+ #ifdef debug_serial
+ Serial.println("OTA Firmware Update");
+ #endif
lcd.setCursor(7,1);
lcd.print("Init");
- Serial.println("Init");
+ #ifdef debug_serial
+ Serial.println("Init");
+ #endif
})
.onEnd([]() {
lcd.setCursor(7,2);
lcd.print("Done.");
- Serial.println("Done.");
+ #ifdef debug_serial
+ Serial.println("Done.");
+ #endif
delay(5000);
ESP.restart();
})
.onProgress([](unsigned int progress, unsigned int total) {
lcd.setCursor(3,1);
lcd.print(progress / (total / 100)); lcd.print("% Complete");
- Serial.println(progress / (total / 100)); lcd.print("% Complete");
+ #ifdef debug_serial
+ Serial.println(progress / (total / 100)); lcd.print("% Complete");
+ #endif
})
.onError([](ota_error_t error) {
lcd.setCursor(3,3);
digitalWrite(led_error_pin, HIGH);
- if (error == OTA_AUTH_ERROR) {lcd.print("Auth Failed"); Serial.println("Auth Failed"); }
- else if (error == OTA_BEGIN_ERROR) {lcd.print("Begin Failed"); Serial.println("Auth Failed"); }
- else if (error == OTA_CONNECT_ERROR) {lcd.print("Connect Failed"); Serial.println("Connect Failed"); }
- else if (error == OTA_RECEIVE_ERROR) {lcd.print("Receive Failed"); Serial.println("Receive Failed"); }
- else if (error == OTA_END_ERROR) {lcd.print("End Failed"); Serial.println("End Failed"); }
+ if (error == OTA_AUTH_ERROR) {
+ lcd.print("Auth Failed");
+ #ifdef debug_serial
+ Serial.println("Auth Failed");
+ #endif
+ }
+ else if (error == OTA_BEGIN_ERROR) {
+ lcd.print("Begin Failed");
+ #ifdef debug_serial
+ Serial.println("Auth Failed");
+ #endif
+ }
+ else if (error == OTA_CONNECT_ERROR) {
+ lcd.print("Connect Failed");
+ #ifdef debug_serial
+ Serial.println("Connect Failed");
+ #endif
+ }
+ else if (error == OTA_RECEIVE_ERROR) {
+ lcd.print("Receive Failed");
+ #ifdef debug_serial
+ Serial.println("Receive Failed");
+ #endif
+ }
+ else if (error == OTA_END_ERROR) {
+ lcd.print("End Failed");
+ #ifdef debug_serial
+ Serial.println("End Failed");
+ #endif
+ }
});
ArduinoOTA.setPort(ota_port);
ArduinoOTA.setPassword(ota_pass);
ArduinoOTA.begin();
+ #ifdef debug_serial
+ Serial.println("OTA Update Init");
+ #endif
//Init LCD, Custom Chars and test LEDs
lcd.init();
@@ -152,7 +190,9 @@ void setup() {
lcd.print("Power Analyzer");
lcd.setCursor(6,2);
lcd.print("V0.36 Beta");
- Serial.println("V0.36 Beta");
+ #ifdef debug_serial
+ Serial.println("V0.36 Beta");
+ #endif
lcd.setCursor(7,3);
lcd.print("CS,2018");
lcd.write(1);
@@ -191,6 +231,9 @@ void setup() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("OTA Firmware Update");
+ #ifdef debug_serial
+ Serial.println("OTA Firmware Update Init");
+ #endif
lcd.setCursor(7,1);
lcd.print("Init");
})
@@ -253,6 +296,7 @@ void setup() {
server.on("/meas/run", HTTP_GET, web_measuring_run);
server.on("/meas/stop", HTTP_GET, web_measuring_stop);
server.on("/meas/reset", HTTP_GET, web_measuring_reset);
+ server.on("/meas/delete", HTTP_GET, web_measuring_delete);
server.on("/meas/values", HTTP_GET, web_get_values);
server.on("/datalog.csv", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/datalog.csv");
@@ -288,6 +332,13 @@ void setup() {
nvs.begin("usage", true);
Ah = nvs.getFloat("Ah");
Wh = nvs.getFloat("Wh");
+ busvoltage_V_max = nvs.getFloat("Voltage_Max");
+ busvoltage_V_min = nvs.getFloat("Voltage_Min");
+ current_A_max = nvs.getFloat("Current_Max");
+ current_A_min = nvs.getFloat("Current_Min");
+ power_W_max = nvs.getFloat("Power_Max");
+ power_W_min = nvs.getFloat("Power_Min");
+ data_timestamp = nvs.getFloat("Date_Timestamp");
nvs.end();
//Enable Tasks
t1.enable();
@@ -347,29 +398,34 @@ void lcd_print() {
} else {
if (lcd_cleared) {lcd_init();}
lcd.setCursor(0,1);
- if (current_A < 100 && current_A >= 10) {lcd.print(" ");} else if (current_A < 10 && current_A >= 0) {lcd.print(" ");};
- if (current_A > -100 && current_A <= -10) {lcd.print(" ");} else if (current_A > -10 && current_A < 0) {lcd.print(" ");};
+ if (current_A < 100 && current_A >= 10) {lcd.print(" ");} else if (current_A < 10 && current_A >= 0) {lcd.print(" ");}
+ if (current_A > -100 && current_A <= -10) {lcd.print(" ");} else if (current_A > -10 && current_A < 0) {lcd.print(" ");}
lcd.print(current_A);
lcd.setCursor(0,2);
- if (power_W < 1000 && power_W > 100) {lcd.print(" ");} else if (power_W < 100 && power_W >= 10) {lcd.print(" ");} else if (power_W < 10) {lcd.print(" ");};
+ if (power_W < 1000 && power_W >= 100) {lcd.print(" ");} else if (power_W < 100 && power_W >= 10) {lcd.print(" ");} else if (power_W < 10) {lcd.print(" ");}
lcd.print(power_W);
lcd.setCursor(0,3);
- if (busvoltage_V < 100 && busvoltage_V >= 10) {lcd.print(" ");} else if (busvoltage_V < 10) {lcd.print(" ");};
+ if (busvoltage_V < 100 && busvoltage_V >= 10) {lcd.print(" ");} else if (busvoltage_V < 10) {lcd.print(" ");}
lcd.print(busvoltage_V);
lcd.setCursor(11,1);
- if (Ah < 1000 && Ah > 100) {lcd.print(" ");} else if (Ah < 100 && Ah >= 10) {lcd.print(" ");} else if (Ah < 10) {lcd.print(" ");};
- if (Ah > -100 && Ah <= -10) {lcd.print(" ");} else if (Ah > -10 && Ah < 0) {lcd.print(" ");};
+ if (Ah < 1000 && Ah >= 100) {lcd.print(" ");} else if (Ah < 100 && Ah >= 10) {lcd.print(" ");} else if (Ah < 10 && Ah >= 0) {lcd.print(" ");}
+ if (Ah > -100 && Ah <= -10) {lcd.print(" ");} else if (Ah > -10 && Ah < 0) {lcd.print(" ");}
lcd.print(Ah);
lcd.setCursor(11,2);
- if (Wh < 1000 && Wh > 100) {lcd.print(" ");} else if (Wh < 100 && Wh >= 10) {lcd.print(" ");} else if (Wh < 10) {lcd.print(" ");};
+ if (Wh < 1000 && Wh > 100) {lcd.print(" ");} else if (Wh < 100 && Wh >= 10) {lcd.print(" ");} else if (Wh < 10) {lcd.print(" ");}
lcd.print(Wh);
+ //Wait seven battery check cylces before display battery voltage due adc noise
lcd.setCursor(14,3);
- if (battery_voltage > 3.4) {lcd.print(battery_voltage);} else {lcd.print("LOW ");}
+ if (battery_meas_init == 7) {
+ if (battery_voltage > 3.4) {lcd.print(battery_voltage);} else {lcd.print("LOW ");}
+ } else {
+ lcd.print("-.--");
+ }
}
}
@@ -395,7 +451,8 @@ void lcd_init() {
}
void lcd_header() {
- if (measuring_run && lcd_minmax == false) {
+ //"Animated" lcd header when running measurement
+ if (measuring_run && lcd_header_run && lcd_minmax == false) {
i_header++;
if (i_header == 1) {
lcd.setCursor(0,0);
@@ -423,13 +480,19 @@ void lcd_header() {
i_header = 0;
}
}
- //Flash Error LED
+ //Flash Error LED on error or batt low
if ((battery_low || errorID) && digitalRead(led_error_pin)) {
digitalWrite(led_error_pin, LOW);
} else if ((battery_low || errorID) && digitalRead(led_error_pin) == false) { digitalWrite(led_error_pin, HIGH); }
if (battery_low == false && errorID == false && digitalRead(led_error_pin)) {
digitalWrite(led_error_pin, LOW);
}
+ //Wait for "measuring run" Message before Updating animated LCD head line
+ if (measuring_run) {
+ lcd_header_run = true;
+ } else {
+ lcd_header_run = false;
+ }
}
void readCurrent() {
@@ -475,6 +538,7 @@ void readCurrent() {
power_W_min = power_W;
}
}
+ //Set measurements variables to zero if reset pressed
if (reset_actual) {
Ah = 0;
Wh = 0;
@@ -487,6 +551,7 @@ void readCurrent() {
current_A_min = 0;
power_W_min = 0;
}
+ //One time steps when measurement starts
if (measuring_run && measuring_init == false) {
busvoltage_V_max = 0;
current_A_max = 0;
@@ -494,16 +559,35 @@ void readCurrent() {
busvoltage_V_min = busvoltage_V;
current_A_min = current_A;
power_W_min = power_W;
+ lcd.setCursor(2,0);
+ lcd.print(" Measuring started ");
+ #ifdef debug_serial
+ Serial.println("Measuring start");
+ #endif
measuring_init = true;
}
+ //One time steps when measurement stops
if (measuring_run == false && measuring_init) {
nvs.begin("usage", false);
nvs.putFloat("Ah", Ah);
nvs.putFloat("Wh", Wh);
+ nvs.putFloat("Voltage_Max", busvoltage_V_max);
+ nvs.putFloat("Voltage_Min", busvoltage_V_min);
+ nvs.putFloat("Current_Max", current_A_max);
+ nvs.putFloat("Current_Min", current_A_min);
+ nvs.putFloat("Power_Max", power_W_max);
+ nvs.putFloat("Power_Min", power_W_min);
+ nvs.putFloat("Date_Timestamp", data_timestamp);
nvs.end();
+ lcd.setCursor(0,0);
+ lcd.print(" Measuring stopped ");
+ #ifdef debug_serial
+ Serial.println("Measuring stop");
+ #endif
measuring_init = false;
}
- if (busvoltage_V > 26 || current_A > 62) {
+ //Check if shunt is within operating parameters
+ if (busvoltage_V > 26 || current_A > 62 || busvoltage_V < 0 || current_A < -62) {
errorID = true;
measuring_run = false;
} else {
@@ -515,15 +599,18 @@ void readCurrent() {
void read_bat() {
battery_average += (analogRead(adc_battery_pin) - battery_average) * 0.3;
battery_voltage = map(battery_average,0,4096,0,440)/100.0;
- if (battery_voltage < 3.3 && battery_low == false) {
- battery_low = true;
- lcd.noBacklight();
- }
- if (battery_voltage > 3.6 && battery_low) {
- battery_low = false;
- digitalWrite(led_error_pin,LOW);
- lcd.backlight();
- }
+ //Wait seven battery check cylces before battery low warnings due adc noise
+ if (battery_meas_init == 7) {
+ if (battery_voltage < 3.3 && battery_low == false) {
+ battery_low = true;
+ lcd.noBacklight();
+ }
+ if (battery_voltage > 3.6 && battery_low) {
+ battery_low = false;
+ digitalWrite(led_error_pin,LOW);
+ lcd.backlight();
+ }
+ } else { battery_meas_init++; }
}
void read_button() {
@@ -581,20 +668,22 @@ void read_button() {
void web_measuring_stop(AsyncWebServerRequest *request) {
if (errorID == false) {measuring_run = false;}
- //request->send(200);
- request->send(SPIFFS, "/index.html");
-}
+ request->send(200);
+ }
void web_measuring_run(AsyncWebServerRequest *request) {
if (errorID == false) {measuring_run = true;}
- //request->send(200);
- request->send(SPIFFS, "/index.html");
+ request->send(200);
}
void web_measuring_reset(AsyncWebServerRequest *request) {
reset_actual = true;
- //request->send(200);
- request->send(SPIFFS, "/index.html");
+ request->send(200);
+}
+
+void web_measuring_delete(AsyncWebServerRequest *request) {
+ SPIFFS.remove("/datalog.csv");
+ request->send(200);
}
void web_get_values(AsyncWebServerRequest *request) {