Ahhh.
Dann gehört da keine Seite auf dem HMI dazu, sondern einfach nur ne Variable....
Wobei...
Wenn Du anhand der Variablen eh nur einen Pin switcht, dann toggle den Pin ohne Variable.
Wenn Du den State des Motorpins brauchst, dann frage den direkt ab.
Spart ne Variable und ist übersichtlicher...
// Forensketch - Übernahme und Übergabe via Multi-Serial mit Zwischenberechnung
// https://forum.arduino.cc/t/arduino-mega-probleme-mit-serieller-schnittstellenausgabe/1064303
//
// basiert auf https://forum.arduino.cc/t/arduino-mega-probleme-mit-serieller-schnittstellenausgabe/1064303/39
#include "EasyNextionLibrary.h"
EasyNex myNex(Serial1); // Zum debuggen Serial, zum Produktiv Serial1
constexpr byte motorPin {12}; // ist typsicher - entspricht const byte motorPin = 12;
enum SEITE {hauptmenu, sport, eco, einstellungen, ladeansicht, batuebersicht, notaus};
byte seite = SEITE::hauptmenu; // Entweder
//byte seite = SEITE::batuebersicht; // Oder
enum LICHT {off, on, automatik};
byte licht = LICHT::off;
byte bmsHeader;
char bmsMessage[10];
uint16_t bmsValue;
// bool motorState = false; //Philipp ergänzt
bool notAusState = false;
bool schuetzState = false;
bool chargeState = false;
uint16_t gasPedalValue;
uint16_t ladeZustandValue;
uint16_t zwoelfVoltValue;
void setup()
{
Serial.begin(115200); //Serial 0 für Debuggen
myNex.begin(9600);
Serial2.begin(4800); //Serial 2 für BMS
}
void loop()
{
readFromBMS();
myNex.NextionListen(); //Philipp ergänzt
writeFromBMS();
}
void readFromBMS()
{
static char buf[100] = {'\0'}; // Puffer vorbereiten
static byte index = 0; // Index vorbereiten
if (Serial2.available() > 0) // Zeichen vorhanden?
{
char c = Serial2.read(); // Zeichen lesen
if (!isControl(c)) // kein Steuerzeichen?
{
buf[index] = c; // aufnehmen
index++; // Nächste Position setzen
}
else if (index > 1) // index ist gefüllt?
{
char header[3] = {'\0'}; // zwischenspeicher
strncpy(header, buf, 2); // füllen
bmsHeader = atoi(header); // Value errechnen
strncpy(bmsMessage, buf + 2, 5); // Rest als Text aufnehmen
char const *pos = strchr( bmsMessage, '.' ); // Ist Zeichen enthalten?
bmsValue = pos ? atof(bmsMessage) * 100 : atoi(bmsMessage); // dann wirds entweder multipliziert oder nicht
memset(buf, '\0', sizeof(buf)); // Buffer löschen
index = 0;
}
}
}
void writeFromBMS()
{
char buf[10] = {'\0'}; // buffer vorbereiten
// *INDENT-OFF*
if (bmsHeader == 0) { return; } // Wenn nichts enthalten-> abbruch
if (seite == SEITE::batuebersicht) // Nur wenn Batterieanzeige
{
switch (bmsHeader)
{
case 1 ... 16: sprintf(buf, "SZ%d", bmsHeader); break; // buffer füllen
case 17: sprintf(buf, "SZges"); break;
case 18: sprintf(buf, "SZmin"); break;
case 19: sprintf(buf, "SZmax"); break;
case 27: sprintf(buf, "fan"); break;
case 31: sprintf(buf, "Tinv"); break;
case 32: sprintf(buf, "Tumg"); break;
case 33: sprintf(buf, "Tmot"); break;
case 34: sprintf(buf, "Tbox"); break;
case 35: sprintf(buf, "Tba1"); break;
case 36: sprintf(buf, "Tba2"); break;
case 37: sprintf(buf, "Tbam"); break;
}
strcat(buf, ".val"); // buffer vervollständigen
Serial.print(buf);
Serial.print(' ');
Serial.println(bmsValue);
myNex.writeNum(buf, bmsValue); // ausgeben
}
else // wenn nicht Batterieanzeige
{
switch (bmsHeader)
{
case 20: evalSchuetz(bmsValue); break; // übergeben
case 21: evalChargeValue(bmsValue); break;
// case 23: evalLiveTimer(bmsValue); break;
case 25: evalChargeStatus(bmsValue); break;
case 26: auswertung_notaus(bmsValue); break;
}
}
// *INDENT-ON*
bmsHeader = 0; // löschen
}
//
//Schütze offen oder geschlossen
void evalSchuetz(const bool isSchuetz)
{
if (isSchuetz)
{
if (!schuetzState)
{
schuetzState = true;
Serial.println(F("Schuetz gesetzt"));
}
}
else if (schuetzState)
{
schuetzState = false;
Serial.println(F("Schuetz gelöscht"));
}
}
//
void auswertung_notaus(const bool isNotAus)
{
if (isNotAus && !notAusState)
{
myNex.writeStr("page 9");
notAusState = true;
}
else if (isNotAus != notAusState)
{
myNex.writeStr("page 0");
notAusState = false;
}
}
//
//Auswertung und Ausgabe von der Gaspedalstellung ans Display
void powermeter(const uint16_t myValue)
{
if (schuetzState)
{
float hilfe = 0;
if (seite == SEITE::sport)
{
hilfe = float(myValue) / 4.608108108108108; //Wertebereich 0-5V = 0-1023;
//Rechenweg: min 69, max 291, Differenz 222, 1023/222=4.608108108108108/1 Schritt
}
else if (seite == SEITE::eco)
{
hilfe = float(myValue) / 6.642857142857143; //Wertebereich 0-5V = 0-1023;
//Rechenweg: min 69, max 223, Differenz 154, 1023/154=6.642857142857143/1 Schritt
}
gasPedalValue = hilfe + 69;
}
else
{
gasPedalValue = 0;
}
}
//
void evalChargeValue(const uint16_t myValue)
{
//Serial.println(i);
ladeZustandValue = myValue;
//Serial.println(ladeZustandValue);
}
//
void auswertung_12V(const uint16_t myValue)
{
float hilfe = float(myValue) * 0.0141739980449658; //Rechenweg -> 14.5 (Max.Voltage) / 1023 = 0.0141739980449658
zwoelfVoltValue = hilfe * 100;
}
//
/*
void evalLiveTimer(int i) //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
{
if (i != alivetimecounter)
{
alivetimecounter = i;
}
else if (i == alivetimecounter)
{
myObject.writeStr("page 8");
}
}
*/
//Laden aktiv oder inaktiv
void evalChargeStatus(const bool myValue)
{
if (!myValue && chargeState)
{
myNex.writeStr("page 0");
chargeState = false;
}
else if (chargeState != myValue)
{
myNex.writeStr("page 5");
chargeState = true;
}
}
//Triggersignale vom Display //Philipp ergänzt ab hier
void trigger0() //Motor
{
digitalWrite(motorPin, !digitalRead(motorPin));
// motorState = !motorState;
Serial.print(F("Motor: "));
Serial.println(digitalRead(motorPin));
}
void trigger1() //Sportansicht
{
seite = SEITE::sport;
//Serial.println("Sport");
}
void trigger2() //Ecoansicht
{
seite = SEITE::eco;
//Serial.println("ECO");
}
void trigger3() //Light ON
{
licht = LICHT::on;
//Serial.println("Licht: EIN");
}
void trigger4() //Light OFF
{
licht = LICHT::off;
//Serial.println("Licht: AUS");
}
void trigger5() //Light AUTO
{
licht = LICHT::automatik;
//Serial.println("Licht: AUTO");
}
void trigger6() //Batterieuebersicht
{
seite = SEITE::batuebersicht;
//Serial.println("Batterieuebersicht");
}
void trigger7() //Ladeansicht
{
seite = SEITE::ladeansicht;
//Serial.println("Ladeansicht");
}
void trigger8() //Hauptmenüseite
{
seite = SEITE::hauptmenu;
//Serial.println("Hauptmenue");
}
void trigger9() //Einstellungsseite
{
seite = SEITE::einstellungen;
//Serial.println("Einstellungen");
}
/*void trigger10() //Notausseite
{
seite = SEITE::notaus;
}*/
Einige Änderungen drin.
Und jetzt ist Schluß für mich.
Ich nehm den Code jetzt so mit und schau mal, ob später noch Zeit bleibt.
Ich wünsch was fettes nachher auf'm Tisch.
Wie es geht kannst hier nachlesen