First working version

This commit is contained in:
Carsten Schmiemann 2022-09-03 05:04:57 +02:00
parent 829c70623d
commit 7cef59552e
7 changed files with 602 additions and 226 deletions

27
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,27 @@
{
"files.associations": {
"array": "cpp",
"*.tcc": "cpp",
"chrono": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"cmath": "cpp",
"fstream": "cpp",
"istream": "cpp",
"numeric": "cpp",
"ostream": "cpp",
"thread": "cpp",
"regex": "cpp",
"utility": "cpp"
}
}

View File

@ -14,8 +14,8 @@ board = ttgo-t-beam
framework = arduino
lib_deps =
knolleary/PubSubClient@^2.8
adafruit/Adafruit GFX Library@^1.11.3
adafruit/Adafruit SSD1306@^2.5.7
extentsoftware/TBeamPower@^2.0.4
peterus/esp-logger @ 0.0.1
bblanchon/ArduinoJson@^6.19.4
olikraus/U8g2@^2.33.12
monitor_speed = 115200

View File

@ -1,158 +1,151 @@
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
/*
; Project: ESP32 GLCD SOLAR MONITOR
; Date: 3rd Sep 2022
;
; (C) 2022 Carsten Schmiemann
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
#include <logger.h>
#include <Wire.h>
#include <U8g2lib.h>
#include "display.h"
#include "pins.h"
#include <display.h>
#include <screens.h>
#include <pins.h>
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
U8G2_SSD1306_128X64_VCOMH0_F_HW_I2C display(U8G2_R0, OLED_RST, OLED_SCL, OLED_SDA);
// cppcheck-suppress unusedFunction
void setup_display() {
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) {
logPrintlnE( "SSD1306 allocation failed");
while (true) {
}
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
void display_begin() {
display.begin();
}
// cppcheck-suppress unusedFunction
void display_toggle(bool toggle) {
logPrintlnI("Toggling display: ");
if (toggle) {
logPrintlnI("On");
display.ssd1306_command(SSD1306_DISPLAYON);
} else {
logPrintlnI("Off");
display.ssd1306_command(SSD1306_DISPLAYOFF);
}
void display_header() {
display.setFont(u8g2_font_10x20_tr);
display.drawStr(0,20,"PV Monitor");
display.drawStr(48,35,"Project");
display.setFont(u8g2_font_6x10_tr);
}
void display_init(char* VERSION) {
display.firstPage();
do {
display_header();
display.drawStr(0,52,"by Carsten Schmiemann");
display.drawStr(30,60,"2022");
display.print(VERSION);
} while ( display.nextPage() );
}
// cppcheck-suppress unusedFunction
void show_display(String header, int wait) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
void display_wifi(char* STATUS) {
display.firstPage();
do {
display_header();
display.drawStr(0,52,"Connecting wifi...");
display.drawStr(30,60, STATUS);
} while ( display.nextPage() );
}
// cppcheck-suppress unusedFunction
void show_display(String header, String line1, int wait) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
display.setTextSize(1);
display.setCursor(0, 16);
display.println(line1);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
void display_mqtt() {
display.firstPage();
do {
display_header();
display.drawStr(0,52,"Connect mqtt...");
} while ( display.nextPage() );
}
// cppcheck-suppress unusedFunction
void show_display(String header, String line1, String line2, int wait) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
display.setTextSize(1);
display.setCursor(0, 16);
display.println(line1);
display.setCursor(0, 26);
display.println(line2);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
void display_category_0() {
display.setFont(u8g2_font_6x10_tr);
display.drawStr(2,7,"PV-Module");
display.drawLine(0, 8, 128, 8);
display.drawLine(100, 0, 100, 8);
display.drawXBM(106,0, down_width, down_height, down_bits);
display.drawXBM(0,9, Solarpanel_width, Solarpanel_height, Solarpanel_bits);
}
// cppcheck-suppress unusedFunction
void show_display(String header, String line1, String line2, String line3, int wait) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
display.setTextSize(1);
display.setCursor(0, 16);
display.println(line1);
display.setCursor(0, 26);
display.println(line2);
display.setCursor(0, 36);
display.println(line3);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
void display_category_1() {
display.setFont(u8g2_font_6x10_tr);
display.drawStr(2,7,"Batterie");
display.drawLine(0, 8, 128, 8);
display.drawLine(100, 0, 100, 8);
display.drawXBM(106,0, down_width, down_height, down_bits);
display.drawXBM(116,0, up_width, up_height, up_bits);
display.drawXBM(7,9, battery_width, battery_height, battery_bits);
display.drawFrame(5,38,40,25);
}
// cppcheck-suppress unusedFunction
void show_display(String header, String line1, String line2, String line3, String line4, int wait) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
display.setTextSize(1);
display.setCursor(0, 16);
display.println(line1);
display.setCursor(0, 26);
display.println(line2);
display.setCursor(0, 36);
display.println(line3);
display.setCursor(0, 46);
display.println(line4);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
void display_category_2() {
display.setFont(u8g2_font_6x10_tr);
display.drawStr(2,7,"Netz");
display.drawLine(0, 8, 128, 8);
display.drawLine(100, 0, 100, 8);
display.drawXBM(116,0, up_width, up_height, up_bits);
display.drawXBM(0,9, grid_width, grid_height, grid_bits);
display.drawBox(6,18,40,10);
}
// cppcheck-suppress unusedFunction
void show_display(String header, String line1, String line2, String line3, String line4, String line5, int wait) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(header);
display.setTextSize(1);
display.setCursor(0, 16);
display.println(line1);
display.setCursor(0, 26);
display.println(line2);
display.setCursor(0, 36);
display.println(line3);
display.setCursor(0, 46);
display.println(line4);
display.setCursor(0, 56);
display.println(line5);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(1);
display.display();
delay(wait);
//PV Charger
void display_screen_0(float pv_voltage, float pv_wattage, float battery_voltage, float pv_amps, float pv_kwh)
{
logPrintlnD("Refresh display values...");
display.firstPage();
do {
display_category_0();
display.setCursor(72,18); display.print(pv_voltage); display.print("V");
display.setCursor(72,28); display.print(pv_wattage); display.print("W");
display.setCursor(72,38); display.print(pv_kwh); display.print("kWh");
display.setCursor(72,54); display.print(battery_voltage); display.print("V");
display.setCursor(72,64); display.print(pv_amps); display.print("A");
} while ( display.nextPage() );
}
//Battery
void display_screen_1(float battery_voltage, float battery_amps, float battery_wattage, float battery_soc)
{
logPrintlnD("Refresh display values...");
display.firstPage();
do {
display_category_1();
display.setCursor(72,18); display.print(battery_voltage); display.print("V");
display.setCursor(72,28); display.print(battery_amps); display.print("A");
display.setCursor(72,38); display.print(battery_wattage); display.print("W");
display.setFont(u8g2_font_inr19_mf);
display.setCursor(70,63); display.print(battery_soc,0); display.print("%");
int batt_fill_y = map(battery_soc, 0, 100, 63, 38);
int batt_fill_height = map(battery_soc, 0, 100, 0, 25);
display.drawBox(5,batt_fill_y,40,batt_fill_height);
} while ( display.nextPage() );
}
//Grid
void display_screen_2(float grid_power, float inv_power, float inv_current, float load_ph1, float load_ph2, float load_ph3)
{
logPrintlnD("Refresh display values...");
display.firstPage();
do {
display_category_2();
display.setDrawColor(0);
display.setCursor(10,26); display.print(grid_power,0); display.print("W");
display.setDrawColor(1);
display.setCursor(43,54); display.print(inv_power,0); display.print("W");
display.setCursor(43,64); display.print(inv_current,1); display.print("A");
float ac_load = load_ph1 + load_ph2 + load_ph3;
display.setCursor(89,22); display.print(ac_load,0); display.print("W");
} while ( display.nextPage() );
}

View File

@ -1,9 +1,33 @@
void setup_display();
void display_toggle(bool toggle);
void show_display(String header, int wait = 0);
void show_display(String header, String line1, int wait = 0);
void show_display(String header, String line1, String line2, int wait = 0);
void show_display(String header, String line1, String line2, String line3, int wait = 0);
void show_display(String header, String line1, String line2, String line3, String line4, int wait = 0);
void show_display(String header, String line1, String line2, String line3, String line4, String line5, int wait = 0);
/*
; Project: ESP32 GLCD SOLAR MONITOR
; Date: 3rd Sep 2022
;
; (C) 2022 Carsten Schmiemann
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
void display_begin();
void display_header();
void display_init(char* VERSION);
void display_wifi(char* STATUS);
void display_mqtt();
void display_category_0();
void display_screen_0(float pv_voltage, float pv_wattage, float battery_voltage, float pv_amps, float pv_kwh);
void display_screen_1(float battery_voltage, float battery_amps, float battery_wattage, float battery_soc);
void display_screen_2(float grid_power, float inv_power, float inv_current, float load_ph1, float load_ph2, float load_ph3);

View File

@ -1,59 +1,198 @@
/*
; Project: ESP32 GLCD SOLAR MONITOR
; Date: 3rd Sep 2022
;
; (C) 2022 Carsten Schmiemann
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include <logger.h>
#include <display.h>
#include <pins.h>
#include <power_management.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <U8g2lib.h>
//Program parts
#include <pins.h>
#include <screens.h>
#include <display.h>
#define VERSION "0.1a"
static const unsigned long DISPLAY_REFRESH_INTERVAL = 1000; // ms
static const unsigned long DISPLAY_SCREEN_INTERVAL = 10000; // ms
//Wifi Setup
const char* WIFI_SSID = "IoT_Temp";
const char* WIFI_PASS = "xyz";
const char* WIFI_PASS = "FpgtW6LMeZjmTH6J2KoSTTiE7rpEEhtfH8LaCjgFbajH2Bk88fkZFu9CopF96i";
const char* mqtt_server = "10.1.0.9";
//Library setup
WiFiClient espClient;
PubSubClient client(espClient);
//Globals
long lastMsg = 0;
char msg[50];
int value = 0;
float pv_v = 0, pv_a = 0, batt_v = 0, batt_i = 0, batt_p = 0, grid_p = 0, batt_soc = 0;
PowerManagement powerManagement;
float pv_v = 0, pv_w = 0, pv_i = 0, pv_kwh = 0, inv_p = 0, inv_i = 0, batt_v = 0, batt_i = 0, batt_p = 0, grid_p = 0, batt_soc = 0, temp_outside = 0, load_ph1 = 0, load_ph2 = 0, load_ph3 = 0;
int lastButtonState = HIGH;
int currentButtonState;
int display_screen = 0;
int display_last_screen = 2;
//MQTT topics
void callback(char* topic, byte* message, unsigned int length) {
logPrintlnD("Message arrived on topic: ");
logPrintlnD(topic);
logPrintlnD("Message: ");
byte messageTemp;
String messageTemp;
for (int i = 0; i < length; i++) {
messageTemp += message[i];
for (byte i = 0; i < length; i++) {
char tmp = char(message[i]);
messageTemp += tmp;
}
logPrintlnD(messageTemp);
//PV Charger - solar voltage
if (String(topic) == "N/48e7da87c8df/solarcharger/279/Pv/V") {
//pv_v = messageTemp.toFloat();
logPrintlnI((char*)messageTemp);
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
pv_v = json["value"];
}
//PV Charger - solar power
if (String(topic) == "N/48e7da87c8df/solarcharger/279/Yield/Power") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
pv_w = json["value"];
}
//PV Charger - solar yield
if (String(topic) == "N/48e7da87c8df/solarcharger/279/History/Daily/0/Yield") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
pv_kwh = json["value"];
}
//PV Charger - bat charge current
if (String(topic) == "N/48e7da87c8df/solarcharger/279/Dc/0/Current") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
pv_i = json["value"];
}
//Grid meter - power
if (String(topic) == "N/48e7da87c8df/grid/40/Ac/Power") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
grid_p = json["value"];
}
//Inverter - power
if (String(topic) == "N/48e7da87c8df/vebus/276/Ac/ActiveIn/L1/P") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
inv_p = json["value"];
}
//Inverter - current
if (String(topic) == "N/48e7da87c8df/vebus/276/Dc/0/Current") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
inv_i = json["value"];
}
//Battery - SOC
if (String(topic) == "N/48e7da87c8df/battery/512/Soc") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
batt_soc = json["value"];
}
//Battery - voltage
if (String(topic) == "N/48e7da87c8df/battery/512/Dc/0/Voltage") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
batt_v = json["value"];
}
//Battery - current
if (String(topic) == "N/48e7da87c8df/battery/512/Dc/0/Current") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
batt_i = json["value"];
}
//Battery - power
if (String(topic) == "N/48e7da87c8df/battery/512/Dc/0/Power") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
batt_p = json["value"];
}
//Temperature - outside
if (String(topic) == "N/48e7da87c8df/temperature/18/Temperature") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
temp_outside = json["value"];
}
//System - AC Load Phase 1
if (String(topic) == "N/48e7da87c8df/system/0/Ac/ConsumptionOnInput/L1/Power") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
load_ph1 = json["value"];
}
//System - AC Load Phase 2
if (String(topic) == "N/48e7da87c8df/system/0/Ac/ConsumptionOnInput/L2/Power") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
load_ph2 = json["value"];
}
//System - AC Load Phase 3
if (String(topic) == "N/48e7da87c8df/system/0/Ac/ConsumptionOnInput/L3/Power") {
DynamicJsonDocument json(512);
deserializeJson(json, messageTemp);
load_ph3 = json["value"];
}
}
//Wifi re-/connect
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
logPrintlnI("Attempting MQTT connection...");
show_display("PV Monitor", "MQTT Connection", "disconnected", "reconnecting...");
display_mqtt();
delay(1500);
// Attempt to connect
if (client.connect("PV_Solar_Monitor")) {
Serial.println("connected");
if (client.connect("PV_solar_monitor")) {
logPrintlnI("connected");
// Subscribe
client.subscribe("N/48e7da87c8df/solarcharger/279/Pv/V");
client.subscribe("N/48e7da87c8df/solarcharger/279/Yield/Power");
client.subscribe("N/48e7da87c8df/solarcharger/279/Yield/System");
client.subscribe("N/48e7da87c8df/solarcharger/279/History/Daily/0/Yield");
client.subscribe("N/48e7da87c8df/solarcharger/279/Dc/0/Current");
client.subscribe("N/48e7da87c8df/grid/40/Ac/Power");
client.subscribe("N/48e7da87c8df/vebus/276/Ac/ActiveIn/L1/P");
client.subscribe("N/48e7da87c8df/vebus/276/Dc/0/Current");
client.subscribe("N/48e7da87c8df/battery/512/Soc");
client.subscribe("N/48e7da87c8df/battery/512/Dc/0/Voltage");
client.subscribe("N/48e7da87c8df/battery/512/Dc/0/Current");
client.subscribe("N/48e7da87c8df/battery/512/Dc/0/Power");
client.subscribe("N/48e7da87c8df/temperature/18/Temperature");
client.subscribe("N/48e7da87c8df/system/0/Ac/ConsumptionOnInput/L1/Power");
client.subscribe("N/48e7da87c8df/system/0/Ac/ConsumptionOnInput/L2/Power");
client.subscribe("N/48e7da87c8df/system/0/Ac/ConsumptionOnInput/L3/Power");
} else {
logPrintlnE("failed, rc=");
logPrintlnE((char*)client.state());
@ -66,66 +205,71 @@ void reconnect() {
void setup() {
Serial.begin(115200);
logPrintlnI("Booting solar monitor app...");
logPrintlnI("Init power management...");
Wire.begin();
if (!powerManagement.begin(Wire)) {
logPrintlnI("AXP192 init done!");
} else {
logPrintlnE("AXP192 init failed!");
}
powerManagement.deactivateLoRa();
powerManagement.activateOLED();
powerManagement.deactivateGPS();
powerManagement.activateMeasurement();
logPrintlnI("Init display...");
setup_display();
show_display("PV Monitor", "is booting", "please wait", 3000);
display_begin();
display_init((char*)VERSION);
delay(2000);
logPrintlnI("Booting solar monitor app..." VERSION);
pinMode(BUTTON_PIN, INPUT_PULLUP);
logPrintlnI( "Set WLAN Mode to STA...");
WiFi.mode(WIFI_STA);
logPrintlnI("Resetting...");
WiFi.disconnect();
logPrintlnI("Connecting ...");
show_display("PV Monitor", "WiFi Connection", "connecting", "please wait", 500);
delay(1000);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Retry connection to WiFi..");
show_display("PV Monitor", "WiFi Connection", "retry connection", 500);
display_wifi((char*)"wait");
delay(500);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
IPAddress ip = WiFi.localIP();
char* ip_address = new char[40]();
sprintf(ip_address, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
show_display("PV Monitor", "WiFi Connection", "success", ip_address, 2000);
show_display("PV Monitor", "MQTT Connection", "connecting to cerbo", "please wait", 500);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
display_wifi(ip_address);
delay(2000);
}
void loop() {
static bool BatteryIsConnected = false;
static String batteryVoltage = "";
static String batteryChargeCurrent = "";
static unsigned int rate_limit_check_battery = 0;
if (!(rate_limit_check_battery++ % 60))
BatteryIsConnected = powerManagement.isBatteryConnect();
if (BatteryIsConnected) {
batteryVoltage = String(powerManagement.getBatteryVoltage(), 2);
batteryChargeCurrent = String(powerManagement.getBatteryChargeDischargeCurrent(), 0);
}
if (powerManagement.isChargeing()) {
powerManagement.enableChgLed();
} else {
powerManagement.disableChgLed();
}
if (!client.connected()) {
reconnect();
}
client.loop();
static unsigned long lastDispRefreshTime = 0;
static unsigned long lastScreenChangeTime = 0;
//Refresh display values
if(millis() - lastDispRefreshTime >= DISPLAY_REFRESH_INTERVAL)
{
lastDispRefreshTime += DISPLAY_REFRESH_INTERVAL;
if (display_screen == 0) {
display_screen_0(pv_v, pv_w, batt_v, pv_i, pv_kwh);
}
if (display_screen == 1) {
display_screen_1(batt_v, batt_i, batt_p, batt_soc);
}
if (display_screen == 2) {
display_screen_2(grid_p, inv_p, inv_i, load_ph1, load_ph2, load_ph3);
}
}
//Change screen after time
if(millis() - lastScreenChangeTime >= DISPLAY_SCREEN_INTERVAL)
{
display_screen++;
lastScreenChangeTime += DISPLAY_SCREEN_INTERVAL;
if (display_screen == display_last_screen + 1) {
display_screen = 0;
}
}
currentButtonState = digitalRead(BUTTON_PIN);
if(lastButtonState == LOW && currentButtonState == HIGH) {
display_screen++;
if (display_screen == display_last_screen + 1) {
display_screen = 0;
}
lastButtonState = currentButtonState;
}
}

View File

@ -1,17 +1,29 @@
#ifndef PINS_H_
#define PINS_H_
#undef OLED_SDA
#undef OLED_SCL
#undef OLED_RST
/*
; Project: ESP32 GLCD SOLAR MONITOR
; Date: 3rd Sep 2022
;
; (C) 2022 Carsten Schmiemann
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 16
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
#define GPS_RX 12
#define GPS_TX 34
#endif
#define BUTTON_PIN 38

176
src/screens.h Normal file
View File

@ -0,0 +1,176 @@
/*
; Project: ESP32 GLCD SOLAR MONITOR
; Date: 3rd Sep 2022
;
; (C) 2022 Carsten Schmiemann
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
#define Solarpanel_width 64
#define Solarpanel_height 56
static unsigned char Solarpanel_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x90, 0x0f,
0x08, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x10, 0x18, 0x00, 0x00, 0x00,
0xf0, 0x18, 0x0e, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x0e, 0xf0, 0x09, 0xe0,
0x21, 0x00, 0x00, 0x00, 0x02, 0x1e, 0x10, 0x78, 0x40, 0x00, 0x00, 0x00,
0x02, 0x02, 0x10, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x04, 0x03, 0xf0, 0x80,
0xf0, 0x00, 0x00, 0x00, 0xe4, 0x02, 0x38, 0x80, 0x0d, 0x01, 0x00, 0x00,
0x18, 0x84, 0x47, 0x80, 0x03, 0x01, 0x00, 0x00, 0x08, 0x6c, 0x40, 0x60,
0x01, 0xf2, 0x0f, 0x00, 0x10, 0x18, 0x80, 0x18, 0x82, 0x01, 0x10, 0x00,
0x10, 0x08, 0x80, 0x07, 0x64, 0x00, 0x20, 0x00, 0x10, 0x1e, 0xc0, 0x01,
0x1c, 0x00, 0x20, 0x00, 0xe0, 0x11, 0x30, 0x01, 0x06, 0x00, 0x20, 0x00,
0x20, 0x20, 0x0c, 0x82, 0x01, 0x00, 0x20, 0x00, 0x40, 0xa0, 0x03, 0x62,
0x00, 0x00, 0x20, 0x00, 0x40, 0xc0, 0x00, 0x1c, 0x00, 0xf0, 0xff, 0x3f,
0x80, 0x70, 0x00, 0x07, 0x00, 0x10, 0x00, 0x20, 0x80, 0x8c, 0x80, 0x01,
0x00, 0x10, 0x00, 0x20, 0x80, 0x83, 0x60, 0x00, 0x00, 0x90, 0x4b, 0x2f,
0x00, 0x00, 0x1d, 0x00, 0x00, 0x50, 0x48, 0x21, 0x00, 0x00, 0x07, 0x00,
0x00, 0x50, 0x48, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x78, 0x2d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x48, 0x29, 0x00, 0x00, 0x00, 0x00,
0x00, 0x50, 0x48, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x4b, 0x2f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0xe0, 0x01, 0x78,
0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x02, 0x84, 0x00, 0x10, 0x00, 0x20,
0x00, 0x10, 0x02, 0x84, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x20, 0x00,
0x80, 0x01, 0x00, 0x00, 0x18, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00,
0x10, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00,
0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00,
0x10, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x08, 0x20, 0x00,
0x80, 0x00, 0x00, 0x30, 0x10, 0x08, 0x20, 0x00, 0x80, 0x00, 0x00, 0x30,
0x10, 0x0c, 0x10, 0x00, 0x80, 0xf8, 0x03, 0xfc, 0x10, 0xfe, 0x0f, 0x00,
0x80, 0xf8, 0x03, 0xfc, 0x10, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x30,
0x10, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x30, 0x10, 0x08, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
#define battery_width 35
#define battery_height 27
static unsigned char battery_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xc0, 0x03, 0x00, 0x80, 0x10, 0x20, 0x04, 0x00, 0x80, 0x10, 0x20, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x7f, 0x00, 0x0c,
0x00, 0x00, 0xc0, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00,
0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00,
0x04, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x81, 0x00, 0x04, 0x00,
0x80, 0x81, 0x00, 0xc4, 0x1f, 0xe0, 0x87, 0x00, 0xc4, 0x1f, 0xe0, 0x87,
0x00, 0x04, 0x00, 0x80, 0x81, 0x00, 0x04, 0x00, 0x80, 0x81, 0x00, 0x04,
0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00,
0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00,
0x04, 0x00, 0x00, 0x80, 0x00, 0xf8, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00 };
#define grid_width 128
#define grid_height 58
static unsigned char grid_bits[] = {
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xc0,
0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0x90, 0x20, 0x60, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x1f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x90, 0x11, 0x81, 0x03, 0x00, 0x00,
0x08, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x1b,
0x01, 0x0e, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x07, 0x30, 0x8f, 0x01, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x0b,
0x00, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x10, 0x11, 0x00, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x20, 0x01, 0x40, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc0,
0x01, 0x00, 0x00, 0x00, 0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x08, 0xf8, 0xff, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00,
0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xc0,
0x18, 0x00, 0x00, 0x00, 0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0xd0, 0x20, 0x60, 0x00, 0x00, 0x00, 0x08, 0xf8, 0xff, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x90, 0x11, 0x81, 0x03, 0x00, 0x00,
0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x1b,
0x01, 0x0c, 0x00, 0x00, 0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x07, 0x30, 0x9f, 0x03, 0x3c, 0x80, 0x01, 0x08, 0xf8, 0xff, 0x0f,
0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x00,
0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x0b,
0x00, 0x40, 0x60, 0x00, 0x08, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x10, 0x11, 0x00, 0x40, 0x30, 0x00, 0x08, 0xf8, 0xff, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x20, 0x00, 0x40, 0xf8, 0xff,
0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc0,
0x01, 0x00, 0x30, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0xc0, 0x01, 0x00, 0x60, 0x00, 0x00, 0xf8, 0xff, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc0, 0x01, 0x00, 0xc0, 0x00,
0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc0,
0x01, 0x00, 0x80, 0x01, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x90, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, 0x00, 0x00,
0x00, 0xf8, 0xff, 0x0f, 0x00, 0x0f, 0xc0, 0x03, 0x00, 0x00, 0x10, 0x0b,
0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x80, 0x10, 0x20, 0x04,
0x00, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f,
0x80, 0x10, 0x20, 0x04, 0x00, 0x00, 0x10, 0x0a, 0x01, 0x00, 0x00, 0x00,
0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xf8, 0xff, 0xff, 0x7f,
0x00, 0x00, 0x90, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x0c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x50, 0x40, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x38, 0x80,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80,
0x00, 0x00, 0x38, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x38, 0x80, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x38, 0x80,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x80,
0x00, 0x00, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x04, 0x00, 0x80, 0x81, 0x00, 0x00, 0x88, 0x11, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x81, 0x00, 0x00, 0x08, 0x0b,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xc4, 0x1f, 0xe0, 0x87,
0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
0xc7, 0x1f, 0xe0, 0x87, 0x00, 0x00, 0x08, 0x1b, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x81, 0x00, 0x00, 0x88, 0x11,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x81,
0x00, 0x00, 0x40, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x2c, 0x80, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x1c, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80,
0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80,
0x00, 0x80, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf8, 0xff, 0xff, 0x7f };
#define up_width 7
#define up_height 7
static unsigned char up_bits[] = {
0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00 };
#define down_width 7
#define down_height 7
static unsigned char down_bits[] = {
0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x00 };