Fix LCD Display, Add OTA

This commit is contained in:
Carsten Schmiemann 2018-08-29 23:37:34 +02:00
parent 3a6c1ca884
commit 222feef353
87 changed files with 201 additions and 55 deletions

4
.gitignore vendored
View File

@ -1,3 +1,5 @@
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/launch.json
.pioenvs
.piolibdeps

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
!<arch>

View File

@ -1 +0,0 @@
!<arch>

Binary file not shown.

Binary file not shown.

View File

@ -59,7 +59,7 @@
<span id="voltage"></span> V
</td>
<td>
---
<span id="shuntvoltage_V_min"></span> / <span id="shuntvoltage_V_max"></span>
</td>
</tr>
<tr class="table-active">
@ -73,7 +73,7 @@
<span id="current"></span> A
</td>
<td>
---
<span id="current_A_min"></span> / <span id="current_A_max"></span>
</td>
</tr>
<tr>
@ -87,7 +87,7 @@
<span id="power"></span> W
</td>
<td>
---
<span id="power_W_min"></span> / <span id="power_W_max"></span>
</td>
</tr>
<tr class="table-active">
@ -115,6 +115,7 @@
<span id="Wh"></span> Wh
</td>
<td>
---
</td>
</tr>
</tbody>
@ -141,7 +142,7 @@
</div>
</div>
</div>
<div>Build by Carsten Schmiemann (2018), Akku <span id="battery"></span> V, Status: <span id="run"></span></div>
<div><center>Build by Carsten Schmiemann (2018), Akku <span id="battery"></span> V, Status: <span id="run"></span></center></div>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/scripts.js"></script>

View File

@ -11,7 +11,13 @@
document.getElementById("Ah").innerHTML = values.Ah;
document.getElementById("Wh").innerHTML = values.Wh;
document.getElementById("battery").innerHTML = values.battery;
document.getElementById("run").innerHTML = values.run;
document.getElementById("run").innerHTML = values.run;
document.getElementById("shuntvoltage_V_max").innerHTML = values.shuntvoltage_V_max;
document.getElementById("shuntvoltage_V_min").innerHTML = values.shuntvoltage_V_min;
document.getElementById("current_A_max").innerHTML = values.current_A_max;
document.getElementById("current_A_min").innerHTML = values.current_A_min;
document.getElementById("power_W_max").innerHTML = values.power_W_max;
document.getElementById("power_W_min").innerHTML = values.power_W_min;
}
};
xhttp.open("GET", "/meas/values", true);

View File

@ -16,3 +16,5 @@ lib_deps = ArduinoINA219, Wire, EEPROM, TaskScheduler, LiquidCrystal_I2C, ESPAsy
board_build.partitions = partitions.csv
monitor_port = COM6
monitor_speed = 115200
upload_port = 10.11.0.44
upload_flags = "--port=1337 --auth=powerlyzer"

View File

@ -12,13 +12,15 @@
#include <ESPAsyncWiFiManager.h>
#include <SPIFFS.h>
#include <ESP8266FtpServer.h>
#include <ArduinoOTA.h>
//Library Config
LiquidCrystal_I2C lcd(0x27,20,4);
INA219 ina219;
AsyncWebServer server(80);
DNSServer dns;
FtpServer ftpSrv;
FtpServer ftpSrv;
Scheduler task;
//Konstanten
#define R_SHUNT 0.001
@ -49,6 +51,14 @@ void web_measuring_reset(AsyncWebServerRequest *request);
void web_get_values(AsyncWebServerRequest *request);
void data_logging();
//Task Scheduler
Task t1(500, TASK_FOREVER, &lcd_print);
Task t2(1750, TASK_FOREVER, &lcd_header);
Task t3(10000, TASK_FOREVER, &read_bat);
Task t4(300, TASK_FOREVER, &read_button);
Task t5(30000, TASK_FOREVER, &data_logging);
//Task t3(60000, TASK_FOREVER, &eeprom_save);
//Globale Variablen
float shuntvoltage_V = 0, shuntvoltage_mV = 0, busvoltage_V = 0, busvoltage_mV = 0, current_A = 0, current_mA = 0, power_W = 0, power_mW = 0;
float shuntvoltage_V_max = 0, current_A_max = 0, power_W_max = 0, shuntvoltage_V_min = 0, current_A_min = 0, power_W_min = 0;
@ -56,8 +66,8 @@ float Ah = 0, mAh = 0, Wh = 0, mWh = 0;
float battery_voltage, battery_average;
int i_header = 0;
bool button1, button2, button3;
bool lcd_light = true, wifi_enabled = true;
bool measuring_run = false, reset_actual = false, reset_minmax =false, battery_low = false;
bool lcd_light = true, wifi_enabled = true, test_mode = false;
bool measuring_run = false, measuring_init = false, reset_actual = false, reset_minmax =false, battery_low = false;
unsigned long lastread = 0;
unsigned long tick;
unsigned long previousMillisReadData = 0;
@ -99,16 +109,6 @@ byte batterie[8] = {
0b11111
};
//Task Scheduler
Task t1(500, TASK_FOREVER, &lcd_print);
Task t2(1750, TASK_FOREVER, &lcd_header);
Task t3(10000, TASK_FOREVER, &read_bat);
Task t4(300, TASK_FOREVER, &read_button);
Task t5(30000, TASK_FOREVER, &data_logging);
//Task t3(60000, TASK_FOREVER, &eeprom_save);
Scheduler task;
void setup() {
//Setup GPIO
pinMode(led_lowbat_pin, OUTPUT);
@ -122,6 +122,46 @@ void setup() {
Serial.begin(115200);
Serial.println("Power Analyzer by Carsten Schmiemann (C) 2018");
//Setup Over The Air - Update
ArduinoOTA
.onStart([]() {
//Disable Tasks
t1.disable();
t2.disable();
t3.disable();
t4.disable();
t5.disable();
SPIFFS.end();
String type;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("OTA Firmware Update");
lcd.setCursor(7,1);
lcd.print("Init");
})
.onEnd([]() {
lcd.setCursor(7,2);
lcd.print("Done.");
delay(5000);
ESP.restart();
})
.onProgress([](unsigned int progress, unsigned int total) {
lcd.setCursor(3,1);
lcd.print(progress / (total / 100)); lcd.print("% Complete");
})
.onError([](ota_error_t error) {
lcd.setCursor(3,3);
lcd.print("Done.");
if (error == OTA_AUTH_ERROR) lcd.print("Auth Failed");
else if (error == OTA_BEGIN_ERROR) lcd.print("Begin Failed");
else if (error == OTA_CONNECT_ERROR) lcd.print("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) lcd.print("Receive Failed");
else if (error == OTA_END_ERROR) lcd.print("End Failed");
});
ArduinoOTA.setPort(1337);
ArduinoOTA.setPassword("powerlyzer");
ArduinoOTA.begin();
//Init LCD and Custom Chars
lcd.init();
lcd.backlight();
@ -138,7 +178,7 @@ void setup() {
lcd.print("Power Analyzer");
lcd.setCursor(7,1);
//lcd.print("Tracker");
lcd.setCursor(5,2);
lcd.setCursor(6,2);
lcd.print("V0.29 Beta");
lcd.setCursor(7,3);
lcd.print("CS,2018");
@ -178,17 +218,66 @@ void setup() {
wifi_enabled = false;
}
//Setup Over The Air - Update
ArduinoOTA
.onStart([]() {
//Disable Tasks
t1.disable();
t2.disable();
t3.disable();
t4.disable();
t5.disable();
SPIFFS.end();
String type;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("OTA Firmware Update");
lcd.setCursor(7,1);
lcd.print("Init");
})
.onEnd([]() {
lcd.setCursor(7,2);
lcd.print("Done.");
delay(5000);
ESP.restart();
})
.onProgress([](unsigned int progress, unsigned int total) {
lcd.setCursor(3,1);
lcd.print(progress / (total / 100)); lcd.print("% Complete");
})
.onError([](ota_error_t error) {
lcd.setCursor(3,3);
lcd.print("Done.");
if (error == OTA_AUTH_ERROR) lcd.print("Auth Failed");
else if (error == OTA_BEGIN_ERROR) lcd.print("Begin Failed");
else if (error == OTA_CONNECT_ERROR) lcd.print("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) lcd.print("Receive Failed");
else if (error == OTA_END_ERROR) lcd.print("End Failed");
});
if (wifi_enabled) {
ArduinoOTA.setPort(1337);
ArduinoOTA.setPassword("powerlyzer");
ArduinoOTA.begin();
}
//Init ina219s
lcd.setCursor(0,1);
lcd.print("Init Sensors...");
ina219.begin();
ina219.configure(INA219::RANGE_16V, INA219::GAIN_2_80MV, INA219::ADC_16SAMP, INA219::ADC_16SAMP, INA219::CONT_SH_BUS);
lastread = millis();
ina219.calibrate(R_SHUNT, V_SHUNT_MAX, V_BUS_MAX, I_MAX_EXPECTED);
delay(300);
lcd.setCursor(16,1);
lcd.print("Done");
delay(200);
lcd.setCursor(0,1);
lcd.print("Init Sensors...");
if (digitalRead(button1_pin)) {
ina219.begin();
ina219.configure(INA219::RANGE_16V, INA219::GAIN_2_80MV, INA219::ADC_16SAMP, INA219::ADC_16SAMP, INA219::CONT_SH_BUS);
lastread = millis();
ina219.calibrate(R_SHUNT, V_SHUNT_MAX, V_BUS_MAX, I_MAX_EXPECTED);
delay(300);
lcd.setCursor(16,1);
lcd.print("Done");
delay(200);
} else {
lcd.setCursor(16,1);
lcd.print("Test");
test_mode = true;
delay(500);
}
//Init Task Scheduler
lcd.setCursor(0,2);
@ -199,10 +288,6 @@ void setup() {
task.addTask(t3);
task.addTask(t4);
task.addTask(t5);
t2.enable();
t3.enable();
t4.enable();
t5.enable();
//Init Filesystem and Webserver
SPIFFS.begin();
server.on("/meas/run", HTTP_GET, web_measuring_run);
@ -229,39 +314,75 @@ void setup() {
lcd.clear();
lcd.setCursor(6,1);
lcd.print("IP address");
lcd.setCursor(5,2);
lcd.setCursor(6,2);
lcd.print(WiFi.localIP());
delay(1500);
}
//Load Default Screen
lcd_init();
//Enable Tasks
t1.enable();
t2.enable();
t3.enable();
t4.enable();
t5.enable();
}
void loop() {
//Exec TaskScheduler
task.execute();
ftpSrv.handleFTP();
ArduinoOTA.handle();
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillisReadData) >= 250) {
previousMillisReadData = millis();
if (test_mode) {
if (digitalRead(button1_pin)) {
shuntvoltage_V += 1;
power_W += 1;
current_A += 1;
Ah += 1;
Wh += 1;
}
if (digitalRead(button2_pin)) {
shuntvoltage_V -= 1;
power_W -= 1;
current_A -= 1;
Ah -= 1;
Wh -= 1;
}
} else {
readCurrent();
}
}
}
void lcd_print() {
if (busvoltage_V > 10) {lcd.setCursor(1,3);} else if (busvoltage_V < 0) {lcd.setCursor(1,3);} else {lcd.setCursor(1,3); lcd.print(" ");}
lcd.print(busvoltage_V);
if (current_A > 10) {lcd.setCursor(1,1);} else if (current_A < 0) {lcd.setCursor(1,1);} else {lcd.setCursor(1,1); lcd.print(" ");}
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(" ");};
lcd.print(current_A);
lcd.setCursor(0,2);
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);
if (Ah > 10) {lcd.setCursor(13,1);} else if (Ah < 0){lcd.setCursor(11,1);} else {lcd.setCursor(11,1); lcd.print(" ");}
lcd.setCursor(0,3);
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(" ");};
lcd.print(Ah);
if (Wh > 10) {lcd.setCursor(13,2);} else if (Wh < 0){lcd.setCursor(11,2);} else {lcd.setCursor(11,2); lcd.print(" ");}
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(" ");};
lcd.print(Wh);
lcd.setCursor(15,3);
lcd.setCursor(14,3);
if (battery_voltage > 3.4) {lcd.print(battery_voltage);} else {lcd.print("LOW ");}
}
@ -275,13 +396,13 @@ void lcd_init() {
lcd.print("W");
lcd.setCursor(7,3);
lcd.print("V");
lcd.setCursor(17,1);
lcd.setCursor(18,1);
lcd.print("Ah");
lcd.setCursor(17,2);
lcd.setCursor(18,2);
lcd.print("Wh");
lcd.setCursor(14,3);
lcd.setCursor(13,3);
lcd.write((uint8_t)2);
lcd.setCursor(19,3);
lcd.setCursor(18,3);
lcd.print("V");
delay(300);
}
@ -420,13 +541,22 @@ void readCurrent() {
current_A_min = 0;
power_W_min = 0;
}
if (measuring_run && measuring_init == false) {
shuntvoltage_V_max = 0;
current_A_max = 0;
power_W_max = 0;
shuntvoltage_V_min = shuntvoltage_V;
current_A_min = current_A;
power_W_min = power_W;
measuring_init = true;
}
lastread = newtime;
ina219.recalibrate();
ina219.reconfig();
}
void read_bat() {
battery_average += (analogRead(adc_battery_pin) - battery_average) * 0.1;
battery_average += (analogRead(adc_battery_pin) - battery_average) * 0.3;
battery_voltage = map(battery_average,0,4096,0,450)/100.0;
if (battery_voltage < 3.3 && battery_low == false) {
battery_low = true;
@ -458,10 +588,10 @@ void read_button() {
else {
button3 = true;
}
if (button1) {
if (button1 && test_mode == false) {
reset_actual = true;
}
if (button2 && measuring_run) {
if (button2 && measuring_run && test_mode == false) {
measuring_run = false;
} else if (button2 && measuring_run == false) {
measuring_run = true;
@ -496,17 +626,24 @@ void web_measuring_reset(AsyncWebServerRequest *request) {
}
void web_get_values(AsyncWebServerRequest *request) {
request->send( 200, "application/json", "{\"voltage\":" + String(busvoltage_V) + ", \"current\":" + String(current_A) + ", \"power\":" + String(power_W) + ", \"Ah\":" + String(Ah) + ", \"Wh\":" + String(Wh) + ", \"battery\":" + String(battery_voltage) + ", \"run\":" + String(measuring_run) + ", \"run\":" + String(shuntvoltage_V_max) + ", \"run\":" + String(shuntvoltage_V_min) + ", \"run\":" + String(current_A_max) + ", \"run\":" + String(current_A_min) + ", \"run\":" + String(power_W_max) + ", \"run\":" + String(power_W_min) + "}");
String web_status;
if (measuring_run) {
web_status = "Running";
}
else {
web_status = "Stopped";
}
request->send( 200, "application/json", "{\"voltage\":" + String(busvoltage_V) + ", \"current\":" + String(current_A) + ", \"power\":" + String(power_W) + ", \"Ah\":" + String(Ah) + ", \"Wh\":" + String(Wh) + ", \"battery\": " + String(battery_voltage) + ", \"run\":\"" + String(web_status) + "\", \"shuntvoltage_V_max\":" + String(shuntvoltage_V_max) + ", \"shuntvoltage_V_min\":" + String(shuntvoltage_V_min) + ", \"current_A_max\":" + String(current_A_max) + ", \"current_A_min\":" + String(current_A_min) + ", \"power_W_max\":" + String(power_W_max) + ", \"power_W_min\":" + String(power_W_min) + "}");
}
void data_logging() {
if (measuring_run) {
if (measuring_run && test_mode == false) {
File datalog = SPIFFS.open("/datalog.csv", "a");
datalog.print(data_timestamp); datalog.print(',');
datalog.print(busvoltage_V); datalog.print(',');
datalog.print(current_A); datalog.print(',');
datalog.println(power_W); datalog.print(',');
datalog.println(Ah); datalog.print(',');
datalog.print(power_W); datalog.print(',');
datalog.print(Ah); datalog.print(',');
datalog.println(Wh);
datalog.close();
data_timestamp++;