Abfrage bzw. Daten auf Fahrzeug-Canbus senden

Liebes Forum,
ich hoffe ich kann hier schnelle und unkomplizierte Hilfe für mein Problem finden.
Um was geht es?
Ganz konkret um einen 20 Jahre alten Volvo S60R der seit ich Ihn habe (13 Jahre) etwas, sagen wir einmal optimiert wurde. Bis vor kurzem waren Zusatzanzeigen von einer Firma verbaut welche es nun nicht mehr gibt und leider defekt sind. Daher habe ich nun einen deutschen Hersteller gekauft welcher zusätzlich zu den verbauten analogen Sensoren auch Canbus Daten auswerten und ganz komfortabel anzeigen kann. Diagramme, Warngrenzen, Symbole etc.
Nun zu meinem Problem, das Motorsteuergerät des Volvos stellt leider diese Daten erst nach einer "Abfrage" zur Verfügung.
Um konkret zu werden, möchte ich beispielsweise die Drehzahl des Motors haben muss ich die Nachricht:
0X000FFFFE CD 7A A6 10 1D 01 00 00 senden um als Antwort:
0X01000021 CD 7A E6 10 1D 12 00 00 zu erhalten. Für was die einzelnen Bytes stehen weiß ich für nahezu alle Anfragen die mich interessieren. Im Beispiel oben
12 = dezimal 18 und muss mit dem Multiplikator 40 multipliziert werden. Ergebnis Motordrehzahl = 720rpm.
Die Abfrage und Multiplikation mit den entsprechenden Parametern kann ich in meinem Abfragegerät machen. Leider kann ich von dort keine Anfragen bzw. Nachrichten auf den Bus senden.
Das bedeutet ich benötige eine Hard und Software welche mir die Abfragen generiert bzw. auf den Bus schickt. Auch wenn ich von Arduino gar keine Ahnung habe gehe ich einmal davon aus dass ich mindestens einen ESP32 und einen MCP2515 benötige. Was ich ebenfalls weiß ist das die Canbus Geschwindigkeit 250kbit/s beträgt.
Reichen diese Daten schon aus um ggf. eine Lösung finden zu können oder gehe ich viel zu blauäugig an diese Sache heran?
Ich danke euch vielmals.
Grüße Andreas

Ich frag mich grad, wenn Du die Datenpakete kennst, warum Du noch ein extra Gerät nimmst.
@agmue ist mit dem ESP gut bei und can kann der auch.
Wenn Du die adressen kennst, baut er Dir vielleicht einen Ansatz, der beides kann..

Aber kcih sehe da nicht so die Hürde.
Ausser die verschmutzte KFZ-Welt um den Controller herum, aber das bekommt man gelöst

Danke für die schnelle Antwort, du sprichst für mich leider in Rätseln. :slight_smile:
Du meinst es ginge auch ohne MCP2515. Wenn das möglich ist, gerne. Alles was über Arduino weiß ist leider gefährliches Halbwissen da ich das bisher noch nie benötigt habe.
Was auch immer ich an Hardware benötige bin ich gerne Bereit zu beschaffen.

Grüße

a)
es erscheint mir eingenartig, dass es nicht irgend ein Paket mit der Drehzahl gäbe.

b)
hängst du dann die zusätzlichen Geräte auch in den OEM CAN Bus oder benötigen die Geräte die CAN Messages wieder anders? Dann bräuchtest du einen zweiten CAN Bus. Dann wäre vermutlich ein anderer Controller mit zwei CAN Buse besser.

c)
Der ESP32 kann CAN von sich aus. Da braucht es keinen MCP2515 sondern "NUR" einen Tranceiver wie z.B. einen
SN65HVD230 data sheet, product information and support | TI.com

oder 233.

Findet man auch als Breakoutboard

Library:
GitHub - sandeepmistry/arduino-CAN: An Arduino library for sending and receiving data using CAN bus.

Oh klasse das geht ja schnell hier.
Zum Verständnis, es gibt nur "einen Empfänger" also meine zusätzliche Anzeige, es handelt sich um ein Canchecked MFD32s und eben evtl. den ESP32. Ja beide sollen in den OEM Canbus. Das MFD habe ich schon drin und es hört auch mit und funktioniert. Aber ohne das ich die ID's weiß, kann ich eben nichts auswerten. Es ist durchaus möglich das Volvo die Drehzahl auch noch in einem anderen Paket auf den Bus legt aber es weiß keiner wo und wie, mit welcher ID etc. Zu allem Überfluss hat Volvo sein komplettes CAN Protokoll 2002,2003 und 2004 für jedes Modelljahr geändert. Erst seit dem ist es einigermaßen konstant. Auch liegen bei mir HS Can 250kbit/s für Motor etc. und LS Can 125kbit/s (Innenraum, Radio, Lenkrad etc.) noch nicht auf der OBD Buchse. Das ist erst ab 2005. Volvo gibt rein gar nichts heraus, daher nehmen alle DIY Projekte bei Github etc. diese "Serviceanfragen" Mir reicht daher, glaube ich, ein CAN Anschluss auf den mit 250kbit/s.
Ich möchte später neben der Drehzahl, gerne die Luftmasse, Ansaugtemperatur und Ladedruck ebenfalls anzeigen. Es müssen also periodisch immer diese Requests gesendet werden.
Der Kollege geht noch viel weiter, da er gleich ein Display mit verwendet und auf beide CAN's geht.
Volvo C30 Arduino Boost Gauge and CAN Bus Reverse Engineering - YouTube

Grüße Andreas

Wieso nimmst Du nicht den Uno Rev 4, der hat doch gleich einen CAN Bus on Board?

Hallo Martin,

danke für deine Antwort. Weil ich leider schlicht weg keine Ahnung habe. Ich habe mir den Link von @noiasca angesehen und dort scheint es nur für den ESP32 etwas zu geben. Ich habe mir eben die ersten Tutorials angesehen damit ich nicht ganz blöd da stehe und wegen jeder Frage hier schreiben muss. Ich bin für jeden Input dankbar und es wäre Klasse wenn Ihr ein Greenhorn etwas an die Hand könntet. Ich habe leider aktuell nicht die Zeit mich in die Materie voll einzulesen. Ich kann zwar aus den Studium noch etwas C++ verstehen, dann hört es aber schon auf.
Vielen Dank für eure Hilfe
Andreas

Ich würde mir an deiner stelle den Uno R4 genauer anschauen. Wenn man schon ein neues Projekt anfängt. Und C++ ja da bin ich grade am lernen. Aber hier gibt es ja Menschen die helfen können.

So ein Klotz nur für CAN? da hat er halben Wagen voll :wink:

ESP32 kann das auch, nur nicht in ganzer Breite wen es geht um BPS, und ist 1/3 so groß

Ob das wohl stimmt :crazy_face:

Die Kombination ist eher ungünstig, da Bibliotheken die eingebauten Register des ESP32 bedienen. Ich nutze den ESP32 zusammen mit TJA1050 CAN Bus Tranceiver Modul.

Die Adresse deutet auf eine "extended ID" hin.

Du könntest mal dieses Programm probieren, getestet mit ESP32:

Programm
// SJA1000 | ESP32
// ------- | -----
//     3V3 | 3V3
//     GND | GND
//     CTX | 5
//     CRX | 4
//

#include <Arduino.h>
#include <ESP32CAN.h>  // https://github.com/miwagner/ESP32-Arduino-CAN
#include <CAN_config.h>

CAN_device_t CAN_cfg;               // CAN Config
unsigned long previousMillis = 0;   // will store last time a CAN Message was send
const int interval = 1000;          // interval at which send CAN Messages (milliseconds)
const int rx_queue_size = 10;       // Receive Queue size

void setup() {
  Serial.begin(115200);
  Serial.println("Basic Demo - ESP32-Arduino-CAN");
  CAN_cfg.speed = CAN_SPEED_250KBPS;
  CAN_cfg.tx_pin_id = GPIO_NUM_5;
  CAN_cfg.rx_pin_id = GPIO_NUM_4;
  CAN_cfg.rx_queue = xQueueCreate(rx_queue_size, sizeof(CAN_frame_t));
  // Init CAN Module
  ESP32Can.CANInit();
}

void loop() {
  unsigned long currentMillis = millis();

  // Receive next CAN frame from queue
  CAN_frame_t rx_frame;
  if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, 3 * portTICK_PERIOD_MS) == pdTRUE) {

    if (rx_frame.FIR.B.FF == CAN_frame_std) {
      printf("New standard frame");
    }
    else {
      printf("New extended frame");
    }

    if (rx_frame.FIR.B.RTR == CAN_RTR) {
      printf(" RTR from 0x%08X, DLC %d\r\n", rx_frame.MsgID,  rx_frame.FIR.B.DLC);
    }
    else {
      printf(" from 0x%08X, DLC %d, Data ", rx_frame.MsgID,  rx_frame.FIR.B.DLC);
      for (int i = 0; i < rx_frame.FIR.B.DLC; i++) {
        printf("0x%02X ", rx_frame.data.u8[i]);
      }
      printf("\n");
    }
  }

  // Send CAN Message
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    CAN_frame_t tx_frame;
    tx_frame.FIR.B.FF = CAN_frame_ext;
    tx_frame.MsgID = 0x000FFFFE;
    tx_frame.FIR.B.DLC = 8;
    tx_frame.data.u8[0] = 0xCD;
    tx_frame.data.u8[1] = 0x7A;
    tx_frame.data.u8[2] = 0xA6;
    tx_frame.data.u8[3] = 0x10;
    tx_frame.data.u8[4] = 0x1D;
    tx_frame.data.u8[5] = 0x01;
    tx_frame.data.u8[6] = 0x00;
    tx_frame.data.u8[7] = 0x00;
    ESP32Can.CANWriteFrame(&tx_frame);

    printf("Sende MsgID 0x%08X, DLC %d, Data ", tx_frame.MsgID,  tx_frame.FIR.B.DLC);
    for (int i = 0; i < tx_frame.FIR.B.DLC; i++) {
      printf("0x%02X ", tx_frame.data.u8[i]);
    }
    printf("\n");
  }
}

Viel Erfolg, bitte berichte :slightly_smiling_face:

1 Like

Du, das ist ein Volvo , nicht irgend so ne ü-Ei Knutschkugel , da geht schon was rein. Das seh ich auch bei meinem 22 Jährigen V70 .

wir das jemals erfahren :wink:

Ja, kenne den, einer steht bei uns in der Tiefgarage, der Eigentümer pflegt den mehr als seinen Merz was stecht dauerhaft unter der Laterne.
War ja auch extra übertrieben meinerseits.
Ob das wirklich ein S60R ist muss mal schauen jedoch ist auch Elter als 20J

Ohh Wahnsinn, vielen vielen Dank für die ganzen Tips hier. Natürlich werde ich berichten. Ich habe jetzt erst einmal die Hardware bestellt die hoffentlich noch vor dem Wochenende bei mir eintrifft.
Ganz konkret ist es ein ESP-32 Kit mit einem TJA1050 Can Board und einem Step Down Converter geworden.
Ich bin gespannt ob ich überhaupt Daten auf das Board bekomme :slight_smile:
Und ja auch mein Volvo steht mehr als er gefahren wird aber trotzdem mag ich das Auto sehr und vor allem hat es nach 20 Jahren nirgends auch nur leichten Rost. Aber klar, wird im Winter auch nicht gefahren. Ich verspreche, wenn es läuft mache ich gerne Bilder oder auch ein Video davon. Nochmals herzlichen Dank, das hätte ich nicht gedacht.
Andreas

@agmue danke für das Programm.
Darf ich dazu noch etwas fragen? Die, ich glaube man nennt es Bibliothek, ESP32CAN.h und CAN_config.h muss ich von github laden und einfügen?
Und in deinem Programm wird wegen der const int interval = 1000; die Abfrage jede Sekunde einmal gesendet?
Vielleicht muss ich meine Frage anders formulieren, wie funktioniert das im CANbus, es können doch sicherlich nicht alle Geräte gerade auf den Bus "rufen" wie es ihnen gefällt? Es muss doch sicherlich auf eine "Lücke" gewartet werden, bevor der Arduino die Nachricht senden darf? Ich frage so doof da das Intervall für die Ansaugtemperatur sicherlich jede Sekunde dicke reicht, die Drehzahl aber vermutlich eher alle 100ms abgefragt werden muss damit mein "digitaler Zeiger" sich auch smooth bewegt :slight_smile:
Danke und Grüße
Andreas

Das ist so in CAN vorgesehen. Pakete haben Prioritäten, wichtige Pakete "überschreiben" weniger wichtige Pakete.

Ja, nur zu :slightly_smiling_face:

Ja, alle Dateien und Verzeichnisse. Wenn Du auf "Code" klickst, bekommst Du einen komprimierte Datei, die Du in des Bibliotheksverzeichnis kopierst, das am Sketchbookverzeichnis klebt. Sieht beispielsweise bei mir so aus:

grafik

Möglicherweise ist meine Bibliothekswahl auch nicht glücklich, aber bei mir hatte ich damit Erfolge. Mit der von @noiasca vorgeschlagenen bin ich nicht so richtig glücklich geworden, müßte ich einfach nochmal probieren.

Ja. Es geht zunächst darum, erstmal eine Reaktion zu bekommen.

Ja, jeder Bus hat eine Kollisionserkennung. Beim CAN-Bus gibt es auch noch eine Prüfsumme für die Datensicherheit. Du mußt Dich darum nicht kümmern, Hardware und Bibliothek machen das für Dich.

Ich auch!

Perfekt, ich glaube das habe ich verstanden :slight_smile: Danke

Die andere Bibliothek läßt sich mit dem Bibliotheksverwalter installieren:

Programm
// SJA1000 | ESP32
// ------- | -----
//     3V3 | 3V3
//     GND | GND
//     CTX | 5
//     CRX | 4
//

#include <CAN.h>  // https://github.com/sandeepmistry/arduino-CAN

void setup() {
  Serial.begin(115200);
  Serial.println("\nStart ESP32-CAN");

  if (!CAN.begin(250E3))  // start the CAN bus at 250 kbps
  {
    Serial.println("Starting CAN failed!");
    while (1);
  }
}

const byte msg[1][8] =
{
  {0xCD, 0x7A, 0xA6, 0x10, 0x1D, 0x01, 0x00, 0x00},  // Motordrehzahl
};

void loop() {
  // send extended packet: id is 29 bits, packet can contain up to 8 bytes of data
  Serial.print("Sende erweitertes Paket ... ");

  CAN.beginExtendedPacket(0x000FFFFE);
  for (byte j = 0; j < 8; j++)
  {
    CAN.write(msg[0][j]);
  }
  if ( CAN.endPacket() )
  {
    Serial.println("verschickt");
  } else {
    Serial.println("Fehler");
  }

  delay(1000);
}

Wenn Du auch Nachrichten empfangen möchtest, müßte das noch ergänzt werden.

Mit einem Display könntest Du Dir Informationen beispielsweise zur Fehlersuche ohne Läppi anzeigen lassen. Ein kleines OLED an I²C kann hilfreich sein.

Danke. Nee so weit will ich noch gar nicht gehen. Wie gesagt zum Empfangen und Anzeigen der Nachrichten ist erst einmal mein externes Display gedacht, da dieses aber nicht senden kann, versuche ich diesen Umweg zu gehen. Ich wäre so happy wenn das geht. :upside_down_face: