Sieht so aus.
#include <algorithm>
Da gibts wohl Board-spezifische Bibs die von der lib genutzt werden. ![]()
Dann mach ichs blind. ![]()
Sieht so aus.
#include <algorithm>
Da gibts wohl Board-spezifische Bibs die von der lib genutzt werden. ![]()
Dann mach ichs blind. ![]()
Ok, ich glaub ich hab dein erstes Problem gefunden.
Sage mal, wenn Du eine celID bekommst, gehört der voltageValue zu der ID.
Du hast Dir das viel zu kompliziert gemacht und dich damit selbst gefangen.
Was gehört denn noch alles zu der jeweiligen cellID?
Und wieviele cellID hast Du davon?
Zusatzfrage: Was nicht zur cellID gehört, was davon gehört noch irgendwie zusammen? Und wie oft gibt es das?
also cellid setzt sich aus den zellanzahlen zusammen, insgesamt in meinem fall 96
sieht dann wie folgt aus 0x36 ist die adresse, danach der erste bit ist welche Zelle, datenbit 1 und 2 ist dann die spannung der jeweiligen zelle, das wird von der bms alle 10ms gesendet
Byte? ![]()
Damit ist das abgehandelt.
Bekommen wir hin.
Aahhh da kommt eine Beschreibung ![]()
Gibts die irgendwo Online? Das scheint was genormtes zu sein.
Damit gehören zur cellID 5 Werte + Checksum.
Nochmal die Frage: Was gehört noch irgendwie zusammen?
Ich versuch grad eine IDE zu bauen für den Teensy. Wäre schade, wenn ich das anfange und auf der halben Strecke verrecke ![]()
Ich bin auch gleich wieder still...
Da muss aber m.E. bestenfalls nur jede zehnte Sendung wirklich verarbeitet werden - Spannungen und Temperaturen sollten sich doch nicht so schnell um signifikant große Beträge ändern. Das Auge kommt da sowieso nicht mehr mit...
also hab da mal was eingefügt, da kann man so einiges nachlesen
editing_canbus_messages.pdf (730,0 KB)
orionbms_obd2_pids.pdf (73,9 KB)
thermistor_module_canbus.pdf (55,3 KB)
eigentlich nicht, es reicht ja alle 500ms, wobei der Leistungsabruf recht schnell gehen sollte, möglichst unter 100ms
Ich bau Dir das so, dass Du nix verpasst.
Irgendwann gegen 20 Uhr werd ich mich melden.
Mal sehen, ob ich das alles bis dahin rausgelesen bekomme. ![]()
das wär echt Mega
Du musst doch sehen ob das Display den Tastendruck erkennt oder verzögert reagiert, genau so wann die Daten vom Display nach Druck auf die Taste rausgehen?
Zumindest wenn man mehrmals drückt.
Daran erkennt man doch ob das Display nicht reagiert oder der Professor bei der Auswertung klemmt.
cu
Kann ich verstehen ![]()
Sag mal, beim Teensy ist ein unsigned int ein 32-bit Wert! Ist das so gewollt, dass alle Deine Werte so gross sind?
In Deinem Code unter anderem setzt Du doch nur 16bittig zusammen:
Volt = (word(rxmsg.buf[1], rxmsg.buf[2]));
hab ich doch geschrieben, das es manchmal geht manchmal nicht, ich seh das auch auf dem savvy can
ich hab das so aus einem anderen code übernommen
https://www.buildpics.org/tag/can-bus/
Da läuft ein Schnüffelscript mit und weil ich mich nicht ausschnüffeln lasse...

Ok, Das wird nur 16bittig...
echt ??, ich mach mal screenshots bzw den code
FlexCAN CANbus(500000);
static CAN_message_t rxmsg;
byte indicator[7];
float BATTV, IAC, dwell, idle_tar, AFRtgt, AFR, newBATTV, oldBATTV;
unsigned int MAP, SPKADV, RPM, TPS, MAT, CLT, injduty, Baro, PW1, nexAFR, nexCLT;
void setup() {
CANbus.begin();
Serial2.begin(115200);
}
void loop(void) {
gauge_display();
if ( CANbus.read(rxmsg) ) {
switch (rxmsg.id) {
case 1520:
RPM = (float)(word(rxmsg.buf[6], rxmsg.buf[7]));
PW1 = (float)(word(rxmsg.buf[2], rxmsg.buf[3]));
injduty = ((PW1 / 1000 * RPM / 120) / 10);
break;
case 1521:
SPKADV = (float)(word(rxmsg.buf[0], rxmsg.buf[1]));
indicator[0] = rxmsg.buf[3];
AFRtgt = (float)(word(0x00, rxmsg.buf[4]));
break;
case 1522:
Baro = (float)(word(rxmsg.buf[0], rxmsg.buf[1]));
MAP = (float)(word(rxmsg.buf[2], rxmsg.buf[3]));
MAT = (float)(word(rxmsg.buf[4], rxmsg.buf[5]));
CLT = (float)(word(rxmsg.buf[6], rxmsg.buf[7]));
nexCLT = (float)(word(rxmsg.buf[6], rxmsg.buf[7]));
break;
case 1523:
TPS = (float)(word(rxmsg.buf[0], rxmsg.buf[1]));
BATTV = (float)(word(rxmsg.buf[2], rxmsg.buf[3]));
AFR = (float)(word(rxmsg.buf[4], rxmsg.buf[5]));
nexAFR = (float)(word(rxmsg.buf[4], rxmsg.buf[5]));
break;
case 1524:
break;
case 1526:
IAC = (float)(word(rxmsg.buf[6], rxmsg.buf[7])); //IAC = (IAC * 49) / 125;
case 1529:
dwell = (float)(word(rxmsg.buf[4], rxmsg.buf[5]));
break;
case 1530:
indicator[1] = rxmsg.buf[0];
indicator[2] = rxmsg.buf[1];
indicator[3] = rxmsg.buf[2];
indicator[6] = rxmsg.buf[6];
indicator[7] = rxmsg.buf[7];
break;
case 1537:
break;
case 1548:
idle_tar = (float)(word(rxmsg.buf[0], rxmsg.buf[1]));
break;
case 1551:
break;
case 1574:
indicator[4] = rxmsg.buf[2];
break;
}
}
}
elapsedMillis DisplayTime;
void gauge_display() {
if ( DisplayTime < 150 ) return;
DisplayTime = 0;
Serial2.print("t3.txt=");
Serial2.write(0x22);
Serial2.print(SPKADV / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("t4.txt=");
Serial2.write(0x22);
Serial2.print(MAP / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("j6.val=");
Serial2.print(nexAFR / 2);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("t14.txt=");
Serial2.write(0x22);
Serial2.print(AFR / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
if ((AFR / 10 < 10.5) && (AFR / 10 > 10) && (TPS / 10 > 80))
gauge_display_AFR_YELLOW();
if ((AFR / 10 < 10.0) && (TPS / 10 > 80))
gauge_display_AFR_RED();
if ((AFR / 10 < 12.5) && (AFR / 10 > 10.5) && (TPS / 10 > 80))
gauge_display_AFR_BLACK();
if ((AFR / 10 > 12.5) && (TPS / 10 > 80))
gauge_display_AFR_RED();
Serial2.print("j2.val=");
Serial2.print(injduty);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("t15.txt=");
Serial2.write(0x22);
Serial2.print(injduty);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
if (injduty < 60)
gauge_display_injduty_black();
if ((injduty >= 60) && (injduty < 79))
gauge_display_injduty_yellow();
if (injduty > 79)
gauge_display_injduty_RED();
Serial2.print("j3.val=");
Serial2.print(TPS / 10);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("t16.txt=");
Serial2.write(0x22);
Serial2.print(TPS / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
newBATTV = BATTV / 10;
if ( newBATTV != oldBATTV )
gauge_display_BATTV();
Serial2.print("t8.txt=");
Serial2.write(0x22);
Serial2.print(MAT / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("t0.txt=");
Serial2.write(0x22);
Serial2.print(RPM);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("j5.val=");
Serial2.print(RPM / 100);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
if (RPM < 5000)
gauge_display_RPM_BLACK();
if ((RPM > 5000) && (RPM < 6000))
gauge_display_RPM_YELLOW();
if ((RPM > 6000))
gauge_display_RPM_RED();
Serial2.print("t17.txt=");
Serial2.write(0x22);
Serial2.print(CLT / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("j4.val=");
Serial2.print(nexCLT / 20);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_injduty_black() {
Serial2.print("j2.pco=BLACK");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("t15.pco=BLACK");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_injduty_yellow() {
Serial2.print("j2.pco=YELLOW");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_injduty_RED() {
Serial2.print("j2.pco=RED");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_BATTV() {
oldBATTV =
Serial2.print("t6.txt=");
Serial2.write(0x22);
Serial2.print(BATTV / 10);
Serial2.write(0x22);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_RPM_BLACK() {
Serial2.print("t0.pco=BLACK");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("j5.pco=BLACK");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_RPM_YELLOW() {
Serial2.print("t0.pco=YELLOW");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("j5.pco=YELLOW");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_RPM_RED() {
Serial2.print("t0.pco=RED");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.print("j5.pco=RED");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_AFR_RED() {
Serial2.print("j6.pco=RED");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_AFR_YELLOW() {
Serial2.print("j6.pco=YELLOW");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
void gauge_display_AFR_BLACK() {
Serial2.print("j6.pco=BLACK");
Serial2.write(0xff);
Serial2.write(0xff);
Serial2.write(0xff);
}
Fängt die cellID bei 0 oder bei 1 an zu zählen? (Ich vermute bei 1)
tatsächlich bei 0, bei der temperatur genauso
Die haben was richtg gemacht!!! YEAH!! ![]()
Zwischenstand.
Ich hab noch nix gemacht, daher muss der Sketch noc immer so falsch laufen, wie bisher.
Durch das auflösen und umschreiben wird jetzt aber auch klar, warum Du so Probleme hast. Dir läuft durch das dauernde Schreiben auf das Nextion die Zeit weg.
Das siehst Du sehr gut, wenn Du Dir sendOut() anschaust.
Wie es besser geht, habe ich in flagOut() ganz kurz gezeigt ![]()
In der Hoffnung, dass ich mich nicht zu sehr vertan habe.
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
static CAN_message_t rxmsg, txmsg;
byte incomingByte = 0;
unsigned int CELL_id, Volt, SOC, hTMP, lTMP, PACKi, iTMP, LV, CELLb, BALL, isoDC, isoWAV, CELLDIFF, avr,
flag, tmp_id, cell_tmp, hCELL, lCELL, pCURR, POWER, health, maxCCL, maxDCL, low_tmp, high_tmp, res, tmpm, tmphs, power;
void setup()
{
Serial2.begin(115200);
can1.begin();
can1.setBaudRate(500000);
txmsg.id = 0x601;
txmsg.len = 8;
txmsg.buf[0] = 0x23;
txmsg.buf[1] = 0x00;
txmsg.buf[2] = 0x20;
txmsg.buf[3] = 0x31;
txmsg.buf[4] = 0x00;
txmsg.buf[5] = 0x2A;
txmsg.buf[6] = 0x00;
txmsg.buf[7] = 0x00;
can1.write(txmsg);
}
//
void loop(void)
{
canReadIn();
cellVoltage();
cellTemperature();
flagOut();
readNextion();
}
//
void canReadIn()
{
if (can1.read(rxmsg))
{
switch (rxmsg.id)
{
case 0x36:
CELL_id = (word(rxmsg.buf[0]));
Volt = (word(rxmsg.buf[1], rxmsg.buf[2]));
break;
case 0x200:
flag = (word(rxmsg.buf[0]));
break;
case 0x581:
power = (word(rxmsg.buf[5], rxmsg.buf[6]));
power = power / 32;
power = power * 0.4;
power = power * 1.36;
break;
case 0x602:
tmphs = (rxmsg.buf[0]);
tmpm = (rxmsg.buf[1]);
break;
case 0x640:
SOC = (word(rxmsg.buf[0]));
res = (word(rxmsg.buf[1], rxmsg.buf[2]));
health = (word(rxmsg.buf[3]));
hCELL = (word(rxmsg.buf[4], rxmsg.buf[5]));
lCELL = (word(rxmsg.buf[6], rxmsg.buf[7]));
CELLDIFF = (hCELL - lCELL);
break;
case 0x641:
hTMP = (word(rxmsg.buf[0], rxmsg.buf[1]));
lTMP = (word(rxmsg.buf[2], rxmsg.buf[3]));
iTMP = (word(rxmsg.buf[4], rxmsg.buf[5]));
break;
case 0x642:
isoDC = (word(rxmsg.buf[0], rxmsg.buf[1]));
isoWAV = (word(rxmsg.buf[2], rxmsg.buf[3]));
avr = (word(rxmsg.buf[4], rxmsg.buf[5]));
break;
case 0x643:
maxDCL = (word(rxmsg.buf[0], rxmsg.buf[1]));
maxCCL = (word(rxmsg.buf[2], rxmsg.buf[3]));
pCURR = (word(rxmsg.buf[4], rxmsg.buf[5]));
PACKi = (word(rxmsg.buf[6], rxmsg.buf[7]));
pCURR = pCURR - 32767;
break;
case 0x1838F380:
tmp_id = (word(rxmsg.buf[0], rxmsg.buf[1]));
cell_tmp = (word(rxmsg.buf[2]));
low_tmp = (word(rxmsg.buf[4]));
high_tmp = (word(rxmsg.buf[5]));
break;
}
}
}
//
void cellVoltage()
{
char buf[10] = {'\0'};
sprintf(buf, "%s%i%s", "x20", CELL_id + 1, ".val=\0");
nextionSendStringValueWithEnd(buf, Volt / 10);
}
//
void cellTemperature()
{
char buf[10] = {'\0'};
sprintf(buf, "%s%i%s", "x30", tmp_id + 1, ".val=\0");
nextionSendStringValueWithEnd(buf, cell_tmp * 10);
}
//
void flagOut()
{
static byte oldFlag = 0xFF;
if (flag == oldFlag)
{
return;
}
oldFlag = flag;
switch (flag)
{
case 0x00:
nextionSendString("p61.aph=0");//mil
nextionSendString("t61.pco=33808"); //charge grau
nextionSendString("p60.aph=0"); //balance
nextionSendString("t60.pco=33808"); //ready grau
break;
case 0x08:
nextionSendString("p61.aph=0"); //mil
nextionSendString("t61.pco=33808"); //charge grau
nextionSendString("p60.aph=0"); //balance
nextionSendString("t60.pco=2016"); //ready grün
break;
}
}
//
void readNextion()
{
if (Serial2.available() > 0)
{
// Vorbelegung
txmsg.id = 0x601;
txmsg.len = 8;
txmsg.buf[0] = 0x23;
txmsg.buf[1] = 0x00;
txmsg.buf[2] = 0x20;
txmsg.buf[3] = 0x31;
txmsg.buf[4] = 0x00;
txmsg.buf[5] = 0x00;
txmsg.buf[6] = 0x00;
txmsg.buf[7] = 0x00;
switch (Serial2.read())
{
case '1':
txmsg.buf[5] = 0x2A;
break;
case '2':
txmsg.buf[5] = 0x4A;
break;
case '3':
txmsg.buf[5] = 0x7D;
break;
default:
txmsg.buf[0] = 0x40;
txmsg.buf[5] = 0x00;
break;
}
can1.write(txmsg);
}
}
void sendOut()
{
nextionSendStringValueWithEnd("x06.val=", hTMP * 10);
nextionSendStringValueWithEnd("x07.val=", lTMP * 10);
nextionSendStringValueWithEnd("x333.val=", avr * 10);
nextionSendStringValueWithEnd("n0.val=", SOC);
nextionSendStringValueWithEnd("n1.val=", PACKi / 10);
nextionSendStringValueWithEnd("x02.val=", hCELL / 100);
nextionSendStringValueWithEnd("x297.val=", hCELL / 10);
nextionSendStringValueWithEnd("x03.val=", lCELL / 100);
nextionSendStringValueWithEnd("x298.val=", lCELL / 10);
nextionSendStringValueWithEnd("x299.val=", CELLDIFF / 10);
nextionSendStringValueWithEnd("n2.val=", pCURR * PACKi / 1000);
nextionSendStringValueWithEnd("x06.val=", hTMP * 10);
nextionSendStringValueWithEnd("x07.val=", lTMP * 10);
nextionSendStringValueWithEnd("x04.val=", LV);
nextionSendStringValueWithEnd("n60.val=", maxDCL);
nextionSendStringValueWithEnd("n61.val=", maxCCL);
nextionSendStringValueWithEnd("n63.val=", health);
nextionSendStringValueWithEnd("x701.val=", isoDC);
nextionSendStringValueWithEnd("x702.val=", isoWAV);
nextionSendStringValueWithEnd("x05.val=", iTMP * 10);
nextionSendStringValueWithEnd("x401.val=", tmphs * 10);
nextionSendStringValueWithEnd("x402.val=", tmpm * 10);
nextionSendStringValueWithEnd("n502.val=", power);
}
//
void nextionSendStringValue(const char *sendBuf, const uint16_t value)
{
Serial2.print(sendBuf);
Serial2.print(value);
}
//
void nextionSendStringValueWithEnd(const char *sendBuf, const uint16_t value)
{
nextionSendStringValue(sendBuf, value);
nextionSendEnd();
}
//
void nextionSendString(const char *sendBuf)
{
Serial2.print(sendBuf);
}
//
void nextionSendStringWithEnd(const char *sendBuf)
{
nextionSendString(sendBuf);
nextionSendEnd();
}
//
void nextionSendEnd()
{
for (byte b = 0; b < 3; b++)
{
Serial2.write(0xff);
}
}
Zusatzfrage:
Ich habe gesehen, dass tempId auch irgendwie genauso zählt wie CellId - kann es sein, dass die Temperatur zu jeder Zelle gehört, wie Voltage???