Guten Morgen und Gutes Neues Jahr
also was ich gestern Abend noch gelernt habe, ich muss eine Request Message senden um dann spezifisch die Daten zu erhalten.
Das bekomme ich nicht hin. Anbei der ganze Code. Bitte um Nachsicht, bin Anfänger. Und ich kämpfe schon sehr viel mit dem Nextion Display - macht die grafischen Dinge einfacher als mit TFT-eSPI oder so sich herum zu schlagen.
// PINS Teensy 4.0:
// CAN 1: CRX1 (23) & CTX1 (22) = MGM ESC
// CAN 2: CRX2 (0) & CTX2 (1) = EMUS BMS
// CAN-Versorgung 3.3V & GND
// GPS TX auf RX2 (7)
// GPS RX auf TX2 (8)
// Button 14 und GND zusammen
// Display 9,10,11 und 13 und 3.3V & GND
// 2m Kabel Ethernet:
// C:\Users\LENOVO\OneDrive\Dokumente\Arduino\libraries\TFT_eSPI --> Datei "User_Setup.h" auf:
// #define SPI_FREQUENCY 36000000 einstellen, ggfs. anpassen
// HISTORIE:
// Serial in GPS Modul siehe Excel muss mit Serial in Teensy übereinstimmen
// Ausgabe UART in GPS muss Protocol out 1-NMEA oder mehr stehen
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <FlexCAN_T4.h>
#include <Streaming.h>
static const int RXPin = 15, TXPin = 14;
static const uint32_t GPSBaud = 9600;//9600;
// The TinyGPSPlus object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//----------------------
//Include EasyNextionLibrary
#include "EasyNextionLibrary.h"
EasyNex myNex(Serial2); // Create an object of EasyNex class with the name < myNex >
uint16_t A6_PIN; // a variable to store the reading
uint16_t A9_PIN; // a variable to store the reading
uint16_t TEST_1;
const int REFRESH_TIME = 100; // time to refresh the Nextion page every 100 ms
unsigned long refresh_timer = millis(); // timer for refreshing Nextion's page
//Include EasyNextionLibrary
//----------------------
//FLEX CAN
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
CAN_message_t msg;
long unsigned int rxId;
long unsigned int rxId_EMUS;
struct CANDATA
{
//MGM Compro ESC Variablen
uint16_t batVoltage;
uint16_t batCurrent;
int32_t rpm;
int16_t motoTemp;
int16_t escTemp;
int16_t externTemp;
int16_t pwmOut;
int16_t pwmIn;
uint32_t error;
uint32_t warning;
uint32_t notice;
uint16_t escInit;
uint16_t bVoltage;
uint16_t feedVoltage;
uint16_t phaseCurrent;
uint16_t avarangeCurrent;
uint8_t busVoltage;
uint8_t mosfetTemp;
//EMUS BMS Variablen
//Overall Parameters page 7
uint16_t emusInputSignals;
uint16_t emusOutputSignals;
uint16_t emusNumberLiveCells;
uint16_t emusChargingState;
uint16_t emusChargStageDuration;
uint16_t emusLastChargError;
//Diagnostics Codes page 10
uint32_t emusProtectionFlags;
uint32_t emusReductionFlags;
uint32_t emusBatteryStatusFlags;
uint16_t emusMinCellModuleTemp;
uint16_t emusMaxCellModuleTemp;
uint16_t emusAvgCellModuleTemp;
uint32_t emusMinCellVolt;
uint32_t emusMaxCellVolt;
uint32_t emusAvgCellVolt;
uint32_t emusTotCellVolt;
uint32_t emusMinCellBalancingRate;
uint32_t emusMaxCellBalancingRate;
uint32_t emusAvgCellBalancingRate;
uint8_t emusCellModule1Temp;
uint8_t emusCellModule2Temp;
uint8_t emusCellModule3Temp;
uint8_t emusCellModule4Temp;
uint8_t emusCellModule5Temp;
uint8_t emusCellModule6Temp;
uint8_t emusCellModule7Temp;
uint8_t emusCellModule8Temp;
//State of Charge parameters page 38
uint32_t emusCurrent;
uint32_t emusEstimatedCharge;
uint32_t emusEstimatedUserCharge;
uint32_t emusEstimatedStateHealth;
//Energy Parameters page 50
uint32_t emusEstimatedEnergy;
};
CANDATA candata;
CANDATA olddata;
bool isNew;
//FLEX CAN
//----------------------
void setup()
{
pinMode(A4, INPUT); // set A0 pin as INPUT
pinMode(A5, INPUT); // set A0 pin as INPUT
Serial.begin(115200);
ss.begin(GPSBaud);
myNex.begin(921600); // NEXTION
//----------------------
//CAN 1&2 Starten...
can1.begin();
can1.setBaudRate(500000);
can2.begin();
can2.setBaudRate(125000);
//...Ende CAN 1&2 Starten
//----------------------
}
void loop()
{
boolean newData = false;
//START: CAN Read und Decodieren EMUS und MGM
//can1.setMBFilter(0, 0x001); // Set mailbox 6 to allow CAN ID 0x123 to be collected - aus Flexcan
if ( can1.read(msg) ) {
rxId = (msg.id);
//can1.read - MGM
Serial.print(msg.mb);
Serial.print(" ID: 0x");
Serial.print(msg.id, HEX ); // von Sparkfun switch (rxId) reinbekommen und auslesen
Serial.print(" DATA: ");
for ( uint8_t i = 0; i < 8; i++ ) {
Serial.print(msg.buf[i]); Serial.print(" ");
}
Serial.print(" TS: ");
Serial.println(msg.timestamp);
//auskommentieren
//START: CAN Read und Decodieren EMUS und MGM
switch (rxId)
{
case 0x1:
//candata.batVoltage = msg.buf[0] | msg.buf[1]; //wird durch 2 Zeilen ersetzt welche analog zur Beschreibung aufsummiert werden
candata.batVoltage = msg.buf[0];
candata.batVoltage += static_cast < uint32_t > (msg.buf[1]) << 8;
//candata.batCurrent = msg.buf[2] | msg.buf[3]; //wird durch 2 Zeilen ersetzt welche analog zur Beschreibung aufsummiert werden
candata.batCurrent = msg.buf[2];
candata.batCurrent += static_cast < uint32_t > (msg.buf[3]) << 8;
candata.rpm = msg.buf[4];
candata.rpm += static_cast < uint32_t > (msg.buf[5]) << 8; // += aufsummieren & 1<<1 ist 2 & 1<<2 ist 4 1<<3 ist 8 & 1<<8 ist 256 also 1<<8 ist gleich 2hoch8
candata.rpm += static_cast < uint32_t > (msg.buf[6]) << 16;
candata.rpm += static_cast < uint32_t > (msg.buf[7]) << 24;
break;
case 0x2:
candata.motoTemp = msg.buf[0] | msg.buf[1];
candata.escTemp = msg.buf[2];
candata.escTemp += static_cast < uint32_t > (msg.buf[3]) << 8;
candata.externTemp = msg.buf[6] | msg.buf[7];
break;
case 0x3:
candata.pwmOut = msg.buf[0];
candata.pwmOut += static_cast < uint32_t > (msg.buf[1]) << 8;
candata.pwmIn = msg.buf[2];
candata.pwmIn += static_cast < uint32_t > (msg.buf[3]) << 8;
break;
case 0x4:
candata.error = msg.buf[0];
candata.error += static_cast < uint32_t > (msg.buf[1]) << 8;
candata.error += static_cast < uint32_t > (msg.buf[2]) << 16;
candata.error += static_cast < uint32_t > (msg.buf[3]) << 24;
candata.warning = msg.buf[4];
candata.warning += static_cast < uint32_t > (msg.buf[5]) << 8;
candata.warning += static_cast < uint32_t > (msg.buf[6]) << 16;
candata.warning += static_cast < uint32_t > (msg.buf[7]) << 24;
break;
case 0x5:
candata.notice = msg.buf[0];
candata.notice += static_cast < uint32_t > (msg.buf[1]) << 8;
candata.notice += static_cast < uint32_t > (msg.buf[2]) << 16;
candata.notice += static_cast < uint32_t > (msg.buf[3]) << 24;
candata.escInit = msg.buf[6] | msg.buf[7];
break;
case 0x6:
candata.bVoltage = msg.buf[0];
candata.bVoltage += static_cast < uint32_t > (msg.buf[1]) << 8;
candata.feedVoltage = msg.buf[2];
candata.feedVoltage += static_cast < uint32_t > (msg.buf[3]) << 8;
candata.phaseCurrent = msg.buf[4];
candata.phaseCurrent += static_cast < uint32_t > (msg.buf[5]) << 8;
candata.avarangeCurrent = msg.buf[6];
candata.avarangeCurrent += static_cast < uint32_t > (msg.buf[7]) << 8;
break;
case 0x7:
candata.busVoltage = msg.buf[4] | msg.buf[5];
candata.mosfetTemp = msg.buf[6] | msg.buf[7];
break;
}
}
else if ( can2.read(msg) ) {
rxId_EMUS = (msg.id);
Serial.print("CAN2 ");
Serial.print("MB: "); Serial.print(msg.mb);
Serial.print(" ID: 0x"); Serial.print(msg.id, HEX );
Serial.print(" EXT: "); Serial.print(msg.flags.extended );
Serial.print(" LEN: "); Serial.print(msg.len);
Serial.print(" DATA: ");
// war 8 als i < 8 - stimmt auch, ansonsten wird aufgefüllt
for ( uint8_t i = 0; i < 8; i++ ) {
Serial.print(msg.buf[i]); Serial.print(" ");
}
Serial.print(" TS: "); Serial.println(msg.timestamp);
switch (rxId_EMUS)
{
case 0x19B50000: //Overall Parameters, page 7
candata.emusInputSignals = msg.buf[0];
candata.emusOutputSignals = msg.buf[1];
candata.emusNumberLiveCells = msg.buf[7];
candata.emusNumberLiveCells += static_cast < uint32_t > (msg.buf[2]) << 8;
candata.emusChargingState = msg.buf[3];
candata.emusChargStageDuration = msg.buf[5];
candata.emusChargStageDuration += static_cast < uint32_t > (msg.buf[4]) << 8;
candata.emusLastChargError = msg.buf[6];
break;
case 0x19B50001: //Battery Voltage Overall Parameters
candata.emusMinCellVolt = msg.buf[0];
candata.emusMaxCellVolt = msg.buf[1];
candata.emusAvgCellVolt = msg.buf[2];
// Data 3= 3rd / Data 4= LSB / Data 5= MSB / Data 6= 2nd --> genau verkehrt MSB, 2nd, 3rd, LSB
candata.emusTotCellVolt = msg.buf[4]; //LSB = Less, Links
candata.emusTotCellVolt += static_cast < uint32_t > (msg.buf[3]) << 8;
candata.emusTotCellVolt += static_cast < uint32_t > (msg.buf[6]) << 16;
candata.emusTotCellVolt += static_cast < uint32_t > (msg.buf[5]) << 24; //MSB = Most, Rechts
break;
case 0x19B50007: //Battery Voltage Overall Parameters
candata.emusReductionFlags = msg.buf[4];
candata.emusBatteryStatusFlags = msg.buf[7];
// Data 3= 3rd / Data 4= LSB / Data 5= MSB / Data 6= 2nd --> genau verkehrt MSB, 2nd, 3rd, LSB
candata.emusProtectionFlags = msg.buf[0]; //LSB = Less, Links
candata.emusProtectionFlags += static_cast < uint32_t > (msg.buf[1]) << 8;
candata.emusProtectionFlags += static_cast < uint32_t > (msg.buf[2]) << 16;
candata.emusProtectionFlags += static_cast < uint32_t > (msg.buf[3]) << 24; //MSB = Most, Rechts
break;
case 0x19B50002: // Cell Module Temperature Overall Parameters
candata.emusMinCellModuleTemp = msg.buf[0];
candata.emusMaxCellModuleTemp = msg.buf[1];
candata.emusAvgCellModuleTemp = msg.buf[2];
break;
case 0x19B50003: // Cell Balancing Rate Overall Parameters
candata.emusMinCellBalancingRate = msg.buf[0];
candata.emusMaxCellBalancingRate = msg.buf[1];
candata.emusAvgCellBalancingRate = msg.buf[2];
break;
// case 0x19B50201: // Individual Cell Module Temperatures – Option A 0x19B50100
// candata.emusCellModule1Temp = msg.buf[0];
// candata.emusCellModule2Temp = msg.buf[1];
// candata.emusCellModule3Temp = msg.buf[2];
// candata.emusCellModule4Temp = msg.buf[3];
// candata.emusCellModule5Temp = msg.buf[4];
// candata.emusCellModule6Temp = msg.buf[5];
// candata.emusCellModule7Temp = msg.buf[6];
// candata.emusCellModule8Temp = msg.buf[7];
// break;
case 0x19B50500: // State of Charge parameters
candata.emusCurrent = msg.buf[1];
candata.emusCurrent += static_cast < uint32_t > (msg.buf[0]) << 8;
candata.emusEstimatedCharge = msg.buf[3];
candata.emusEstimatedCharge += static_cast < uint32_t > (msg.buf[2]) << 8;
candata.emusEstimatedUserCharge = msg.buf[6];
candata.emusEstimatedUserCharge += static_cast < uint32_t > (msg.buf[5]) << 8;
candata.emusEstimatedStateHealth = msg.buf[7];
case 0x19B50600: // Energy Parameters
candata.emusEstimatedEnergy = msg.buf[3];
candata.emusEstimatedEnergy += static_cast < uint32_t > (msg.buf[2]) << 8;
break;
}
}
//ENDE: CAN Read und Decodieren EMUS und MGM
//----------------------
//AUS GPS
while (ss.available() > 0)
if (gps.encode(ss.read()))
//Serial.println(F("GPS Online"));
// TEST_1 = (gps.time.second());
//TEST BEIDES MOEGLICH:
// myNex.writeNum("N1.val", (gps.time.second()));
if (millis() > 5000 && gps.charsProcessed() < 10)
{
//Serial.println(F("OFFLINE"));
while(true);
}
//AUS GPS
//----------------------
//AUS NEXTION
if((millis()-refresh_timer) > REFRESH_TIME){ //IMPORTANT do not have serial print commands in the loop without a delay
// or an if statement with a timer condition like this one.
//ÜBERGABE UHRZEIT UND DATUM
myNex.writeNum("N1.val", gps.time.hour());
myNex.writeNum("N2.val", gps.time.minute());
myNex.writeNum("N3.val", gps.time.second());
myNex.writeNum("N4.val", gps.date.day());
myNex.writeNum("N5.val", gps.date.month());
myNex.writeNum("N6.val", gps.date.year());
//ÜBERGABE UHRZEIT UND DATUM
//----------------------
//ÜBERGABE ... VARIABLEN
myNex.writeNum("N7.val", gps.satellites.value());
myNex.writeNum("N8.val", gps.altitude.meters());
myNex.writeNum("N9.val", gps.speed.kmph());
//ÜBERGABE ... VARIABLEN
//----------------------
//BERECHNUNG ZURÜCK oder ZIEL/STARTPUNKT
static const double TARGET_LAT = 47.24837, TARGET_LON = 8.70710;
unsigned long distanceKmToTarget =
(unsigned long)TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
TARGET_LAT,
TARGET_LON); // / 1000; 1000 für km ansonten Meter
myNex.writeNum("N10.val",(distanceKmToTarget));//, gps.location.isValid(), 9));
//BERECHNUNG ZURÜCK oder ZIEL/STARTPUNKT
//----------------------
//BERECHNUNG COURSE ZIEL/STARTPUNKT
double courseToTarget =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
TARGET_LAT,
TARGET_LON);
myNex.writeNum("N11.val",(courseToTarget));
const char *cardinalToTarget = TinyGPSPlus::cardinal(courseToTarget);
myNex.writeNum("N12.val",(*cardinalToTarget));
myNex.writeNum("N13.val",(gps.location.isValid() ? cardinalToTarget : "*** "));
//BERECHNUNG COURSE ZIEL/STARTPUNKT
//----------------------
//MGM
myNex.writeNum("N14.val", (static_cast < float > (candata.feedVoltage)* 0.1));
myNex.writeNum("N15.val", (static_cast < float > (candata.escTemp)));
myNex.writeNum("X19.val", (static_cast < float > (candata.pwmOut)));
myNex.writeNum("X20.val", (static_cast < float > (candata.rpm)));
myNex.writeNum("N16.val", (static_cast < float > (candata.pwmOut)));
myNex.writeNum("N17.val", (static_cast < float > (candata.rpm)));
//MGM
//----------------------
//EMUS
myNex.writeNum("X0.val", (static_cast < float > (candata.emusMinCellVolt) + 200));
myNex.writeNum("X1.val", (static_cast < float > (candata.emusMaxCellVolt) + 200));
myNex.writeNum("X2.val", (static_cast < float > (candata.emusAvgCellVolt) + 200));
myNex.writeNum("X3.val", (static_cast < float > (candata.emusTotCellVolt)*10));
myNex.writeNum("X4.val", (static_cast < float > (candata.emusMinCellBalancingRate)));
myNex.writeNum("X5.val", (static_cast < float > (candata.emusMaxCellBalancingRate)));
myNex.writeNum("X6.val", (static_cast < float > (candata.emusAvgCellBalancingRate)));
myNex.writeNum("X7.val", (static_cast < float > (candata.emusMinCellModuleTemp) - 100));
myNex.writeNum("X8.val", (static_cast < float > (candata.emusMaxCellModuleTemp) - 100));
myNex.writeNum("X9.val", (static_cast < float > (candata.emusAvgCellModuleTemp) - 100));
myNex.writeNum("X10.val", (static_cast < float > (candata.emusInputSignals)));
myNex.writeNum("X11.val", (static_cast < float > (candata.emusOutputSignals)));
myNex.writeNum("X12.val", (static_cast < float > (candata.emusNumberLiveCells)));
myNex.writeNum("X13.val", (static_cast < float > (candata.emusChargingState)));
myNex.writeNum("X14.val", (static_cast < float > (candata.emusChargStageDuration)));
myNex.writeNum("X15.val", (static_cast < float > (candata.emusLastChargError)));
// myNex.writeNum("X16.val", (static_cast < float > (candata.emusReductionFlags)));
// myNex.writeNum("X17.val", (static_cast < float > (candata.emusBatteryStatusFlags)));
// //myNex.writeNum("X18.val", (static_cast < float > (candata.emusProtectionFlags)));
// myNex.writeNum("X20.val", (static_cast < float > (candata.emusProtectionFlags)));
// myNex.writeNum("N16.val", (static_cast < float > (candata.emusProtectionFlags)));
// myNex.writeNum("N17.val", (static_cast < float > (candata.emusBatteryStatusFlags)));
myNex.writeNum("X20.val", (static_cast < float > (candata.emusEstimatedEnergy)));
// CAN_message_t msg;
// // 1. ID zusammensetzen: Byte1(Base MSB), Byte2(Base LSB), Byte3(0x00), Byte4(0x0B)
// // Ergibt bei Extended ID (29-Bit) oft ein Format wie 0xByte1Byte2000B
// //msg.id = 0x11000B; // Beispielwert basierend auf deiner Beschreibung
// msg.id = 0x19B50B; // Beispielwert basierend auf deiner Beschreibung
// // 2. Flags setzen
// msg.flags.extended = 1; // Ext.ID 1
// msg.flags.remote = 0; // RTR 0
// // 3. DLC und Payload
// msg.len = 2; // DLC 2
// msg.buf[0] = 0x00; // Data0 0x00
// msg.buf[1] = 0x01; // Data1 1
// // Nachricht senden
// if (can1.write(msg)) {
// Serial.println("CAN Nachricht gesendet!");
// } else {
// Serial.println("Senden fehlgeschlagen.");
// }
// delay(1000); // 1 Sekunde Intervall
//EMUS
//----------------------
//MGM
// myNex.writeNum("N21.val", (static_cast < float > (candata.batCurrent) * 0.1));
// myNex.writeNum("N22.val", (static_cast < float > (candata.rpm)));
// myNex.writeNum("N23.val", (static_cast < float > (candata.pwmIn) / 10.23));
// myNex.writeNum("N24.val", (static_cast < float > (candata.phaseCurrent)));
//MGM
//----------------------
//ALTERNATIVE
// int temp_A9 = analogRead(A9); // Einlesen PIN A9
// A9_PIN = map(temp_A9, 0, 1024, 0, 1480); // entpsricht der Spannung des 4S LiPos für die Versorgung
// myNex.writeNum("NA9.val", A9_PIN);
//ALTERNATIVE
//----------------------
myNex.writeNum("NA6.val", map(analogRead(A4), 0, 1024, 0, 5780));
myNex.writeNum("NA9.val", map(analogRead(A5), 0, 1024, 0, 1480));
//----------------------
refresh_timer = millis(); // Set the timer equal to millis, create a time stamp to start over the "delay"
}
}