Hallöchen zusammen,
ich weiss, ich weiss, es gibt den "Zeigt her eure geilen Projekte"-Thread. Ich möchte diesen Thread aber auch nutzen um Probleme zu diskutieren. Es gibt ja im Wohnmobilsektor alles zum kaufen was man sich vorstellt....aber die Preis sind jenseits von gut und Böse. Also was macht der geneigt Bastler: selber bauen. So kam auch dieses Projekt zustande. Erst mal zur Hardware:
- Herzstück ist ein Arduino Mega (vorallem wegen der seriellen Ports)
- Ein BME280 Sensor für Temperatur, Feuchtigkeit und Luftdruck (letzterer für die Wettervorhersage)
- Ein ADXL345 für die Ausrichtung des Wohnmobils
- Ein RTC DS3231
- Momentan noch 2 Nanos zur Simulation der beiden Solarladeregler
- Ein 7" Touchdisplay mit Shield
Künftig werden anstelle der beiden Nanos 2 Solarladeregler seriell verbunden. Die Wasserwerte und die Bordbatterie werden noch durch Zufallswerte simuliert. Bei der Bordbatteriemessung kommt ein Spannungsteiler zum Einsatz, und der Wasserstandsensor liefert bis 2.2 Volt und kann so direkt am Analogpin ausgemessen werden.
Bekannte BUGS (da bin ich noch am debuggen)
- Random Freezes
- Nach dem Neustart ist manchmal der Touchscreen noch aktiv und wechselt einfach auf die letzte gedrückte Position
Hier mal der Sketch zum ganzen Projekt (ich weiss es gibt da bestimmt Verbesserungspotential, und ich bin da auch offen für Vorschläge:
//#######################################################################
//# Wohnmobil-Monitor by Roland Kälin
//#
//# Dieses System ist ausgelegt für eine Auflösung vonn 800x480
//# Benutzt wird ein 7" Touch-Display mit einem SSD1963 Treiber
//# Touchtreiber ist ein TF5206
//#
//# Bekannte Bugs:
//# 1. Der Sketch friert manchmal ein. Ob der Watchdog das merkt wird sich zeigen
//# 2. Manchmal gibt es Random touches
//#
//#######################################################################
#define __DEBUG__
#ifdef __DEBUG__
#define DEBUG(x) Serial.print (x)
#define DEBUGLN(x) Serial.println (x)
#else
#define DEBUG(x)
#define DEBUGLN(x)
#endif
#include <SPI.h>
#include <Wire.h>
#include <UTFT.h>
#include <UTFT_Geometry.h>
#include <Adafruit_FT6206.h>
#include <ADXL345_WE.h> //Gyroskop Bibliothek
#include <EEPROM.h>
#include <BME280I2C.h>
#include "HardwareSerial.h"
#include "icons.h"
#include "victron.h"
// Template Funktion größten Wert aus Array ermitteln
template <typename T, size_t size> T maxRead(const T (&arr)[size]) {
T maxValue {arr[0]};
for (auto &value : arr) maxValue = max(maxValue, value);
return maxValue;
}
// Template Funktion kleinsten Wert aus Array ermitteln
template <typename T, size_t size> T minRead(const T (&arr)[size]) {
T minValue {arr[0]};
for (auto &value : arr) minValue = min(minValue, value);
return minValue;
}
//Display und Touch
Adafruit_FT6206 ts = Adafruit_FT6206();
#define TFT_CS 20
#define TFT_DC 21
UTFT tft(SSD1963_800, 38, 39, 40, 41); //(byte model, int RS, int WR, int CS, int RST, int SER)
UTFT_Geometry geo(&tft);
#define FT5206_WAKE 11
#define FT5206_INT 48
int displayY = tft.getDisplayXSize();
int displayX = tft.getDisplayYSize();
int splashCounter = 0;
//Schriftarten
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t arial_normal[];
extern uint8_t Inconsola[];
extern uint8_t UbuntuBold[];
extern uint8_t various_symbols[];
extern uint8_t Various_Symbols_32x32[];
//Touchscreen Offsets
int offsetX = 0;
int offsetY = 10;
//Programmversion
String Version = "1.4.2";
//Uhr
#include <RTClib.h> //Real Time Clock Bibliothek einbinden
RTC_DS1307 rtc; //Uhr benennen
#define RST_PIN -1 //Reset Pin nicht vorhanden --> also -1
//Colors
#define BLACK 0x0000
#define GREY 0x5555
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define DARKGREEN 0x05C0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define GOLD 0xDDC0
#define WHITE 0xFFFF
#define DARKGREY 0x10A2
//Temperatursensor
BME280I2C bme;
float temp(NAN), hum(NAN), pres(NAN), temp_alt, hum_alt, pres_alt;
float sealevelKorr;
float baro[100];
String tStamp[100];
int b, l1;
static uint32_t baroloop;
float maxValueb, minValueb;
long yPixel, yPixel1, yb, yb1;
int barostatus = 0;
float mosl = 867, moslEE;
float baroInterval = 0.6; //in minuten 14.4 enspricht 24 stunden - 7.2 entspricht 12 stunden - 0.6 entspricht 1 Stunde - 0.05 entspricht 5 Minuten
float hoehenkorrektur = 0;
//Uhrzeitvariablen
String Datumget;
String Uhrget;
String Tagnow;
String Wochentag;
String Datumget_alt;
String Uhrget_alt;
String Tagnow_alt;
String Wochentag_alt;
byte ControllerUhr = 0;
int tiStampMin, tiStampStd, tiStamp;
//Batterien
float Aufbaubatterie, Bordbatterie;
//Wasserstandvariablen
int Wasserstand;
float Wasser;
//Gauge Variablen
#define RED2RED 0
#define GREEN2GREEN 1
#define BLUE2BLUE 2
#define BLUE2RED 3
#define GREEN2RED 4
#define RED2GREEN 5
byte seg = 5; //5 // Segments are 5 degrees wide = 60 segments for 300 degrees
byte inc = 5; //10 // Draw segments every 5 degrees, increase to 10 for segmented ring
//Gyroskop
#define ADXL345_I2CADDR 0x53 // 0x1D if SDO = HIGH
ADXL345_WE myAcc = ADXL345_WE(ADXL345_I2CADDR); //Name des Gyroskops
uint32_t runTime = -99999; // time for next update
enum pageId {
MENU,
INFO,
BATTERIE,
WATER,
INFO1,
DISPLAYAUS,
SOLAR,
SOLAR1,
WETTER,
WETTERTREND,
EINSTELL,
EINSTELLFARBE,
EINSTELLHOEHE,
LEVEL,
SPLASH,
NEUSTART,
TIMEOUT,
WECHSELRICHTER,
};
unsigned int currentPage = MENU, oldPage = -1;
//Tonausgabe
int tonPin = 45;
//Solarvariablen
float SolarAmps, SolarAmps2, SolarVolts, BatAmps, BatVolts;
int SolarWatts;
String label200, label160, val200, val160;
String PID200, PID160; //Produkt-ID
String FW200, FW160; //Firmware Version
String SER200, SER160; //Seriennummer
float V200, V160; //[V] Batteriespannung
float Ib200, Ib160; //[mA] Batterieladestrom
float VPV200, VPV160; //[V] Solar-Panel Spannung
float PPV200, PPV160; //[W] Solar-Panel Leistung
int CS200, CS160; //Charger-Status 0=Aus, 2=Error, 3=Laden, 4=Entladen, 5=Batt V halten
String MPPT200, MPPT160; //Unbekannter Wert
String OR200, OR160; //Unbekannter Wert
int ERR200, ERR160; //Error-Status 0=Kein Error, 2=Batt V zu hoch, 17=Temp zu hoch, 18=Überstrom, 19=Amp umgekehrt, 20=Ladezeitlimit abgelaufen, 21=Amp Sensor Fehler, 26=Anschlüsse überhitzt, 33=Solar V zu hoch, 34=Solar A zu hoch, 38=Input abgeschaltet, 116=WerkseinstellungenDatenVerloren, 117=Falsche Firmware, 119=Einstellungen falsch
float LOAD200, LOAD160; //Lastausgang ON/OFF
float IL200, IL160; //[mA] Lastausgang-Strom
float H19200, H19160; //[kWh] Ertrag über die gesamte Lebensdauer des Gerätes
int H20200, H20160; //[kWh] Ertrag Heute
int H21200, H21160; //[W] Max-Leistung Heute
int H22200, H22160; //[kWh] Ertrag Gestern
int H23200, H23160; //[W] Max-Leistung Gestern
int HSDS200, HSDS160; //[T] Anzahl Tage über die gesamte Lebensdauer des Gerätes
float tempfloat = 0.00;
int radius = 70;
//Einstellungen zum Nivelieren
float abwlr = 1.5; //winkelabweichung zum Keilen
float abwhv = 1.5;
float links = 0.0, rechts = 0.0, vorne = 0.0, hinten = 0.0;
float rad = 0.0174532925;
//Umrechnung RGB in 565
#define RGB565(r, g, b) ((((r)& 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))
//Farbeinstellungen
uint16_t Vorder, BtnTextf, Schriftf, Vorder_alt, BtnTextf_alt, Schriftf_alt;
int selRot, selGruen, selBlau, selRot_alt, selGruen_alt, selBlau_alt;
int pixel_x_alt; //Touch_getXY() updates global vars
int o = 0;
int n = 1;
int F = 0;
int rot, gruen, blau, fx, fy, cursx, rf, gf, bf;
//Systemreset
void(* resetFunc) (void) = 0;//declare reset function at address 0
//Bildschirm schwarz
unsigned int aus_ee;
long aus;
static uint32_t sekundenloop, timeoutloop;
int zahl[8], ki = 0, ka = 0;
int uebergabe = 0;
//Wechselrichter
bool wechselrichterStatus = false;
//Buttons
bool down = 0;
bool pressed = 0;
int ty, tx;
void setup(void)
{
Serial.begin(9600);
Serial1.begin(19200);
Serial3.begin(19200);
aus_ee = EEPROM[0];
//Grundfarben definieren
BtnTextf = 0xFFFF;
Vorder = 0x0a2a;
Schriftf = 0xf2f0;
readeepromColor();
fx = 100;//Position Farbbalken
fy = 100;
cursx = 0;
tft.InitLCD();
if (!ts.begin(40)) {
DEBUGLN("Unable to start touchscreen.");
}
else {
DEBUGLN("Touchscreen started.");
}
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
pinMode (FT5206_WAKE, INPUT);
digitalWrite(FT5206_WAKE, HIGH );
pinMode (FT5206_INT, INPUT);
tft.fillScr(0, 0, 0);
tft.setFont(SmallFont);
DEBUGLN("TFT initialized");
//Uhr
#ifndef ESP8266 //Wenn ein ESP8266 angeschlossen ist
while (!Serial); // auf den Seriellen Port warten. Dieser wird für natives USB benötigt
#endif
delay(500);
if (! rtc.begin())
{ //Wenn rtc.begin fehlschlägt
DEBUGLN("Konnte die RTC nicht starten"); //Ausgabe auf den seriellen Monitor
abort(); //abbrechen
}
delay(1000); //1 Sekunde warten
if (! rtc.isrunning())
{ //Wenn RTC nicht läuft
DEBUGLN("RTC läuft nicht, also müssen wir die Zeit einstellen");
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Daten von Systemzeit holen
// rtc.adjust(DateTime(2023, 6, 23, 18, 7, 30)); //Datum und Uhrzeit manuell eingeben (ohne anführende Nullen
}
// Wenn nur Zeit/Datum eingestellt werden muss
//Serial.println("RTC läuft, aber wir müssen die Zeit einstellen");
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Daten von Systemzeit holen
// rtc.adjust(DateTime(2023, 6, 23, 18, 7, 30)); //Datum und Uhrzeit manuell eingeben (ohne anführende Nullen
getUhrzeit();
//Gyroskop abfragen
if (!myAcc.init()) {
DEBUGLN("ADXL345 not connected!");
}
//Korrekturfaktoren für das Gyroskop
myAcc.setCorrFactors(-262.0, 279.0, -270.0, 275.0, -291.0, 214.0);
//Gyroskop ausrichten
delay(2000);
myAcc.measureAngleOffsets();
//Gyroskop Abtastrate
myAcc.setDataRate(ADXL345_DATA_RATE_50);
//Gyroskop Messbereich
myAcc.setRange(ADXL345_RANGE_2G);
// Temperatursensor starten
while (!bme.begin())
{
DEBUGLN("Could not find BME280 sensor!");
delay(1000);
}
switch (bme.chipModel())
{
case BME280::ChipModel_BME280:
DEBUGLN("Found BME280 sensor! Success.");
break;
default:
DEBUGLN("Found UNKNOWN sensor! Error!");
}
//Wire starten
Wire.begin();
Wire.setClock(400000L);
//Wasserstand holen
getWasser();
currentPage = SPLASH;
sekundenloop = millis();
baroloop = millis();
timeoutloop = millis();
wechselrichterStatus = 1;
label200 = "0";
label160 = "0";
b = 99;
tx = 0;
ty = 0;
down = 0;
watchdogSetup();
DEBUGLN("Setup komplett");
}
void loop(void)
{
//DEBUG("Timeout: ");
//DEBUGLN((millis() / 10000) - (timeoutloop / 10000));
if (millis() - baroloop > baroInterval * 60000)
{
DEBUGLN("Baroloop");
getBaroTrend();
baroloop = millis();
}
if ((millis() / 10000) - (timeoutloop / 10000) < aus_ee)
{
DEBUG("Timeoutloop: ");
DEBUGLN((millis() / 10000) - (timeoutloop / 10000));
switch (currentPage)
{
case WETTERTREND:
DEBUGLN("Case Wettertrend");
if (currentPage != oldPage) drawWetterTrendScreen();
zbp(WETTER);
hbp();
break;
case SPLASH:
DEBUGLN("Case Splash");
if (currentPage != oldPage) drawSplashScreen();
// getSolar200();
// getSolar160();
splashCounter++;
if (splashCounter == 100)
{
down = 0;
currentPage = MENU;
}
sekundenloop = millis();
break;
case MENU: //Menu page
DEBUGLN("Case Menu");
if (currentPage != oldPage) drawMenuScreen();
getTouched();
if ((down == 1) and (tx > 250 - 250) and (ty > 100 - 60) and (tx < 250 + 250 / 2) and (ty < 100 + 60 / 2))
{
currentPage = WATER;
down = 0;
}
if ((down == 1) and (tx > 550 - 250) and (ty > 100 - 60) and (tx < 550 + 250 / 2) and (ty < 100 + 60 / 2))
{
currentPage = LEVEL;
down = 0;
}
if ((down == 1) and (tx > 250 - 250) and (ty > 205 - 60) and (tx < 250 + 250 / 2) and (ty < 205 + 60 / 2))
{
currentPage = BATTERIE;
down = 0;
}
if ((down == 1) and (tx > 550 - 250) and (ty > 205 - 60) and (tx < 550 + 250 / 2) and (ty < 205 + 60 / 2))
{
currentPage = WETTER;
down = 0;
}
if ((down == 1) and (tx > 250 - 250) and (ty > 310 - 60) and (tx < 250 + 250 / 2) and (ty < 310 + 60 / 2))
{
currentPage = SOLAR;
down = 0;
}
if ((down == 1) and (tx > 550 - 250) and (ty > 310 - 60) and (tx < 550 + 250 / 2) and (ty < 310 + 60 / 2))
{
currentPage = WECHSELRICHTER;
down = 0;
}
ibp();
sbp();
abp();
break;
case WATER: //Wasserstand
DEBUGLN("Case Wasser");
if (currentPage != oldPage) drawWaterScreen();
updateWater();
hbp();
break;
case LEVEL:
DEBUGLN("Case Level");
if (currentPage != oldPage) drawLevelScreen();
getLevel();
hbp();
break;
case SOLAR: //Solar 160W
DEBUGLN("Case Solar");
if (currentPage != oldPage) drawSolarScreen();
hbp();
vbp(SOLAR1);
break;
case SOLAR1: //Solar 200 W
DEBUGLN("Case Solar1");
if (currentPage != oldPage) drawSolar1Screen();
updateSolarWerte();
hbp();
zbp(SOLAR);
break;
case WETTER:
DEBUGLN("Case Wetter");
if (currentPage != oldPage)
{
getTemperatur();
getUhrzeit();
drawWetterScreen();
}
updateUhrzeit();
updateTemperatur();
hbp();
vbp(WETTERTREND);
break;
case INFO:
DEBUGLN("Case Info");
if (currentPage != oldPage) drawInfoScreen();
if (down == 1)
{
currentPage = MENU;
down = 0;
}
break;
case EINSTELL:
DEBUGLN("Case Einstell");
//DEBUG("Down: ");
//DEBUGLN(down);
if (currentPage != oldPage) drawEinstellScreen();
if ((down == 1) and (tx > 250 - 250) and (ty > 100 - 60) and (tx < 250 + 250 / 2) and (ty < 100 + 60 / 2))
{
currentPage = NEUSTART;
down = 0;
}
if ((down == 1) and (tx > 250 - 250) and (ty > 205 - 60) and (tx < 250 + 250 / 2) and (ty < 205 + 60 / 2))
{
currentPage = TIMEOUT;
down = 0;
}
if ((down == 1) and (tx > 250 - 250) and (ty > 310 - 60) and (tx < 250 + 250 / 2) and (ty < 310 + 60 / 2))
{
currentPage = EINSTELLFARBE;
down = 0;
}
if ((down == 1) and (tx > 550 - 250) and (ty > 100 - 60) and (tx < 550 + 250 / 2) and (ty < 100 + 60 / 2))
{
currentPage = EINSTELLHOEHE;
down = 0;
}
hbp();
break;
case EINSTELLFARBE:
DEBUGLN("Case Einstellfarbe");
if (currentPage != oldPage) drawEinstellFarbeScreen();
Farbenwahl();
zbp(EINSTELL);
hbp();
break;
case EINSTELLHOEHE:
DEBUGLN("Case Einstellhoehe");
if (currentPage != oldPage) drawEinstellHoeheScreen();
Hoehenwahl();
zbp(EINSTELL);
hbp();
break;
case BATTERIE:
DEBUGLN("Case Batterie");
if (currentPage != oldPage) drawBatterieScreen();
updateBatterie();
hbp();
break;
case NEUSTART: //System zurücksetzen
DEBUG("Case Neustart");
if (currentPage != oldPage) drawResetScreen();
if ((down == 1) and (tx > 140) and (ty > displayY - 42) and (tx < 260) and (ty < displayY - 2))
{
down = 0;
resetFunc();
}
if ((down == 1) and (tx > 560) and (ty > displayY - 42) and (tx < 680) and (ty < displayY - 2))
{
currentPage = EINSTELL;
down = 0;
}
break;
case DISPLAYAUS:
DEBUG("Case Displayaus");
if (currentPage != oldPage)drawDisplayAusScreen();
tx = 0;
ty = 0;
if (ts.touched())
{
digitalWrite(8, HIGH);
down = 0;
delay(500);
}
break;
case TIMEOUT:
DEBUG("Case Timeout");
if (currentPage != oldPage)drawTimeoutScreen();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
if ((down == 1) and (tx > 480) and (ty > displayY - 42) and (tx < 600) and (ty < displayY - 2))
{
down = 0;
if (aus_ee < 60)
{
tft.print(" ", 350, 70);
tft.print(" ", 20, 90);
}
aus_ee = aus_ee + 1;
tft.printNumI(aus_ee * 10, 350, 70);
if (aus_ee >= 60)
{
aus_ee = 60;
tft.print("Mehr als 10 Minuten macht keinen Sinn", 20, 90);
tft.print(aus_ee * 10, 350, 70);
}
delay(300);
}
if ((down == 1) and (tx > 200) and (ty > displayY - 42) and (tx < 320) and (ty < displayY - 2))
{
down = 0;
if (aus_ee > 0)
{
tft.print(" ", 350, 70);
tft.print(" ", 20, 90);
}
aus_ee = aus_ee - 1;
tft.printNumI(aus_ee * 10, 350, 70);
if (aus_ee <= 12)
{
aus_ee = 12;
tft.print("Weniger als 2 Minuten ist nicht erlaubt", 20, 90);
tft.printNumI(aus_ee * 10, 350, 70);
}
delay(300);
}
if ((down == 1) and (tx > 340) and (ty > displayY - 42) and (tx < 460) and (ty < displayY - 2))
{
down = 0;
EEPROM.update(0, aus_ee);
delay(10);
currentPage = EINSTELL;
}
hbp();
break;
case WECHSELRICHTER:
DEBUGLN("Case Wechselrichter");
if (currentPage != oldPage)drawWechselrichterScreen();
getTouched();
if ((down == 1) and (tx > 540) and (ty > 230) and (tx < 660) and (ty < 270))
{
if (wechselrichterStatus == 0)
{
wechselrichterStatus = 1;
drawSwitch(50, 100, 300, 20, Vorder, wechselrichterStatus);
pressed = 0;
}
}
if ((down == 1) and (tx > 140) and (ty > 230) and (tx < 260) and (ty < 270))
{
if ((wechselrichterStatus == 1))
{
wechselrichterStatus = 0;
drawSwitch(50, 100, 300, 20, Vorder, wechselrichterStatus);
pressed = 0;
}
}
hbp();
break;
}
if (oldPage == currentPage)
{
getTouched();
if (down == 1 and digitalRead(8) == LOW)
{
DEBUGLN("Dsiplay ist aus und wartet auf touch");
timeoutloop = millis();
down = 0;
digitalWrite(8, HIGH);
delay(500);
}
}
}
else if (((millis() / 10000) - (timeoutloop / 10000) > aus_ee - 1) and (digitalRead(8) == HIGH))
{
DEBUGLN("Dsiplay wird ausgeschalten durch timer");
down = 0;
digitalWrite(8, LOW);
}
else if (((millis() / 10000) - (timeoutloop / 10000) > aus_ee - 1) and (digitalRead(8) == LOW))
{
DEBUGLN("Display wurde ausgeschalten durch timer und wartet auf touch");
DEBUG("Timeoutloop Display ist aus: ");
DEBUGLN((millis() / 10000) - (timeoutloop / 10000));
DEBUG("CurrentPage: ");
DEBUGLN(currentPage);
if (ts.touched() and digitalRead(8) == LOW)
{
timeoutloop = millis();
down = 0;
digitalWrite(8, HIGH);
delay(500);
}
}
asm("WDR");
//DEBUGLN("Watchdog Reset");
}
/************************************************************************************
Screens gestalten
************************************************************************************/
void drawWechselrichterScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Wechselrichter", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
drawSwitch(50, 100, 300, 20, Vorder, wechselrichterStatus);
tft.setColor(Schriftf);
tft.print("Aus", 0, 100 - tft.getFontYsize() / 2);
tft.print("Ein", 355, 100 - tft.getFontYsize() / 2);
Button(600, 250, 120, 40, Vorder, BtnTextf, "AN", UbuntuBold);
Button(200, 250, 120, 40, Vorder, BtnTextf, "AUS", UbuntuBold);
showHome();
oldPage = currentPage;
}
void drawSplashScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Vorder);
tft.drawBitmap(displayX / 2 - 250, displayY / 2 - 65, 250, 65, rimor, 2);
oldPage = currentPage;
}
void drawTimeoutScreen()
{
down = 0;
aus_ee = EEPROM[0];
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Timeout fur das Display", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
tft.print ("Timeout in Sekunden: ", 20, 70);
tft.printNumI(aus_ee * 10, 350, 70);
Button(260, displayY - 22, 120, 40, Vorder, BtnTextf, "-10", UbuntuBold);
Button(540, displayY - 22, 120, 40, Vorder, BtnTextf, "+10", UbuntuBold);
Button(displayX / 2, displayY - 22, 120, 40, Vorder, BtnTextf, "OK", UbuntuBold);
showHome();
oldPage = currentPage;
}
void drawDisplayAusScreen()
{
down = 0;
digitalWrite(8, LOW);
oldPage = currentPage;
}
void drawMenuScreen()
{
down = 0;
tx = 0;
ty = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Womo - Monitor", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
// Button
tft.setColor(Vorder);
Button(250, 100, 250, 60, Vorder, BtnTextf, "Wasser", UbuntuBold);
Button(550, 100, 250, 60, Vorder, BtnTextf, "Level", UbuntuBold);
Button(250, 205, 250, 60, Vorder, BtnTextf, "Batterie", UbuntuBold);
Button(550, 205, 250, 60, Vorder, BtnTextf, "Wetter", UbuntuBold);
Button(250, 310, 250, 60, Vorder, BtnTextf, "Solar", UbuntuBold);
Button(550, 310, 250, 60, Vorder, BtnTextf, "Strom", UbuntuBold);
showInfo();
showSet();
showAus();
oldPage = currentPage;
}
void drawBatterieScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Ladezustand Batterien", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
updateBatterie();
showHome();
oldPage = currentPage;
}
void drawSolarScreen()//Solar gesamt
{
radius = 120;
down = 0;
for (int r = 0; r < 10; r++)
{
getSolar200();
getSolar160();
}
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Solarleistung gesamt", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
//Volts
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
String bText = String((VPV200 + VPV160) / 2);
int laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, displayX / 4 - laengeText - 50, displayY / 2 - tft.getFontYsize() / 2);
tft.print("V", displayX / 4 + laengeText - 50, displayY / 2 - tft.getFontYsize() / 2);
ringMeter((VPV200 + VPV160) / 2, 12, 45, displayX / 4 - radius - 50, displayY / 2 - radius, radius, RED2GREEN );
//Amps
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
bText = String((PPV200 + PPV160) / (VPV200 + VPV160) / 2);
laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, displayX / 2 - laengeText, displayY / 2 - tft.getFontYsize() / 2);
tft.print("A", displayX / 2 + laengeText, displayY / 2 - tft.getFontYsize() / 2);
ringMeter((PPV200 + PPV160) / (VPV200 + VPV160) / 2, 0, 20, displayX / 2 - radius, displayY / 2 - radius, radius, RED2GREEN );
//Watts
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
bText = String((PPV200 + PPV160), 0);
laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, displayX / 4 * 3 - laengeText + 50, displayY / 2 - tft.getFontYsize() / 2);
tft.print("W", displayX / 4 * 3 + laengeText + 50, displayY / 2 - tft.getFontYsize() / 2);
ringMeter(PPV200 + PPV160, 1, 360, displayX / 4 * 3 - radius + 50, displayY / 2 - radius, radius, RED2GREEN );
showHome();
showVor();
oldPage = currentPage;
}
void drawSolar1Screen()
{
down = 0;
getSolar200();
getSolar160();
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Solarwerte", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
tft.print("Bat. Spannung: ", 20, 50);
tft.printNumF(V200, 2, 360, 50);
tft.print(" V", 470, 50);
tft.print("Ladestrom: ", 20, 100);
tft.printNumF(Ib200 + Ib160, 2, 360, 100);
tft.print(" A", 470, 100);
tft.print("Tot. Ertrag: ", 20, 150);
tft.printNumF(H19200 + H19160, 2, 360, 150);
tft.print(" kWh", 470, 150);
tft.print("Ertrag heute: ", 20, 200);
tft.printNumF(H20200 + H20160, 2, 360, 200);
tft.print(" Wh", 470, 200);
tft.print("max Leistung heute: ", 20, 250);
tft.printNumF(H21200 + H21160, 2, 360, 250);
tft.print(" W", 470, 250);
tft.print("Ertrag gestern: ", 20, 300);
tft.printNumF(H22200 + H22160, 2, 360, 300);
tft.print(" Wh", 470, 300);
tft.print("max Leistung gestern: ", 20, 350);
tft.printNumF(H23200 + H23160, 2, 360, 350);
tft.print(" W", 470, 350);
showHome();
showVor();
showZuruck();
oldPage = currentPage;
}
void drawWaterScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Frischwasser", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
randomSeed(millis());
Wasserstand = random(0, 220);
getWasser();
showHome();
oldPage = currentPage;
}
void drawLevelScreen()
{
down = 0;
tft.fillScr(0x0000);
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Nivelierung", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
getLevel();
tft.setColor(WHITE);
tft.drawRect(10, 100, 70, 120);
tft.drawRect(10, 250, 70, 270);
tft.drawRect(300, 100, 360, 120);
tft.drawRect(300, 250, 360, 270);
tft.drawLine(40, 120, 40, 175);
tft.drawLine(40, 195, 40, 250);
tft.drawCircle(40, 185, 10);
tft.drawLine(330, 120, 330, 250);
tft.drawLine(50, 185, 330, 185);
showHome();
oldPage = currentPage;
}
void drawInfoScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Informationen", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
tft.print("Dieses System wurde in muhevoller", 25, 80);
tft.fillRect(412, 80, 414, 82);
tft.fillRect(418, 80, 420, 82);
tft.print("Kleinstarbeit und mit viel Zeit", 25, 105);
tft.print("von Roland zusammengekloppelt.", 25, 130);
tft.fillRect(396, 130, 398, 132);
tft.fillRect(402, 130, 404, 132);
tft.print("Bei Fragen gerne melden.", 25, 155);
tft.print("Tel: +41 79 XXX XX XX", 25, 205);
tft.print("email: rxxxxxxxxx@gmail.com", 25, 230);
tft.print("Programmversion: ", 25, 280);
tft.print(Version, 300, 280);
down = 0;
oldPage = currentPage;
}
void drawEinstellScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Einstellungen", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
Button(250, 100, 250, 60, Vorder, BtnTextf, "Neustart", UbuntuBold);
Button(250, 205, 250, 60, Vorder, BtnTextf, "Display", UbuntuBold);
Button(250, 310, 250, 60, Vorder, BtnTextf, "Farben", UbuntuBold);
Button(550, 100, 250, 60, Vorder, BtnTextf, "Hoehe", UbuntuBold);
showHome();
oldPage = currentPage;
}
void drawEinstellFarbeScreen()
{
down = 0;
tft.clrScr();
Button(50, fy + 25, 50, 50, Vorder, BtnTextf, "-", UbuntuBold);
Button(406, fy + 25, 50, 50, Vorder, BtnTextf, "+", UbuntuBold);
Button(50, fy + 125, 50, 50, Vorder, BtnTextf, "-", UbuntuBold);
Button(406, fy + 125, 50, 50, Vorder, BtnTextf, "+", UbuntuBold);
Button(50, fy + 225, 50, 50, Vorder, BtnTextf, "-", UbuntuBold);
Button(406, fy + 225, 50, 50, Vorder, BtnTextf, "+", UbuntuBold);
Button(650, fy + 25, 250, 50, Vorder, BtnTextf, "Hauptfarbe", UbuntuBold);
Button(650, fy + 125, 250, 50, Vorder, BtnTextf, "Textfarbe", UbuntuBold);
Button(650, fy + 325, 250, 50, Vorder, BtnTextf, "Reset", UbuntuBold);
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.setColor(Schriftf);
tft.drawRoundRect(525, fy + 200, 775, fy + 250);
tft.print("Farbeinstellungen", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
farben();
showHome();
showZuruck();
oldPage = currentPage;
}
void drawEinstellHoeheScreen()
{
moslEE = EEPROM.read(10);
if (EEPROM.read(9) > 0)
{
mosl = moslEE * 20 + 10;
}
else
{
mosl = moslEE * 20;
}
down = 0;
tft.clrScr();
Button(50, 125, 50, 50, Vorder, BtnTextf, "-", UbuntuBold);
Button(406, 125, 50, 50, Vorder, BtnTextf, "+", UbuntuBold);
Button(650, 125, 250, 50, Vorder, BtnTextf, "Speichern", UbuntuBold);
tft.setFont(UbuntuBold);
tft.setColor(Schriftf);
String bText = String (mosl, 0);
bText = " " + bText + " m.u.M.";
int laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, 225 - laengeText, 100 + tft.getFontYsize() / 2);
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.setColor(Schriftf);
tft.print("Hoeheneinstellung", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
showHome();
showZuruck();
oldPage = currentPage;
}
void drawWetterScreen()
{
down = 0;
tft.clrScr();
tft.setFont(BigFont);
tft.print("Heute ist: ", 50, 50);
tft.print(Wochentag, 330, 50);
tft.print(Datumget, 330, 75);
tft.print(Uhrget, 330, 100);
Uhrget_alt = Uhrget;
Datumget_alt = Datumget;
Tagnow_alt = Tagnow;
tft.setFont(BigFont);
tft.print("Temperatur: ", 50, 150);
tft.printNumF(temp, 1, 361, 150);
tft.print(" C ", 440, 150);
tft.print("Luftfeuchtigkeit: ", 50, 175);
tft.printNumF(hum, 1, 361, 175);
tft.print(" % ", 440, 175);
tft.print("Luftdruck: ", 50, 200);
tft.printNumF(pres / 100 + sealevelKorr + hoehenkorrektur, 2, 329, 200);
tft.print(" hpa ", 440, 200);
//DEBUG("Press Sealevel: ");
//DEBUGLN(pres / 100 + hoehenkorrektur + sealevelKorr);
//DEBUG("Press: ");
//DEBUGLN(pres / 100 + hoehenkorrektur);
if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 75 and (pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 105)
{
tft.print("Tendenz: Regen", 50, 250);
}
else if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 106 and (pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 112)
{
tft.print("Tendenz: Wechselhaft", 50, 250);
}
else if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 113 and (pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 129)
{
tft.print("Tendenz: Schoen", 50, 250);
}
else if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 130)
{
tft.print("Tendenz: Trocken", 50, 250);
}
showHome();
showVor();
oldPage = currentPage;
}
////////////////////////////////////////////////////////////////////
//WetterTrend
////////////////////////////////////////////////////////////////////
void drawWetterTrendScreen()
{
down = 0;
for (int l1 = 0; l1 < (sizeof(baro) / sizeof(baro[0])); l1++)
{
maxValueb = maxRead(baro);
minValueb = minRead(baro);
}
tft.clrScr();
tft.setColor(Vorder);
tft.setFont(SmallFont);
tft.drawLine(59, 50, 59, 350);
tft.drawLine(59, 350, 761, 350);
tft.printNumF(maxValueb / 1, 2, 0, 50 - (tft.getFontYsize() / 2));
tft.printNumF(minValueb / 1, 2, 0, 350 - (tft.getFontYsize() / 2));
int calc = 0;
//DEBUG("Timestamp: ");
//DEBUGLN(tiStamp);
DateTime now = rtc.now(); //Daten auslesen
tiStampStd = now.hour();
tiStampMin = now.minute();
tiStamp = tiStampStd * 60 + tiStampMin + (11 * baroInterval);
for (int posi = 10; posi >= 1; posi--)
{
if ((tiStamp - 10 * baroInterval) < 60) tiStamp = tiStamp + 1440;
tiStamp = tiStamp - 11 * baroInterval;
//DEBUG("TimeSchtamp: ");
//DEBUGLN(tiStamp);
//DEBUG("Calc: ");
//DEBUGLN(calc);
tiStampStd = tiStamp / 60;
tiStampMin = tiStamp - (tiStampStd * 60);
//DEBUG("Std: ");
//DEBUGLN(tiStampStd);
String Std, Min, Stempel;
if (tiStampStd < 10)
{
Std = String(tiStampStd);
Std = "0" + Std;
}
else if (tiStampStd == 24)
{
Std = "00";
}
else
{
Std = String(tiStampStd);
}
if (tiStampMin < 10)
{
Min = String(tiStampMin);
Min = "0" + Min;
}
else
{
Min = String(tiStampMin);
}
Stempel = (Std + ":" + Min);
tft.print(Stempel, (59 - tft.getFontYsize() / 2) + (posi - 1) * 77, 400, 270);
//DEBUG("Timestamp: ");
//DEBUG(tiStampStd);
//DEBUG(" : ");
//DEBUGLN(tiStampMin);
calc++;
}
l1 = 0;
while (l1 < 99)
{
yb = baro[l1];
yPixel = map(yb, minValueb, maxValueb, 349, 50);
yb1 = baro[l1 + 1];
yPixel1 = map(yb1, minValueb, maxValueb, 349, 50);
tft.setColor(Schriftf);
tft.drawLine(l1 * 7 + 60, yPixel, l1 * 7 + 67, yPixel1);
l1++;
}
showHome();
showZuruck();
oldPage = currentPage;
}
void drawResetScreen()
{
down = 0;
tft.clrScr();
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.print("Neustart", 20, 5);
tft.drawLine(0, 34, displayX * 0.6, 34);
tft.setFont(BigFont);
tft.print("Bei einem Neustart des Systems", 25, 70);
tft.print("werden alle Parameter neu geladen.", 25, 95);
tft.print("Das Fahrzeug muss dabei ganz", 25, 120);
tft.print("gerade stehen, da der Niveausensor", 25, 145);
tft.print("dabei neu kalibriert wird.", 25, 170);
tft.print("Neu starten ? ", 25, 220);
Button(200, displayY - 42, 120, 40, Vorder, BtnTextf, "JA", UbuntuBold);
Button(600, displayY - 42, 120, 40, Vorder, BtnTextf, "NEIN", UbuntuBold);
oldPage = currentPage;
}
/************************************************************************************
Zusätzliche Funktionen
*************************************************************************************/
//#######################################################
//Fest platzierte Buttons
//#######################################################
void showHome()//Home Button anzeigen
{
Button(70, displayY - 22, 120, 40, Vorder, WHITE, "Home", UbuntuBold);
}
void hbp() //home Button pressed
{
getTouched();
if (down == 1)
{
if ((tx > 10) and (ty > displayY - 42) and (tx < 130) and (ty < displayY - 2))
{
currentPage = MENU;
down = 0;
}
}
}
void showVor()//Vorwärts Button anzeigen
{
Button(465, displayY - 22, 120, 40, Vorder, WHITE, "S", Various_Symbols_32x32);
}
void vbp(unsigned int Page) //Vorwärts Button gedrückt
{
getTouched();
if (down == 1)
{
if ((tx > 405) and (ty > displayY - 42) and (tx < 525) and (ty < displayY - 2))
{
currentPage = Page;
down = 0;
}
}
}
void showZuruck()//Zurück Button anzeigen
{
Button(335, displayY - 22, 120, 40, Vorder, WHITE, "R", Various_Symbols_32x32);
}
void zbp(unsigned int Page) //Zurück Button pressed
{
getTouched();
if (down == 1)
{
if ((tx > 275) and (ty > displayY - 42) and (tx < 355) and (ty < displayY - 2))
{
currentPage = Page;
down = 0;
}
}
}
void showAus() //Display aus
{
Button(displayX - 26, displayY - 27, 50, 50, Vorder, BtnTextf, "l", Various_Symbols_32x32);
}
void abp() //Info Button gedrückt
{
getTouched();
if (down == 1)
{
if ((tx < displayX - 1) and (ty > displayY - 42) and (tx > displayX - 51) and (ty < displayY - 2))
{
down = 0;
digitalWrite(8, LOW);
delay(500);
timeoutloop = millis();
}
}
}
void showInfo()//info Button anzeigen
{
Button(displayX - 26, 26, 50, 50, Vorder, WHITE , "i", UbuntuBold);
}
void ibp() //Info Button gedrückt
{
getTouched();
if (down == 1)
{
if ((tx < displayX - 1) and (ty > 1) and (tx > displayX - 51) and (ty < 51))
{
currentPage = INFO;
down = 0;
}
}
}
void showSet()//Settings Button anzeigen
{
Button(displayX - 86, 26, 50, 50, Vorder, WHITE, "s", Various_Symbols_32x32);
}
void sbp() //Settings Button gedrückt
{
getTouched();
if (down == 1)
{
if ((tx < displayX - 61) and (ty > 1) and (tx > displayX - 101) and (ty < 51))
{
currentPage = EINSTELL;
down = 0;
}
}
}
//##############################################
//#Uhrzeit auslesen
//##############################################
void getUhrzeit()
{
vbp(WETTERTREND);
hbp();
DateTime now = rtc.now(); //Daten auslesen
char buf1[] = " DDD"; //Wochentag in buf2[] schreiben
Tagnow = (now.toString(buf1)); //Wochentag als String übergeben an tagnow
//Überprüfung welcher Wochentag ist, und diesen dann ausgeschrieben an Display senden mit Zeilenumbruch
if (Tagnow == " Sam") Wochentag = "Samstag";
else if (Tagnow == " Son") Wochentag = "Sonntag";
else if (Tagnow == " Mon") Wochentag = "Montag ";
else if (Tagnow == " Die") Wochentag = "Dienstag";
else if (Tagnow == " Mit") Wochentag = "Mittwoch";
else if (Tagnow == " Don") Wochentag = "Donnerstag";
else if (Tagnow == " Fre") Wochentag = "Freitag ";
//Überprüfung fertig
char buf2[] = "DD.MM.YYYY";
Datumget = (now.toString(buf2));
char buf3[] = "hh:mm";
Uhrget = (now.toString(buf3)); //Aktuelle Uhrzeit in oledreset schreiben
DEBUG("tiStamp: ");
DEBUGLN(tiStamp);
}
//##############################################
//#Uhrzeit aktualisieren
//##############################################
void updateUhrzeit()
{
getUhrzeit();
if (Uhrget != Uhrget_alt or Datumget != Datumget_alt or Tagnow != Tagnow_alt)
{
tft.setFont(BigFont);
tft.print(Wochentag, 330, 50);
tft.print(Datumget, 330, 75);
tft.print(Uhrget, 330, 100);
Uhrget_alt = Uhrget;
Datumget_alt = Datumget;
Tagnow_alt = Tagnow;
}
}
//##############################################
//#Temperatursensor auswerten
//##############################################
void getTemperatur()
{
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
sealevelKorr = (1013.25 * pow((1 - 6.5 * mosl / (288150)), 5.255));
sealevelKorr = 1013.25 - sealevelKorr;
}
//##############################################
//#Temperatursensor updaten
//##############################################
void updateTemperatur()
{
getTemperatur();
tft.setFont(BigFont);
if (pres != pres_alt)
{
tft.printNumF(pres / 100 + sealevelKorr + hoehenkorrektur, 2, 329, 200);
// tft.print("hpa", 440, 200);
pres_alt = pres / 100 + sealevelKorr + hoehenkorrektur;
}
if ((temp) != (temp_alt, 0))
{
tft.printNumF(temp, 1, 361, 150);
temp_alt = (temp);
}
if ((hum, 0) / 100 != (hum_alt, 0))
{
tft.printNumF(hum, 1, 361, 175);
tft.print("Luftdruck : ", 50, 200);
hum_alt = (hum, 0) / 100;
}
if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 74)
{
tft.print("Tendenz : Sturm", 50, 250);
}
if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 75 and (pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 105)
{
tft.print("Tendenz : Regen", 50, 250);
}
if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 106 and (pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 112)
{
tft.print("Tendenz : Wechselhaft", 50, 250);
}
if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 113 and (pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) <= 129)
{
tft.print("Tendenz : Schoen", 50, 250);
}
if ((pres / 100 + hoehenkorrektur + sealevelKorr) - (pres / 100 - hoehenkorrektur) >= 130)
{
tft.print("Tendenz : Trocken", 50, 250);
}
}
//##############################################
//#Vorläufige Werte für diverse Sensoren
//##############################################
void getWasser()
{
Wasserstand = (Wasserstand / 100 * 45.45);
}
void updateWater()
{
if (Wasserstand < 100)
{
Wasserstand++;
int radius = 180;
ringMeter(Wasserstand, 0, 100, displayX / 2 - radius, displayY / 2 - radius, radius, 5);
tft.setFont(UbuntuBold);
tft.setColor(Schriftf);
String Wasser = String(Wasserstand);
int laengeText = (Wasser.length() * tft.getFontXsize() / 2);
tft.print(Wasser, displayX / 2 - laengeText , displayY / 2 - tft.getFontYsize() / 2);
tft.print("% ", displayX / 2 + laengeText, displayY / 2 - tft.getFontYsize() / 2);
}
}
void getBordbatterie()
{
randomSeed(millis());
Bordbatterie = random(1200, 1400);
}
//#######################################################
//Ringmeter
//#######################################################
int ringMeter(int value, int vmin, int vmax, int x, int y, int r, byte scheme)
{
x += r; y += r; // Calculate coords of centre of ring
int w = r / 4; // Width of outer ring is 1/4 of radius
int angle = 150; // Half the sweep angle of meter (300 degrees)
int text_colour = 0; // To hold the text colour
int v = map(value, vmin, vmax, -angle, angle); // Map the value to an angle v
// Draw colour blocks every inc degrees
for (int i = -angle; i < angle; i += inc) {
// Choose colour from scheme
int colour = 0;
switch (scheme) {
case 0: colour = RED; break; // Fixed colour
case 1: colour = GREEN; break; // Fixed colour
case 2: colour = BLUE; break; // Fixed colour
case 3: colour = rainbow(map(i, -angle, angle, 0, 127)); break; // Full spectrum blue to red
case 4: colour = rainbow(map(i, -angle, angle, 63, 127)); break; // 0x07e0 to red (high temperature etc)
case 5: colour = rainbow(map(i, -angle, angle, 127, 63)); break; // Red to 0x07e0 (low battery etc)
default: colour = BLUE; break; // Fixed colour
}
// Calculate pair of coordinates for segment start
float sx = cos((i - 90) * 0.0174532925);
float sy = sin((i - 90) * 0.0174532925);
uint16_t x0 = sx * (r - w) + x;
uint16_t y0 = sy * (r - w) + y;
uint16_t x1 = sx * r + x;
uint16_t y1 = sy * r + y;
// Calculate pair of coordinates for segment end
float sx2 = cos((i + seg - 90) * 0.0174532925);
float sy2 = sin((i + seg - 90) * 0.0174532925);
int x2 = sx2 * (r - w) + x;
int y2 = sy2 * (r - w) + y;
int x3 = sx2 * r + x;
int y3 = sy2 * r + y;
if (i < v) { // Fill in coloured segments with 2 triangles
tft.setColor(colour);
geo.fillTriangle(x0, y0, x1, y1, x2, y2);
geo.fillTriangle(x1, y1, x2, y2, x3, y3);
text_colour = colour; // Save the last colour drawn
}
else // Fill in blank segments
{
tft.setColor(DARKGREY);
geo.fillTriangle(x0, y0, x1, y1, x2, y2);
geo.fillTriangle(x1, y1, x2, y2, x3, y3);
}
}
}
// #########################################################################
// Return a 16 bit rainbow colour
// #########################################################################
unsigned int rainbow(byte value)
{
// Value is expected to be in range 0-127
// The value is converted to a spectrum colour from 0 = blue through to 127 = red
byte red = 0; // Red is the top 5 bits of a 16 bit colour value
byte green = 0;// 0x07e0 is the middle 6 bits
byte blue = 0; // Blue is the bottom 5 bits
byte quadrant = value / 32;
if (quadrant == 0) {
blue = 31;
green = 2 * (value % 32);
red = 0;
}
if (quadrant == 1) {
blue = 31 - (value % 32);
green = 63;
red = 0;
}
if (quadrant == 2) {
blue = 0;
green = 63;
red = value % 32;
}
if (quadrant == 3) {
blue = 0;
green = 63 - 2 * (value % 32);
red = 31;
}
return (red << 11) + (green << 5) + blue;
}
//#######################################################
//Nivelierung
//#######################################################
void getLevel()
{
xyzFloat corrAngles = myAcc.getCorrAngles();
tft.setColor(0x07e0);
tft.fillCircle(400, 185, 50);
tft.setColor(0x0000);
tft.drawCircle(400, 185, 10);
tft.setColor(0xFFFF);
tft.drawCircle(400, 185, 51);
tft.setFont(BigFont);
//Variablen für Berechnungen definieren
int Achsabstand = 410;
int Radstand = 165;
//Links Keile
if (corrAngles.x > abwlr and corrAngles.y<abwhv and corrAngles.y> abwhv * -1)
{
if (corrAngles.x > 10 and corrAngles.y<abwhv and corrAngles.y> abwhv * -1)
{
corrAngles.x = 10;
}
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Links ", 70, 320);
links = (sin(corrAngles.x * rad)) * Radstand;
tft.printNumF(links, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(RED);
tft.fillRect(301, 101, 359, 119);
tft.setColor(GREEN);
tft.fillRect(301, 251, 359, 269);
tft.setColor(RED);
tft.fillRect(11, 101, 69, 119);
tft.setColor(GREEN);
tft.fillRect(11, 251, 69, 269);
}
//Rechts Keile
if (corrAngles.x < abwlr * -1 and corrAngles.y<abwhv and corrAngles.y> abwhv * -1)
{
if (corrAngles.x < -10 and corrAngles.y<abwhv and corrAngles.y> abwhv * -1)
{
corrAngles.x = -10;
}
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Rechts ", 70, 320);
rechts = (sin(corrAngles.x * -1 * rad)) * Radstand;
tft.printNumF(rechts, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(GREEN);
tft.fillRect(301, 101, 359, 119);
tft.setColor(RED);
tft.fillRect(301, 251, 359, 269);
tft.setColor(GREEN);
tft.fillRect(11, 101, 69, 119);
tft.setColor(RED);
tft.fillRect(11, 251, 69, 269);
}
//Vorne Keile
if (corrAngles.y < abwhv * -1 and corrAngles.x<abwlr and corrAngles.x> abwlr * -1)
{
if (corrAngles.y < - 10 and corrAngles.x<abwlr and corrAngles.x> abwlr * -1)
{
corrAngles.y = -10;
}
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Vorne ", 70, 320);
vorne = (sin(corrAngles.y * -1 * rad)) * Achsabstand;
tft.printNumF(vorne, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(RED);
tft.fillRect(301, 101, 359, 119);
tft.setColor(RED);
tft.fillRect(301, 251, 359, 269);
tft.setColor(GREEN);
tft.fillRect(11, 101, 69, 119);
tft.setColor(GREEN);
tft.fillRect(11, 251, 69, 269);
}
//Hinten Keile
if (corrAngles.y > abwhv and corrAngles.x<abwlr and corrAngles.x> abwlr * -1)
{
if (corrAngles.y > 10 and corrAngles.x<abwlr and corrAngles.x> abwlr * -1)
{
corrAngles.y = 10;
}
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Hinten ", 70, 320);
hinten = (sin(corrAngles.y * rad)) * Achsabstand;
tft.printNumF(hinten, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(GREEN);
tft.fillRect(301, 101, 359, 119);
tft.setColor(GREEN);
tft.fillRect(301, 251, 359, 269);
tft.setColor(RED);
tft.fillRect(11, 101, 69, 119);
tft.setColor(RED);
tft.fillRect(11, 251, 69, 269);
}
//Hinten Links Keile
if (corrAngles.x > abwlr and corrAngles.y > abwhv)
{
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Hinten Links ca. ", 70, 320);
hinten = (sin(corrAngles.y * rad)) * Achsabstand;
links = (sin(corrAngles.x * rad)) * Radstand;
if (hinten < links)tft.printNumF(links, 1, 70, 350);
if (hinten > links)tft.printNumF(hinten, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(GREEN);
tft.fillRect(301, 101, 359, 119);
tft.setColor(GREEN);
tft.fillRect(301, 251, 359, 269);
tft.setColor(RED);
tft.fillRect(11, 101, 69, 119);
tft.setColor(GREEN);
tft.fillRect(11, 251, 69, 269);
}
//Hinten Rechts Keile
if (corrAngles.x < abwlr * -1 and corrAngles.y > abwhv)
{
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Hinten Rechts ca. ", 70, 320);
hinten = (sin(corrAngles.y * rad)) * Achsabstand;
rechts = (sin(corrAngles.x * -1 * rad)) * Radstand;
if (hinten < rechts)tft.printNumF(links, 1, 70, 350);
if (hinten > rechts)tft.printNumF(hinten, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(GREEN);
tft.fillRect(301, 101, 359, 119);
tft.setColor(GREEN);
tft.fillRect(301, 251, 359, 269);
tft.setColor(GREEN);
tft.fillRect(11, 101, 69, 119);
tft.setColor(RED);
tft.fillRect(11, 251, 69, 269);
}
//Vorne Links Keile
if (corrAngles.x > abwlr and corrAngles.y < abwhv * -1)
{
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Vorne Links ca. ", 70, 320);
vorne = (sin(corrAngles.y * -1 * rad)) * Achsabstand;
links = (sin(corrAngles.x * rad)) * Radstand;
if (vorne < links)tft.printNumF(links, 1, 70, 350);
if (vorne > links)tft.printNumF(vorne, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(RED);
tft.fillRect(301, 101, 359, 119);
tft.setColor(GREEN);
tft.fillRect(301, 251, 359, 269);
tft.setColor(GREEN);
tft.fillRect(11, 101, 69, 119);
tft.setColor(GREEN);
tft.fillRect(11, 251, 69, 269);
}
//Vorne Rechts Keile
if (corrAngles.x < abwlr * -1 and corrAngles.y < abwhv * -1)
{
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print("Vorne Rechts ca. ", 70, 320);
vorne = (sin(corrAngles.y * -1 * rad)) * Achsabstand;
rechts = (sin(corrAngles.x * -1 * rad)) * Radstand;
if (vorne < rechts)tft.printNumF(links, 1, 70, 350);
if (vorne > rechts)tft.printNumF(hinten, 1, 70, 350);
tft.print(" cm ", 110, 350);
tft.setColor(GREEN);
tft.fillRect(301, 101, 359, 119);
tft.setColor(RED);
tft.fillRect(301, 251, 359, 269);
tft.setColor(GREEN);
tft.fillRect(11, 101, 69, 119);
tft.setColor(GREEN);
tft.fillRect(11, 251, 69, 269);
}
if ((corrAngles.x < abwlr and corrAngles.x > abwlr * -1) and (corrAngles.y < abwhv and corrAngles.y > abwhv * -1))
{
tft.setColor(RED);
tft.fillCircle(400 + corrAngles.y * 4, 185 + corrAngles.x * 4, 5);
tft.print(" ", 70, 350);
tft.print(" ", 70, 320);
tft.setColor(GREEN);
tft.fillRect(11, 101, 69, 119);
tft.fillRect(11, 251, 69, 269);
tft.fillRect(301, 101, 359, 119);
tft.fillRect(301, 251, 359, 269);
}
}
//##############################################
//#Farbenbalken anzeigen
//##############################################
void farben()
{
tft.setColor(0xFFFF);
tft.drawRect(fx - 1, fy - 1, fx + 256, fy + 51);
tft.drawRect(fx - 1, fy + 99, fx + 256, fy + 151);
tft.drawRect(fx - 1, fy + 199, fx + 256, fy + 251);
cursx = 0;
for (rot = 0; rot < 255; rot++)
{
tft.setColor(rot, 0, 0);
tft.fillRect(fx + cursx, fy, fx + cursx + 1, fy + 50);
cursx++;
}
cursx = 0;
for (gruen = 0; gruen < 255; gruen++)
{
tft.setColor(0, gruen, 0);
tft.fillRect(fx + cursx, fy + 100, fx + cursx + 1, fy + 150);
cursx++;
}
cursx = 0;
for (blau = 0; blau < 255; blau++)
{
tft.setColor(0, 0, blau);
tft.fillRect(fx + cursx, fy + 200, fx + cursx + 1, fy + 250);
cursx++;
}
tx = 127;
ty = fy + 5;
readeepromColor();
tft.setColor(WHITE);
tft.setFont(Various_Symbols_32x32);
tft.print("P", fx - tft.getFontXsize() / 2 + selRot, fy - 2 - tft.getFontYsize());
tft.print("P", fx - tft.getFontXsize() / 2 + selGruen, fy + 98 - tft.getFontYsize());
tft.print("P", fx - tft.getFontXsize() / 2 + selBlau, fy + 198 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
//##############################################
//#Farben von Touchscreen
//##############################################
void Farbenwahl()
{
//Rot
if ((down == 1) and (tx >= 25) and (ty >= fy) and (tx <= 75 - 25) and (ty <= fy + 50)) //rotminus
{
down = 0;
if (selRot > 0)
{
tft.setFont(Various_Symbols_32x32);
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selRot, fy - 2 - tft.getFontYsize());
selRot = selRot - 2;
tft.setColor(WHITE);
if (selRot <= 0)selRot = 0;
tft.print("P", fx - (tft.getFontXsize() / 2) + selRot, fy - 2 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
if ((down == 1) and (tx >= 381) and (ty >= fy) and (tx <= 431 - 25) and (ty <= fy + 50)) //rotplus
{
down = 0;
if (selRot < 255)
{
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selRot, fy - 2 - tft.getFontYsize());
selRot = selRot + 2;
if (selRot >= 255)selRot = 255;
tft.setColor(WHITE);
tft.print("P", fx - (tft.getFontXsize() / 2) + selRot, fy - 2 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
//Gruen
if ((down == 1) and (tx >= 25) and (ty >= fy + 100) and (tx <= 75 - 25) and (ty <= fy + 150)) //gruenminus
{
down = 0;
if (selGruen > 0)
{
tft.setFont(Various_Symbols_32x32);
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selGruen, fy + 98 - tft.getFontYsize());
selGruen = selGruen - 2;
if (selGruen <= 0)selGruen = 0;
tft.setColor(WHITE);
tft.print("P", fx - (tft.getFontXsize() / 2) + selGruen, fy + 98 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
if ((down == 1) and (tx >= 381) and (ty >= fy + 100) and (tx <= 431 - 25) and (ty <= fy + 150)) //gruenplus
{
down = 0;
if (selGruen < 255)
{
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selGruen, fy + 98 - tft.getFontYsize());
selGruen = selGruen + 2;
if (selGruen >= 255)selGruen = 255;
tft.setColor(WHITE);
tft.print("P", fx - (tft.getFontXsize() / 2) + selGruen, fy + 98 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
//Blau
if ((down == 1) and (tx >= 25) and (ty >= fy + 200) and (tx <= 75 - 25) and (ty <= fy + 250)) //rotminus
{
down = 0;
if (selBlau > 0)
{
tft.setFont(Various_Symbols_32x32);
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selBlau, fy + 198 - tft.getFontYsize());
selBlau = selBlau - 2;
if (selBlau <= 0)selBlau = 0;
tft.setColor(WHITE);
tft.print("P", fx - (tft.getFontXsize() / 2) + selBlau, fy + 198 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
if ((down == 1) and (tx >= 381) and (ty >= fy + 200) and (tx <= 431 - 25) and (ty <= fy + 250)) //Blauplus
{
down = 0;
if (selBlau < 255)
{
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selBlau, fy + 198 - tft.getFontYsize());
selBlau = selBlau + 2;
if (selBlau >= 255)selBlau = 255;
tft.setColor(WHITE);
tft.print("P", fx - (tft.getFontXsize() / 2) + selBlau, fy + 198 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
if ((down == 1) and (tx >= 525) and (ty >= fy) and (tx <= 775) and (ty <= fy + 50)) //Vorder
{
down = 0;
Button(650, fy + 25, 250, 50, Vorder, BtnTextf, "Set", UbuntuBold);
delay(1000);
Button(650, fy + 25, 250, 50, Vorder, BtnTextf, "Hauptfarbe", UbuntuBold);
Vorder = RGB565(selRot, selGruen, selBlau);
EEPROM.update(1, selRot);
EEPROM.update(2, selGruen);
EEPROM.update(3, selBlau);
}
if ((down == 1) and (tx >= 525) and (ty >= fy + 100) and (tx <= 775) and (ty <= fy + 150)) //Schrift
{
down = 0;
Button(650, fy + 125, 250, 50, Vorder, BtnTextf, "Set", UbuntuBold);
delay(1000);
Button(650, fy + 125, 250, 50, Vorder, BtnTextf, "Textfarbe", UbuntuBold);
Schriftf = RGB565(selRot, selGruen, selBlau);
EEPROM.update(4, selRot);
EEPROM.update(5, selGruen);
EEPROM.update(6, selBlau);
}
if ((down == 1) and (tx >= 525) and (ty >= fy + 300) and (tx <= 775) and (ty <= fy + 350)) //Reset
{
down = 0;
tft.setColor(0x0000);
tft.print("P", fx - (tft.getFontXsize() / 2) + selRot, fy - 2 - tft.getFontYsize());
tft.print("P", fx - (tft.getFontXsize() / 2) + selGruen, fy + 98 - tft.getFontYsize());
tft.print("P", fx - (tft.getFontXsize() / 2) + selBlau, fy + 198 - tft.getFontYsize());
selRot = 255 / 2;
selGruen = 255 / 2;
selBlau = 255 / 2;
tft.setColor(WHITE);
tft.print("P", fx - (tft.getFontXsize() / 2) + selRot, fy - 2 - tft.getFontYsize());
tft.print("P", fx - (tft.getFontXsize() / 2) + selGruen, fy + 98 - tft.getFontYsize());
tft.print("P", fx - (tft.getFontXsize() / 2) + selBlau, fy + 198 - tft.getFontYsize());
tft.setColor(selRot, selGruen, selBlau);
tft.fillRoundRect(526, fy + 201, 774, fy + 249);
}
}
void Hoehenwahl()
{
if ( mosl <= 0) mosl = 1;
if ( mosl >= 5000) mosl = 5000;
//Höhe korrigieren
if ((down == 1) and (tx >= 25) and (ty >= 75) and (tx <= 75) and (ty <= 125)) //Höhe minus
{
down = 0;
if ( mosl > 0)
{
mosl = mosl - 10;
//DEBUGLN(mosl);
if ( mosl <= 0) mosl = 1;
tft.setFont(UbuntuBold);
tft.setColor(Schriftf);
String bText = String(mosl, 0);
bText = " " + bText + " m.u.M.";
int laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, 225 - laengeText, 100 + tft.getFontYsize() / 2);
delay(250);
}
}
if ((down == 1) and (tx >= 381) and (ty >= 75) and (tx <= 431) and (ty <= fy + 125)) //Hoehe plus
{
down = 0;
if ( mosl < 5000)
{
mosl = mosl + 10;
if ( mosl >= 5000) mosl = 5000;
tft.setFont(UbuntuBold);
tft.setColor(Schriftf);
String bText = String(mosl, 0);
bText = " " + bText + " m.u.M.";
int laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, 225 - laengeText, 100 + tft.getFontYsize() / 2);
delay(250);
}
}
if ((down == 1) and (tx >= 525) and (ty >= 75) and (tx <= 775) and (ty <= 125)) //Vorder
{
down = 0;
Button(650, 125, 250, 50, Vorder, BtnTextf, "Set", UbuntuBold);
delay(1000);
Button(650, 125, 250, 50, Vorder, BtnTextf, "Speichern", UbuntuBold);
//DEBUG("Mosl: ");
//DEBUGLN(mosl);
moslEE = mosl / 20;
int moslEEvergleich = mosl / 20;
//DEBUG("MoslEE: ");
//DEBUGLN(moslEE);
//DEBUG("MoslEEvergleich: "); DEBUGLN(moslEEvergleich);
if (moslEEvergleich < moslEE)
{
EEPROM.update(9, 1);
EEPROM.update(10, moslEE);
}
else
{
EEPROM.update(9, 0);
EEPROM.update(10, moslEE);
}
}
}
void readeepromColor()
{
selRot = EEPROM.read(4);
selGruen = EEPROM.read(5);
selBlau = EEPROM.read(6);
Schriftf = RGB565(selRot, selGruen, selBlau);
selRot = EEPROM.read(1);
selGruen = EEPROM.read(2);
selBlau = EEPROM.read(3);
Vorder = RGB565(selRot, selGruen, selBlau);
}
void drawSlider(int x, int y, int slideLength, int sliderWidth, int sliderHeight, int color, int bordercolor)
{
tft.setColor(color);
tft.drawRect(x - sliderWidth / 2 - 1, y - sliderHeight / 2 - 1, slideLength + sliderWidth / 2 + 1 + x, sliderHeight + 2 + y);
tft.fillRect(x - sliderWidth / 2 + 1 / 2, y - sliderHeight / 2 + 1 / 2, sliderWidth - 2, sliderHeight - 2);
tft.setColor(bordercolor);
tft.drawRect(x - sliderWidth / 2, y - sliderHeight / 2, sliderWidth, sliderHeight);
}
void drawSwitch (int x, int y, int swLength, int swWidth, int color, int swStatus)
{
if (swStatus == 0)
{
tft.setColor(Vorder);
tft.drawRoundRect(x, y - swWidth / 2, swLength + x, swWidth / 2 + y);
tft.fillRoundRect(x + 2, y - swWidth / 2 + 2, x + swLength / 5, swWidth / 2 + y - 2);
tft.setColor(0x0000);
tft.fillRoundRect(x + swLength - swLength / 5, y - swWidth / 2 + 2, x + swLength - 2, swWidth / 2 + y - 2);
}
if (swStatus == 1)
{
tft.setColor(Vorder);
tft.drawRoundRect(x, y - swWidth / 2, swLength + x, swWidth / 2 + y);
tft.fillRoundRect(x + swLength - swLength / 5, y - swWidth / 2 + 2, x + swLength - 2, swWidth / 2 + y - 2);
tft.setColor(0x0000);
tft.fillRoundRect(x + 2, y - swWidth / 2 + 2, x + swLength / 5, swWidth / 2 + y - 2);
}
}
void Wechselrichter()
{
if ((wechselrichterStatus = true))
wechselrichterStatus = false;
else if ((wechselrichterStatus = false))
wechselrichterStatus = true;
}
void showSolar200()
{
Serial.println("------ -200W------");
Serial.print("Produkt ID : ");
Serial.println(PID200);
Serial.print("Firmware : ");
Serial.println(FW200);
Serial.print("Serien#: ");
Serial.println(SER200);
Serial.print("Betteriespannung : ");
Serial.print(V200);
Serial.println(" V");
Serial.print("Batterie Ladestrom : ");
Serial.print(Ib200);
Serial.println(" A");
Serial.print("Solarspannung : ");
Serial.print(VPV200);
Serial.println(" V");
Serial.print("Solarleistung : ");
Serial.print(PPV200);
Serial.println(" W");
Serial.print("Ladestatus : ");
Serial.print(CS200);
Serial.println(" -> 0 = Aus, 2 = Err, 3 = Lad, 4 = Entl, 5 = halten");
Serial.print("MPPT : ");
Serial.println(MPPT200);
Serial.print("OR : ");
Serial.println(OR200);
Serial.print("Error : ");
Serial.print(ERR200);
Serial.println(" -> 0 = OK, 2 = Batt V zu hoch, 17 = Temp zu hoch, 18 = Überstrom, 21 = Amp Sensor Fehler, 33 = Solar V zu hoch, 34 = Solar A zu hoch");
Serial.print("Lastausgang : ");
Serial.println(LOAD200);
Serial.print("Lastausgang Strom : ");
Serial.print(IL200);
Serial.println(" A");
Serial.print("Ertrag gesamt : ");
Serial.print(H19200);
Serial.println(" kWh");
Serial.print("Ertrag heute : ");
Serial.print(H20200);
Serial.println(" Wh");
Serial.print("Maximalleistung heute : ");
Serial.print(H21200);
Serial.println(" W");
Serial.print("Leistung gestern : ");
Serial.print(H22200);
Serial.println(" Wh");
Serial.print("Maximalleistung gestern : ");
Serial.print(H23200);
Serial.println(" W");
Serial.print("HSDS : ");
Serial.println(HSDS200);
}
void showSolar160()
{
Serial.println("------ -160W------");
Serial.print("Produkt ID : ");
Serial.println(PID160);
Serial.print("Firmware : ");
Serial.println(FW160);
Serial.print("Serien#: ");
Serial.println(SER160);
Serial.print("Betteriespannung : ");
Serial.print(V160);
Serial.println(" V");
Serial.print("Batterie Ladestrom : ");
Serial.print(Ib160);
Serial.println(" A");
Serial.print("Solarspannung : ");
Serial.print(VPV160);
Serial.println(" V");
Serial.print("Solarleistung : ");
Serial.print(PPV160);
Serial.println(" W");
Serial.print("Ladestatus : ");
Serial.print(CS160);
Serial.println(" -> 0 = Aus, 2 = Err, 3 = Lad, 4 = Entl, 5 = halten");
Serial.print("MPPT : ");
Serial.println(MPPT160);
Serial.print("OR : ");
Serial.println(OR160);
Serial.print("Error : ");
Serial.print(ERR160);
Serial.println(" -> 0 = OK, 2 = Batt V zu hoch, 17 = Temp zu hoch, 18 = Überstrom, 21 = Amp Sensor Fehler, 33 = Solar V zu hoch, 34 = Solar A zu hoch");
Serial.print("Lastausgang : ");
Serial.println(LOAD160);
Serial.print("Lastausgang Strom : ");
Serial.print(IL160);
Serial.println(" A");
Serial.print("Ertrag gesamt : ");
Serial.print(H19160);
Serial.println(" kWh");
Serial.print("Ertrag heute : ");
Serial.print(H20160);
Serial.println(" Wh");
Serial.print("Maximalleistung heute : ");
Serial.print(H21160);
Serial.println(" W");
Serial.print("Leistung gestern : ");
Serial.print(H22160);
Serial.println(" Wh");
Serial.print("Maximalleistung gestern : ");
Serial.print(H23160);
Serial.println(" W");
Serial.print("HSDS : ");
Serial.println(HSDS160);
}
void getSolar200()
{
if (Serial1.available() > 10) {
label200 = Serial1.readStringUntil('\t');
val200 = Serial1.readStringUntil('\r\r\n');
if (label200 == "PID") {
PID200 = val200;
} else if (label200 == "FW") {
FW200 = val200;
} else if (label200 == "SER#") {
SER200 = val200;
} else if (label200 == "V") {
float temp = val200.toFloat();
temp = temp / 1000;
V200 = temp;
} else if (label200 == "I") {
float temp = val200.toFloat();
temp = temp / 10000;
Ib200 = val200.toFloat();
} else if (label200 == "VPV") {
float temp = val200.toFloat();
temp = temp / 1000;
VPV200 = temp;
} else if (label200 == "PPV") {
PPV200 = val200.toFloat();
} else if (label200 == "CS") {
CS200 = val200.toInt();
} else if (label200 == "MPPT") {
MPPT200 = val200;
} else if (label200 == "OR") {
OR200 = val200;
} else if (label200 == "ERR") {
ERR200 = val200.toInt();
} else if (label200 == "LOAD") {
LOAD200 = val200.toFloat();
} else if (label200 == "IL") {
IL200 = val200.toFloat();
} else if (label200 == "H19") {
int temp = val200.toInt();
temp = temp / 10;
H19200 = temp;
} else if (label200 == "H20") {
int temp = val200.toInt();
temp = temp / 10;
H20200 = temp;
} else if (label200 == "H21") {
float temp = val200.toFloat();
temp = temp / 1000;
H21200 = val200.toInt();
} else if (label200 == "H22") {
int temp = val200.toInt();
temp = temp / 10;
H22200 = temp;
} else if (label200 == "H23") {
float temp = val200.toFloat();
temp = temp / 1000;
H23200 = val200.toInt();
} else if (label200 == "HSDS") {
float temp = val200.toFloat();
temp = temp / 100;
HSDS200 = val200.toInt();
}
}
}
void getSolar160()
{
if (Serial1.available() > 10) {
label160 = Serial1.readStringUntil('\t');
val160 = Serial1.readStringUntil('\r\r\n');
if (label160 == "PID") {
PID160 = val160;
} else if (label160 == "FW") {
FW160 = val160;
} else if (label160 == "SER#") {
SER160 = val160;
} else if (label160 == "V") {
float temp = val160.toFloat();
temp = temp / 1000;
V160 = temp;
} else if (label160 == "I") {
float temp = val160.toFloat();
temp = temp / 10000;
Ib160 = val160.toFloat();
} else if (label160 == "VPV") {
float temp = val160.toFloat();
temp = temp / 1000;
VPV160 = temp;
} else if (label160 == "PPV") {
PPV160 = val160.toFloat();
} else if (label160 == "CS") {
CS160 = val160.toInt();
} else if (label160 == "MPPT") {
MPPT160 = val160;
} else if (label160 == "OR") {
OR160 = val160;
} else if (label160 == "ERR") {
ERR160 = val160.toInt();
} else if (label160 == "LOAD") {
LOAD160 = val160.toFloat();
} else if (label160 == "IL") {
IL160 = val160.toFloat();
} else if (label160 == "H19") {
int temp = val160.toInt();
temp = temp / 10;
H19160 = temp;
} else if (label160 == "H20") {
int temp = val160.toInt();
temp = temp / 10;
H20160 = temp;
} else if (label160 == "H21") {
float temp = val160.toFloat();
temp = temp / 1000;
H21160 = val160.toInt();
} else if (label160 == "H22") {
int temp = val160.toInt();
temp = temp / 10;
H22160 = temp;
} else if (label160 == "H23") {
float temp = val160.toFloat();
temp = temp / 1000;
H23160 = val160.toInt();
} else if (label160 == "HSDS") {
float temp = val160.toFloat();
temp = temp / 100;
HSDS160 = val160.toInt();
}
}
}
void updateSolarWerte()
{
for (int r = 0; r < 5; r++)
{
getSolar200();
getSolar160();
}
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
tft.printNumF(V200, 2, 360, 50);
tft.printNumF(Ib200 + Ib160, 2, 360, 100);
tft.printNumF(H19200 + H19160, 0, 360, 150);
tft.printNumF(H20200 + H20160, 0, 360, 200);
tft.printNumF(H21200 + H21160, 0, 360, 250);
tft.printNumF(H22200 + H22160, 0, 360, 300);
tft.printNumF(H23200 + H23160, 0, 360, 350);
hbp();
label200 = "0";
label160 = "0";
}
void updateSolarScreen()
{
for (int r = 0; r < 200; r++)
{
getSolar200();
getSolar160();
}
//Volts
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
String bText = String((VPV200 + VPV160) / 2);
int laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, displayX / 4 - laengeText - 50, displayY / 2 - tft.getFontYsize() / 2);
tft.print("V", displayX / 4 + laengeText - 50, displayY / 2 - tft.getFontYsize() / 2);
ringMeter((VPV200 + VPV160) / 2, 12, 45, displayX / 4 - radius - 50, displayY / 2 - radius, radius, RED2GREEN );
//Amps
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
bText = String((PPV200 + PPV160) / (VPV200 + VPV160) / 2);
laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, displayX / 2 - laengeText, displayY / 2 - tft.getFontYsize() / 2);
tft.print("A", displayX / 2 + laengeText, displayY / 2 - tft.getFontYsize() / 2);
ringMeter((PPV200 + PPV160) / (VPV200 + VPV160) / 2, 0, 20, displayX / 2 - radius, displayY / 2 - radius, radius, RED2GREEN );
//Watts
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
bText = String((PPV200 + PPV160), 0);
laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print(bText, displayX / 4 * 3 - laengeText + 50, displayY / 2 - tft.getFontYsize() / 2);
tft.print("W", displayX / 4 * 3 + laengeText + 50, displayY / 2 - tft.getFontYsize() / 2);
ringMeter(PPV200 + PPV160, 1, 360, displayX / 4 * 3 - radius + 50, displayY / 2 - radius, radius, RED2GREEN );
label200 = "0";
label160 = "0";
}
void updateBatterie()
{
getBordbatterie();
getSolar200();
int radius = 150;
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
String bText = "Aufbaubatterie";
int laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print("Aufbaubatterie", displayX / 4 - laengeText, 50);
String V200text = String(V200);
laengeText = (V200text.length() * tft.getFontXsize() / 2);
tft.print(V200text, displayX / 4 - laengeText, displayY / 2 - tft.getFontYsize() / 2);
tft.print("V", displayX / 4 + laengeText, displayY / 2 - tft.getFontYsize() / 2);
ringMeter(V200, 11.6, 14.4, displayX / 4 - radius, displayY / 2 - radius, radius, RED2GREEN );
//Bordbatterie
tft.setColor(Schriftf);
tft.setBackColor(0x0000);
tft.setFont(BigFont);
bText = "Bordbatterie";
laengeText = bText.length() * tft.getFontXsize() / 2;
tft.print("Bordbatterie", displayX / 4 * 3 - laengeText, 50);
String Bordtext = String(Bordbatterie / 100);
laengeText = (Bordtext.length() * tft.getFontXsize() / 2);
tft.print(Bordtext, displayX / 4 * 3 - laengeText, displayY / 2 - tft.getFontYsize() / 2);
tft.print("V", displayX / 4 * 3 + laengeText, displayY / 2 - tft.getFontYsize() / 2);
ringMeter(Bordbatterie, 1100, 1500, displayX / 4 * 3 - radius, displayY / 2 - radius, radius, RED2GREEN );
label200 = "0";
}
void getBaroTrend()
{
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
if (b == 99)
{
bme.read(pres, temp, hum, tempUnit, presUnit);
sealevelKorr = (1013.25 * pow((1 - 6.5 * mosl / (288150)), 5.255));
sealevelKorr = 1013.25 - sealevelKorr;
//DEBUG("SLK+99: "); DEBUGLN(sealevelKorr);
baro[b] = pres / 100 + sealevelKorr;
//DEBUG("Baro+99: "); DEBUGLN(baro[b]);
b--;
}
if ((b >= 0) and (b < 99))
{
baro[b] = baro[b + 1];
bme.read(pres, temp, hum, tempUnit, presUnit);
sealevelKorr = (1013.25 * pow((1 - 6.5 * mosl / (288150)), 5.255));
sealevelKorr = 1013.25 - sealevelKorr;
//DEBUG("SLK: "); DEBUGLN(sealevelKorr);
baro[b + 1] = pres / 100 + sealevelKorr;
//DEBUG("Baro: "); DEBUGLN(baro[b] + 1);
b--;
}
else
{
for (int Fifo = 0; Fifo < 99; Fifo++)
{
baro[Fifo] = baro[Fifo + 1];
}
bme.read(pres, temp, hum, tempUnit, presUnit);
baro[99] = pres + 9840;
}
}
void getTouched()
{
// See if there's any touch data for us
if (ts.touched())
{
// Retrieve a point
TS_Point p = ts.getPoint();
down = 1;
//DEBUG("touch down: ");
//DEBUGLN(down);
ty = p.y - offsetY;
tx = p.x;
//DEBUG("tx: ");
//DEBUGLN(tx);
//DEBUG("ty: ");
//DEBUGLN(ty);
timeoutloop = millis();
}
}
void Button(int x, int y, int btnX, int btnY, int colorF, int colorS, String btnText, uint8_t *Schrift)
{
tft.setColor(colorF);
tft.fillRoundRect(x - btnX / 2, y - btnY / 2, x + btnX / 2, y + btnY / 2);
tft.setColor(WHITE);
tft.drawRoundRect(x - btnX / 2, y - btnY / 2, x + btnX / 2, y + btnY / 2);
tft.setColor(colorS);
tft.setBackColor(colorF);
tft.setFont(Schrift);
int textlength, textheight, laenge;
laenge = btnText.length();
textlength = tft.getFontXsize() * laenge;
textheight = tft.getFontYsize();
tft.print(btnText, x - textlength / 2, y - textheight / 2 + 2);
tft.setBackColor(0x0000);
tx = 0;
ty = 0;
}
void watchdogSetup(void)
{
cli(); // disable all interrupts
asm("WDR"); // watchdog reset
Serial.println("Watchdog setup complete");
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = (1 << WDE) | (1 << WDP3) | (1 << WDP0); // 4s / no interrupt, system reset
sei();
}
Dann noch das Fritzing Schema:
und ein paar Eindrücke:
Nun denn, lasset die Diskusion beginnen. Ich bin auch für kreative Vorschläge was dieDarstellung betrifft offen. Der Nivelierungsbildschirm gefällt mir noch nicht wirklich.
Als Amateur habe ich natürlich vieles nach der Holzhackermethode programmiert, aber soweit läuft alles. Die Nivelierfunktion ist sehr umfangreich, da fehlt mir aber noch das know-how um das abzukürzen. Und ja, ich habs grad gesehen, da ist wohl ein Hund über den Screen gelaufen.