Guten Abend,
für unser Studienprojekt bauen wir ein Elektrokart.
Des Aufbau wo, indem unser Problemfall vorliegt, ist folgender:
BMS -> Serielle Schnittstelle 1 (2400 Baud) -> Arduino Mega 2560 -> Serielle Schnittstelle "0" (9600 Baud) -> Nextion NX8048P070-011
Das BMS nimmt Daten der Batterie auf, der Mega schickt diese weiter bzw. verarbeitet sie und das Display gibt diese aus.
Info, aber nicht relevant: Die Baudrate zwischen BMS und Mega ist deswegen so gering, weil bisher ansonsten Teilstücke der Nachrichten nicht richtig eingelesen werden und es zu Problemen führt.
Der Mega wird zum Steuern weiterer Funktionen am Kart benötigt und ist somit unumgänglich.
Es liest z.B. auch über den Hallsensor unsere Geschwindigkeit ein und steuert das Licht.
Problemstellung
Das Problem befindet sich zwischen dem Mega und dem Nextion.
Die Daten vom BMS empfangen, auswerten und weiterschicken funktioniert einwandfrei -> Daten gelangen richtig ans Display über die Switch Case Funktion.
Sobald aber lediglich eine Nachricht (im Code zu finden unter dem Switch Case hier Beispielhaft "Powermeter") außerhalb der Switch Case auf den Bus zum Display geschickt wird, kommt nur noch Müll am Display an.
Fragestellung
Wieso kann diese eine zusätzliche Botschaft, außerhalb der des Switch Case die Datenübertragung so durcheinander bringen und welche Abhilfe gibt es??
Wir benötigen zwingend die Ausgabe weiterer Daten an das Display, die z.B. nicht über das BMS eingespeist werden, sondern direkt vom Mega kommen (z.B. die Geschwindigkeit über Hallsensor, welcher direkt am Mega hängt).
Ich bin sehr gespannt auf euer konstruktive Meinung und hoffe dadurch wieder etwas dazuzulernen!
LG
Philipp
/*
Fehler: Sobald Botschaften innerhalb der Loop, aber außerhalt dem Switch Case auf die Serielle Schnittstelle zum Display gelegt werden, kommt es zu Problemen!
*/
//*********************************************************************************************************
// Bibliothek einbinden
#include "EasyNextionLibrary.h"
//*********************************************************************************************************
// Serielle Kommunikation festlegen
EasyNex myObject(Serial);
//*********************************************************************************************************
// Globale Variable definieren
//Taster Display
int flag_motor = 0;
int flag_sportansicht = 0;
int flag_ecoansicht = 0;
int flag_lightON = 0;
int flag_lightOFF = 1;
int flag_lightAUTO = 0;
//Hilfsvariablen
int licht_relais = 11;
int motor_relais = 12;
int LED = 13;
int eingang_fotodiode = A0;
int wert_fotodiode = 0;
byte eingang_hallsensor = 21;
int anzahl_flanken = 0;
//char zeilenumbruch = '\n';
//Daten vom BMS
int cell_temp1 = 0;
int cell_temp2 = 0;
int cell_temp3 = 0;
int cell_temp4 = 0;
int cell_volt1 = 0;
int cell_volt2 = 0;
int cell_volt3 = 0;
int cell_volt4 = 0;
int cell_volt5 = 0;
int cell_volt6 = 0;
int cell_volt7 = 0;
int cell_volt8 = 0;
int cell_volt9 = 0;
int cell_volt10 = 0;
int cell_volt11 = 0;
int cell_volt12 = 0;
int cell_volt13 = 0;
int cell_volt14 = 0;
int cell_volt15 = 0;
int cell_volt16 = 0;
int cell_volt_min = 0;
int cell_volt_max = 0;
int cell_volt_ges = 0;
int batterieschuetz = 0; //0 = offen, 0 = geschlossen
int powermeter = 69; //0 = Off; 69 = Ready
int ladezustand = 0;
int ladenaktiv = 0;
//Kommunikation mit BMS
int data = 0;
String eingang_BMS = "";
String zwischenspeicher_BMS = "";
int header_BMS = 0;
float botschaft_BMS = 0.0;
//*********************************************************************************************************
//Funktionsdefinitionen
//Motor Ein/Aus
void motorsteuerung (int i)
{
if(i % 2 == 1)
{
digitalWrite(motor_relais, LOW);
}
else
{
digitalWrite(motor_relais, HIGH);
}
}
//Lichtsteuerung
void lichtsteuerung (int an, int aus, int automatik)
{
if(aus == 1)
{
digitalWrite(licht_relais, HIGH);
}
else if(an == 1)
{
digitalWrite(licht_relais, LOW);
}
else
{
wert_fotodiode = analogRead(eingang_fotodiode);
if(wert_fotodiode > 250)
{
digitalWrite(licht_relais, LOW);
}
else
{
digitalWrite(licht_relais, HIGH);
}
}
}
//Flankenzaehler Hallsensor
void flankenzaehler_hallsensor()
{
anzahl_flanken++;
}
//Drehzahlberechnung
void drehzahlberechnung(int i)
{
i = i / 3;
//Serial.print("Drehzahl = ");
//Serial.println(i);
}
//Laden aktiv oder inaktiv
void ladeansicht(int i)
{
if(i == ladenaktiv)
{
}
else if(i == 0 & ladenaktiv == 1)
{
myObject.writeStr("page 0");
ladenaktiv = 0;
}
else
{
myObject.writeStr("page 5");
ladenaktiv = 1;
}
}
//Schütze offen oder geschlossen
/*void schuetzauswertung(int i)
{
if(i == batterieschuetz)
{
}
else if(i == 1 & batterieschuetz == 0)
{
powermeter = 69;
batterieschuetz = 1;
}
else if(i == 0 & batterieschuetz == 1)
{
powermeter = 0;
batterieschuetz = 0;
}
}*/
//*********************************************************************************************************
void setup()
{
//Baudrate festlegen für Serielle Schnittstellen
myObject.begin(9600);
Serial1.begin(2400);
//Eingänge festlegen
pinMode(eingang_hallsensor,INPUT_PULLUP);
//Ausgänge festlegen
pinMode(motor_relais, OUTPUT);
pinMode(licht_relais, OUTPUT);
pinMode(LED, OUTPUT);
//Interrupts aufrufen
attachInterrupt(digitalPinToInterrupt(eingang_hallsensor), flankenzaehler_hallsensor, FALLING);
// //Starte Interrupt Timer
// TCCR0A=(1<<WGM01); //Set the CTC mode
// OCR0A=0xF9; //Value for ORC0A for 1ms
//
// TIMSK0|=(1<<OCIE0A); //Set the interrupt request
// sei(); //Enable interrupt
//
// TCCR0B|=(1<<CS01); //Set the prescale 1/64 clock
// TCCR0B|=(1<<CS00);
}
//*********************************************************************************************************
void loop()
{
//Zyklische Abfrage vom Display
myObject.NextionListen();
//Funktionsaufrufe
motorsteuerung(flag_motor);
lichtsteuerung(flag_lightON, flag_lightOFF, flag_lightAUTO);
drehzahlberechnung(anzahl_flanken);
//Datenempfang und Verarbeitung vom BMS
if(Serial1.available() > 0)
{
data = Serial1.read();
if (char(data) != '\n')
{
eingang_BMS += char(data);
}
else
{
zwischenspeicher_BMS = eingang_BMS;
eingang_BMS = "";
header_BMS = zwischenspeicher_BMS.substring(0,2).toInt();
botschaft_BMS = zwischenspeicher_BMS.substring(2).toFloat();
switch(header_BMS)
{
//Spannung
case 1: cell_volt1 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ1.val", cell_volt1); break;
case 2: cell_volt2 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ2.val", cell_volt2); break;
case 3: cell_volt3 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ3.val", cell_volt3); break;
case 4: cell_volt4 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ4.val", cell_volt4); break;
case 5: cell_volt5 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ5.val", cell_volt5); break;
case 6: cell_volt6 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ6.val", cell_volt6); break;
case 7: cell_volt7 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ7.val", cell_volt7); break;
case 8: cell_volt8 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ8.val", cell_volt8); break;
case 9: cell_volt9 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ9.val", cell_volt9); break;
case 10: cell_volt10 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ10.val", cell_volt10); break;
case 11: cell_volt11 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ11.val", cell_volt11); break;
case 12: cell_volt12 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ12.val", cell_volt12); break;
case 13: cell_volt13 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ13.val", cell_volt13); break;
case 14: cell_volt14 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ14.val", cell_volt14); break;
case 15: cell_volt15 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ15.val", cell_volt15); break;
case 16: cell_volt16 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ16.val", cell_volt16); break;
case 17: cell_volt14 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ14.val", cell_volt14); break;
case 18: cell_volt15 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ15.val", cell_volt15); break;
case 19: cell_volt16 = ((int)(botschaft_BMS*100)); myObject.writeNum("SZ16.val", cell_volt16); break;
//Schütze 00=offen; 01=geschlossen
//case 20: schuetzauswertung((int)botschaft_BMS); break;
//Ladezustand
case 21: ladezustand = ((int)botschaft_BMS); myObject.writeNum("Ladelevel.val", ladezustand);
myObject.writeNum("Ladezustand.val", ladezustand); break;
//Ladesituation
case 25: ladeansicht((int)botschaft_BMS); break;
//Temperatur
case 30: cell_temp1 = ((int)(botschaft_BMS*100)); myObject.writeNum("TZ1.val", cell_temp1); break;
case 31: cell_temp2 = ((int)(botschaft_BMS*100)); myObject.writeNum("TZ2.val", cell_temp2); break;
case 32: cell_temp3 = ((int)(botschaft_BMS*100)); myObject.writeNum("TZ3.val", cell_temp3); break;
case 33: cell_temp4 = ((int)(botschaft_BMS*100)); myObject.writeNum("TZ4.val", cell_temp4); break;
default: break;
}
}
}
//Powermeter
//Fehlend: Gaspedal einlesen + auswerten und Wert an Display schicken.
//Falls Schütze geschalten -> Wert + Powermeter
//Falls Schütze offen -> Powermeter darf keinen Wert übermitteln
//myObject.writeNum("PM.val", powermeter);
}
//*********************************************************************************************************
//Triggersignale vom Display
void trigger0() //Motor
{
flag_motor = flag_motor + 1;
}
void trigger1() //Sportansicht
{
//BMS Rückmelden das Sportmodus aktiv ist
}
void trigger2() //Ecoansicht
{
//BMS Rückmelden das Ecomodus aktiv ist
}
void trigger3() //Light ON
{
flag_lightON = 1;
flag_lightOFF = 0;
flag_lightAUTO = 0;
}
void trigger4() //Light OFF
{
flag_lightON = 0;
flag_lightOFF = 1;
flag_lightAUTO = 0;
}
void trigger5() //Light AUTO
{
flag_lightON = 0;
flag_lightOFF = 0;
flag_lightAUTO = 1;
}