Compare commits

...

13 Commits

10 changed files with 108 additions and 58 deletions

BIN
docs/Breadboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
docs/NodeMCU v3 Pinout.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
docs/Screen_Battery.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
docs/Screen_Grid_InvOff.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
docs/Screen_Grid_InvOn.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
docs/Screen_PV.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
docs/Wifi Manager.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -51,8 +51,8 @@ void display_header() {
void display_header_small() {
display.setFont(u8g2_font_6x10_tr);
display.drawStr(40,7,"PV Monitor Project");
display.drawLine(0, 8, 128, 8);
display.drawStr(10,7,"PV Monitor Project");
display.drawLine(0, 10, 128, 10);
}
void display_init(char* VERSION) {
@ -60,8 +60,8 @@ void display_init(char* VERSION) {
do {
display_header();
display.drawStr(0,52,"by Carsten Schmiemann");
sprintf(screenbuffer, "(C) 2022 %s", VERSION);
display.drawStr(40,60,screenbuffer);
display.drawStr(20,60, "(C) 2022");
display.drawStr(76,60, VERSION);
} while ( display.nextPage() );
}

View File

@ -22,16 +22,19 @@
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
#include <Arduino.h>
//#include <Arduino.h>
#include <logger.h>
#ifdef ESP32
#include <SPIFFS.h>
#define Flash SPIFFS
#include <WiFi.h>
#endif
#ifdef ESP8266
#include <FS.h>
#include <LittleFS.h>
#define Flash LittleFS
#include <ESP8266WiFi.h>
#endif
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
@ -44,7 +47,7 @@
#include <pins.h>
#include <display.h>
static String VERSION = "0.5b";
char VERSION[6] = "v0.5b";
//Defaults
char mqtt_server[15] = "";
@ -95,8 +98,8 @@ PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
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, batt_c_min = 0, batt_c_max = 0, grid_p = 0, batt_soc = 0, temp_outside = 0, load_ph1 = 0, load_ph2 = 0, load_ph3 = 0;
int lastButtonState = HIGH;
int currentButtonState;
bool lastButtonRotationState = HIGH, lastButtonSetupState = HIGH;
bool currentButtonRotationState, currentButtonSetupState;
int display_screen = 0;
int display_last_screen = 2;
@ -107,6 +110,9 @@ void callback(char* topic, byte* message, unsigned int length) {
logPrintlnD("Message: ");
String messageTemp;
//Status LED flash on receive
digitalWrite(STATUS_LED, !digitalRead(STATUS_LED));
for (byte i = 0; i < length; i++) {
char tmp = char(message[i]);
messageTemp += tmp;
@ -227,7 +233,7 @@ void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
logPrintlnI("Attempting MQTT connection...");
display_text((char*)"Connect to GX MQTT..", mqtt_server);
display_text((char*)"Connect to GX MQTT...", mqtt_server);
delay(2000);
// Attempt to connect
if (client.connect("PV_solar_monitor")) {
@ -254,9 +260,10 @@ void reconnect() {
} else {
logPrintlnE("failed, rc=");
logPrintlnE((char*)client.state());
logPrintlnE(" try again in 5 seconds");
display_text((char*)"MQTT Error, rc", (char*)client.state());
// Wait 5 seconds before retrying
logPrintlnE(" try again in 10 seconds");
String msg = " MQTT Error rc=" + (String)client.state();
display_text_fullscreen((char*)"MQTT Connection Error", (char*)"Did you enable MQTT", (char*)"on your GX device?", (char*)msg.c_str(), (char*)"", (char*)"Retry in 10 seconds...");
// Wait 10 seconds before retrying
delay(5000);
}
}
@ -265,21 +272,23 @@ void reconnect() {
void setup() {
Serial.begin(115200);
Serial.println("Booting...");
pinMode(BUTTON_ROTATION, INPUT_PULLUP);
pinMode(BUTTON_SETUP, INPUT_PULLUP);
pinMode(STATUS_LED, OUTPUT);
display_begin();
Serial.println("Display init...");
display_init((char*)VERSION);
display_init(VERSION);
delay(2000);
display_text_fullscreen((char*)"Test1", (char*)"Test2", (char*)"Test3", (char*)"Test4", (char*)"Test5", (char*)"Test6");
delay(2000);
//read configuration from FS json
Serial.println("mounting FS...");
if (SPIFFS.begin()) {
//read configuration from Flash json
Serial.println("mounting Flash...");
if (Flash.begin()) {
Serial.println("mounted file system");
if (SPIFFS.exists("/config.json")) {
if (Flash.exists("/config.json")) {
//file exists, reading and loading
Serial.println("reading config file");
File configFile = SPIFFS.open("/config.json", "r");
File configFile = Flash.open("/config.json", "r");
if (configFile) {
Serial.println("opened config file");
size_t size = configFile.size();
@ -316,13 +325,21 @@ void setup() {
}
}
} else {
Serial.println("failed to mount FS");
Serial.println("failed to mount Flash");
}
delay(2000);
//logPrintlnI(printf("Booting solar monitor app... %s", VERSION));
logPrintlnI("Booting solar monitor app..." + VERSION);
display_text((char*)"Connect to AP:PV_MON", (char*)" for configuration");
String bootmsg = "Booting solar monitor app..." + (String)VERSION;
logPrintlnI(bootmsg.c_str());
display_text((char*)"Connect to AP:PV_Mon", (char*)" for configuration");
#ifdef ESP8266
WiFi.hostname("ESP_Solar_Monitor");
#endif
#ifdef ESP32
WiFi.setHostname("ESP_Solar_Monitor");
#endif
//Wifi Manager parameters
WiFiManagerParameter custom_mqtt_server("mqtt_server", "IP adress of GX Device (MQTT No SSL)", mqtt_server, 15);
WiFiManagerParameter custom_gx_vrm_id("gx_vrm_id", "VRM ID of GX device", gx_vrm_id, 20);
@ -345,10 +362,19 @@ void setup() {
wm.addParameter(&custom_address_inverter);
wm.addParameter(&custom_address_battery);
wm.addParameter(&custom_address_outside_temperature);
wm.setTimeout(60);
wm.autoConnect("PV_Mon");
display_text((char*)" Connecting wifi...", "");
//Start wifi manager configuration if BUTTON_SETUP is pressed on start-up
currentButtonSetupState = digitalRead(BUTTON_SETUP);
if(lastButtonSetupState == HIGH && currentButtonSetupState == LOW)
{
display_text((char*)"Connect to AP:PV_Mon", (char*)"for re-configuration");
wm.startConfigPortal("PV_Mon");
} else
{
wm.autoConnect("PV_Mon");
}
display_text((char*)" Connecting wifi...", (char*)"");
delay(500);
logPrintlnI("Connecting wifi...");
IPAddress ip = WiFi.localIP();
@ -370,7 +396,7 @@ void setup() {
char* ip_address = new char[40]();
sprintf(ip_address, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
display_text((char*)" Connected. IP:", ip_address);
//save the custom parameters to FS
//save the custom parameters to Flash
if (shouldSaveConfig) {
Serial.println("saving config");
#if defined(ARDUINOJSON_VERSION_MAJOR) && ARDUINOJSON_VERSION_MAJOR >= 6
@ -389,7 +415,7 @@ void setup() {
json["address_battery"] = address_battery;
json["address_outside_temperature"] = address_outside_temperature;
File configFile = SPIFFS.open("/config.json", "w");
File configFile = Flash.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
@ -450,29 +476,21 @@ void setup() {
Serial.print("gx_vrm_id: "); Serial.println(gx_vrm_id);
Serial.print("disp_refresh_interval: "); Serial.println(DISPLAY_REFRESH_INTERVAL);
Serial.print("disp_screen_interval: "); Serial.println(DISPLAY_SCREEN_INTERVAL);
display_text((char*)"Config: MQTT Server", mqtt_server);
delay(1500);
display_text((char*)"Config: GX VRM-ID", gx_vrm_id);
delay(1500);
display_text((char*)"Config: LCD Refresh", disp_refresh_interval);
delay(1500);
display_text((char*)"Config: LCD Rotation", disp_screen_interval);
delay(1500);
display_text_fullscreen((char*)"Configuration summary", (char*)"GX MQTT Server IP:", mqtt_server, (char*)"GX VRM ID:", gx_vrm_id, (char*)" 1/2");
delay(3000);
display_text_fullscreen((char*)"Configuration summary", (char*)"Disp. Refresh:", disp_refresh_interval, (char*)"Disp. rotation:", disp_screen_interval, (char*)" 2/2");
delay(3000);
}
void loop() {
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;
digitalWrite(STATUS_LED, LOW); //Turn Status LED ON again
lastDispRefreshTime += DISPLAY_REFRESH_INTERVAL;
if (display_screen == 0) {
display_screen_0(pv_v, pv_w, batt_v, pv_i, pv_kwh);
}
@ -484,21 +502,50 @@ void loop() {
}
}
//Change screen after time
if(millis() - lastScreenChangeTime >= DISPLAY_SCREEN_INTERVAL)
{
//Change screen after time if intervall setting not zero
if (DISPLAY_SCREEN_INTERVAL != 0)
{
if(millis() - lastScreenChangeTime >= DISPLAY_SCREEN_INTERVAL)
{
display_screen++;
lastScreenChangeTime += DISPLAY_SCREEN_INTERVAL;
if (display_screen == display_last_screen + 1)
{
//If no pv power generated, skip PV charger screen
if (pv_kwh == 0)
{
display_screen = 1;
}
else
{
display_screen = 0;
}
}
}
}
//Rotate screen if BUTTON_ROTATION is pressed
currentButtonRotationState = digitalRead(BUTTON_ROTATION);
if(lastButtonRotationState == HIGH && currentButtonRotationState == LOW)
{
display_screen++;
lastScreenChangeTime += DISPLAY_SCREEN_INTERVAL;
if (display_screen == display_last_screen + 1) {
display_screen = 0;
if (display_screen == display_last_screen + 1)
{
//If no pv power generated, skip PV charger screen
if (pv_kwh == 0)
{
display_screen = 1;
}
else
{
display_screen = 0;
}
}
}
currentButtonState = digitalRead(BUTTON_PIN);
if(lastButtonState == LOW && currentButtonState == HIGH) {
display_screen++;
if (display_screen == display_last_screen + 1) {
display_screen = 0;
lastButtonRotationState = currentButtonRotationState;
}
lastButtonState = currentButtonState;
if (!client.connected()) {
reconnect();
}
client.loop();
}

View File

@ -27,4 +27,7 @@
#define LCD_RW_SI 13
#define LCD_CS 15
#define BUTTON_PIN 6
#define STATUS_LED 2
#define BUTTON_ROTATION 3
#define BUTTON_SETUP 4