CANbus-Konflikt im Menu

Hallo Gemeinde :slight_smile:
kurz zur erklärung des ganzen.
Ich habe einen VW T5 in dem ein zusätzlicher CAN-Bus läuft der ein paar verschiedene (eigene) Steuereinheiten verbindet(alles Arduino-Controller).

ein Arduino Mega ist ausgestattet mit einem 2,8" TouchDisplay. Über eben Jenes Display kann man durch 6 "Hauptmenüs" steuern. per Touch sind in diesen Menüs unterschiedliche Sachen zu steuern. das funktioniert auch ganz gut, bis auf das laden der einzelnen Icons. das dauert recht lang und man kann diesem 120x120Pixel großen Icons zugucken wie sie von oben nach unten abgearbeitet werden. aber prinzipiel stört mich das nicht sonderlich.
jetzt zum eigentlichen Problem. die meiste Zeit über versendet dieser Controller nur kurze Status-Bytes über den Bus, der dann auf einem anderen Controller Relaise schließt/öffnet und noch ein bisschen mehr.
Jetzt möchte ich aber von diesem zweiten Controller zwei Spannungswerte in jeweils 2 Byte zurück an die Displayeinheit schicken.
Allerdings hängt sich dabei der Controller auf, weil er beim Icons/Bilder laden vom Interrupt des Can-Busses unterbrochen wird. (das Laden der bilder dauert für 120x120Pixel gut eine ganze Sekunde).

erst nach den Bild-Lade-Prozess den Can-Bus abzufragen würde bedeuten das vermutlich daten verloren gehen. Weniger wild bei spannungswerten, aber bei Status-bytes wäre das doof.
wie könnte ich den Code so grundsätzlich verbessern um keine Konflikte diesbezüglich zu bekommen. hat jemand eine Idee ?

Meine C-Fähigkeiten beschränken sich auf Learning-by-doing und "das brauch ich gerad also versuch ich es zu verstehen". zusätzlich versuch cih mir momentan auch noch Basiswissen anzueignen.

beste Grüße

und natürlich der Code… sorry

Bilder.h (5.56 KB)

Cockpit_0.2_Mega_CAN.ino (14.5 KB)

Welche CanBus-Hardware verwendest Du?

Welche CanBus-Bibliothek verwendest Du?

Wie sieht das Programm einer Steuereinheit aus?

CAN-Bus-Hardware : MCP2515 Amazon Link

CAN-Bus-Blibothek: https://github.com/sandeepmistry/arduino-CAN.git

Die Steuereinheit( steuert verschiedene Ausgänge um Zwei Blei-Säure Batterien unterschiedlich laden zu können und einen Kühlschrank(AN/AUS) ) und funktioniert zufriedenstellend

Bat_Platine.ino (18.2 KB)

Diese CAN-Bus-Hardware habe ich auch, die Bibliothek ist mir (noch) unbekannt.

Igor_T5:
Allerdings hängt sich dabei der Controller auf, weil er beim Icons/Bilder laden vom Interrupt des Can-Busses unterbrochen wird. (das Laden der bilder dauert für 120x120Pixel gut eine ganze Sekunde).

Könntest Du das bitte etwas genauer beschreiben, was passiert?

Was mir spontan auffällt: Die ISR onReceive verwendet ID_Dummy, warum global? Müßten Spannung_Bat1 und Spannung_Bat2 nicht volatile sein und warum sind die float, wenn nur zwei Bytes geschickt werden?

Verwendest Du 8 oder 16 MHz beim MCP2515?

Wo hast Du CS von CD-Leser und MCP2515 angeschlossen?

Ohne bmp-Dateien, zumindest ohne BASE.bmp wird das Verständnis etwas schwierig.

agmue:
Diese CAN-Bus-Hardware habe ich auch, die Bibliothek ist mir (noch) unbekannt.

kannst du eine andere/bessere Empfehlen ?

agmue:
Könntest Du das bitte etwas genauer beschreiben, was passiert?

na klar! der Zweite Controller(Bat_Platine) schickt circa jede sekunde den Spannungswerd der Batterien. Läd in diesem Moment gerade der Display-Controller ein neues Bild, weil ich das Menü wechsel, dann bleibt der Controller dabei hängen. das heißt das Bild läd nur stückweiße und danach geht nichts mehr. ich versuche gleich mal, das Problem vielleicht noch näher zu analysieren. Für jedes Icon(immer 120x120Pixel) braucht der Controller circa 1 sekunde, eine Menüseite besteht aus quasi 4 Icons was dann wiederrum bedeutet das beim Menü-wechsel das ganze mal locker 4 sekunden dauert. In dieser Zeit ist der Controller eben voll ausgelastet damit einfach nur Bilder zu laden und es würden theoretisch ein haufen Can-Busdaten verloren gehen.

agmue:
Was mir spontan auffällt: Die ISR onReceive verwendet ID_Dummy, warum global? Müßten Spannung_Bat1 und Spannung_Bat2 nicht volatile sein und warum sind die float, wenn nur zwei Bytes geschickt werden?

ID_Dummy hatte ih der übersicht halber global gemacht. theoretisch wäre es in der funktion natürlich sinnvoller aber macht das so viel unterschied, Speicherplatz ist ja für den Arduino Mega noch genug vorhanden?!?
ZU Spannung_Bat1/2, die werte werden doch nicht im ISP verändert, darum hatte es für mich jetzt kein sinn gemacht das sie volatile sein sollten, wenn ich das falsch sehe dann korigier mich gern :slight_smile:
Float weil ich ja Gleitkommaberechnungen anstelle und wenigstens zwei Nachkommastellen haben möchte. theoretisch könnte man das vielleicht schneller und geschickter lösen, würde am ursprünglichen Problem aber nichts ändern glaube ich.

agmue:
Verwendest Du 8 oder 16 MHz beim MCP2515?

Ich benutze die Platine Out of the Box und haben auch nichts einstellen müssen.

agmue:
Wo hast Du CS von CD-Leser und MCP2515 angeschlossen?

CS vom MCP ist auf Pin 53
CS vom SD-Kartenleser ist auf Pin 49

Erweiterte Variante: Du zerlegst das Laden und Zeichnen des Bildes in mehrere (kurze) Teilabschnitte für deren Dauer Du den Interrupt sperrst. Dazwischen erlaubst Du den Interrupt, verarbeitest, was da ist und machst mit dem nächsten Teilabschnitt weiter.

Gruß Tommy

noiasca:
die Sandeep lib verwende ich am ESP32, die läuft eigentlich gut.

Aber bezüglich 8 oder 16MHz musst du dennoch aufpassen. Meine Module haben einen 8MHz Quartz drauf - solange du nur die gleichen Module verwendest kann die Kommunikation funktionieren. Sobald du aber unterschiedliche Module verwendest (oder wie ich Unos mit diesen Modul und ESP32 mit einem separaten Wandler) musst beim initialisieren des CAN Objektes die richtige Quartz-Frequenz auch mitgeben. Ich wüde das an deiner Stelle richtig machen.

mit der Übertragung habe ich keine Probleme das funktioniert wunderbar, ich benutze einige Mega und ein Arduino Uno. aber ich werd es umsetzen und verbessern um Problemen aus dem Weg zu gehen.

noiasca:
Zum eigentlichen Problem: brauchst du unbedingt die Aktualität über den Interrupt? oder kannst du den Interrupt für die Zeit des Bildaufbaus aussetzen und danach erst wieder einsetzen. Etwas Puffer müsste das CAN-Modul ja eigentlich haben. Liest halt erst dann weiter, wenn du mit dem Bild fertig bist.

ich werd das ausprobieren. Grundsätzlich sollte das von der Zeit her passen.

Hast du Erfahrungen mit der Library im Bezug auf Filter setzen ? Ich konnte diesbezüglich noch nichts finden.

danke für die Ideen

gib es eine Möglichkeit das Bild schneller zu laden bzw. vielleicht nicht als BMP? Im Prinzip sind das ganz einfache Icons die mehr oder weniger selbst gezeichnet sind. sowas wie im Anhang.

beim Filtern musst nur aufpassen, dass du auch die zweite Maske setzen musst, auch wenn du nur einen Filter brauchst. Ansonsten lässt der zweite Filter wieder alles durch.

habs zwar nur mit der CoryFowler gemacht, wird aber bei Sandeep nicht anders sein.

    CAN.init_Mask(0, 0, myMask);                // Init first mask
    CAN.init_Filt(0, 0, myFilter);              // Init first filter
    //  CAN.init_Filt(1, 0, myFilter);              // Init second filter...
    CAN.init_Mask(1, 0, myMask);                // Init second mask - must be set, otherwise first mask isn't working

Igor_T5:
kannst du eine andere/bessere Empfehlen ?

Im Thema UNO - Mega - Teensy mittels CAN-Bus verbinden habe ich mal etwas probiert. Eine Empfehlung für diese Bibliothek kann ich daraus aber nicht ableiten, da fehlt mir die Erfahrung.

Nur bin ich zusammen mit einem Teensy über die 8/16 MHz gestolpert. Innerhalb eines geschlossenen Busses nur mit MCP2515 merkt man den Fehler nicht. Der Teensy hat die Bus-Hardware eingebaut, da merkt man es dann.

Igor_T5:
Läd in diesem Moment gerade der Display-Controller ein neues Bild, weil ich das Menü wechsel, dann bleibt der Controller dabei hängen. das heißt das Bild läd nur stückweiße und danach geht nichts mehr. ich versuche gleich mal, das Problem vielleicht noch näher zu analysieren.

Das Laden eines Bildes dürfte nach meiner Vorstellung nicht zeitkritisch sein und sollte von einem Interrupt unterbrochen werden dürfen. Da SD und MCP2515 über SPI laufen, könnte an dieser Stelle ein Konflikt auftreten, auch wenn ich nicht weiß, welcher das sein könnte.

Igor_T5:
ZU Spannung_Bat1/2, die werte werden doch nicht im ISP verändert, …

Spannung_Bat1 = (char)CAN.read();
...
Spannung_Bat2 = (char)CAN.read();

Da bin ich anderer Meinung!

Acht Byte können schön zerstückelt werden. Nur angemerkt, hat mit Deiner Frage nichts zu tun.

Igor_T5:
sowas wie im Anhang.

Wo? Um es nachzuvollziehen, wären die Bildchen ganz hilfreich.

Thommy hatte ja schon einen Vorschlag gemacht, wie man das Problem umgehen könnte. Der Master (der mit dem Display) könnte wie bei I2C auch Spannungwerte anfordern, wenn gerade kein Bild aufgebaut wird.

Oder er schickt eine Meldung “bin beschäftigt” vor dem Bildaufbau. Möglicherweise kann das sogar das CanBus-Protokoll, denn ich habe schon mal “Datenübertragung nicht erfolgreich” gelesen, wenn ein UNO mit dem Laden eines neuen Programms beschäftigt war.

Grundsätzlich fände ich es aber schon wichtig, zunächst der Ursache des Problems näher zu kommen.

Hallo,
leider hatte ich in den letzten Wochen keine Zeit mich dem Problem zu witmen.

seit einigen Tagen arbeite ich jetzt wieder daran bin aber gerade so ein bisschen mit dem Latein am Ende.

Ich habe das Programm nochmal verändert und brauche das SPI nur noch für das CAN-Modul, daher kann ich einen Bus-konflikt ausschließen.

Aufgefallen ist mir, dass das Programm circa 3 mal langsamer durchlaufen wird wenn ich die Interrupt routine für den CAN-BUS im Setup-Teil registriere. selbst Ohne inhalt der Interrupt-Service-Routine. und auch ohne Interrupt, also Datenpaket auf dem CAN-BUS.

Soll der Controller durch antippen eines Icon´s ein neues Icon aufbauen kann man zugucken wie jede einzelne Linie langsam Stück für Stück aufgebaut wird. im übrigen werden keine BMP-Datein mehr geladen sondern nur noch Rechtecke gezeichnet und Text ausgeben. Das hat wunderbar funktioniert und ging in Bruchteilen einer Sekunde, statt “große” 120x120 Icon´s von der SD karte zu laden.

Hat jemand eine Idee wo da das Problem liegen könnte ? Ich weiß im Moment nicht wie ich den Fehler weiter suchen soll. Warum macht das Aktivieren des Interrupts das Programm so langsam, selbst wenn die ISR gar nicht aufgerufen wird.

Cockpit_0.3.ino (7.87 KB)