Forum: Mikrocontroller und Digitale Elektronik Arduino mit CAN-Shield Can-Daten auslesen


von DanielDuesentrieb (Gast)


Lesenswert?

Guten Tag,

ich hab ein Arduino Uno und das Sparkfun CAN Shield und würde gern die 
Geschwindigkeit eines Wagens und Drehzahl von dessen Motors (Audi A3, BJ 
2008) auslesen.
Ich hab CAN High, Can Low, 5V und GND hinterm Navi oder aus dem OBD2 
Port.

Verbinde ich jeden der Pins vom Shield mit den jeweiligen Pins auf dem 
Arduino? Dann ist der Uno nämlich komplett voll und ich muss mindestens 
ein, besser ein paar mehr Pins frei haben für ein paar kontroll LEDs. 
Braucht das Shield immer alle Pins oder kann man die ggf noch anders 
benutzen, falls sie das Shield nicht braucht ?

Dann die wichtige Frage:
Wie kriege ich die Drehzahl und die Geschwindigkeit aus dem CAN 
ausgelesen?

#include <Canbus.h>
if(Canbus.init(CANSPEED_500))  den Can Chip initialisieren

und dann mit Canbus.ecu_req(VEHICLE_SPEED,buffer) in einen puffer 
schreiben ?
Ich hätte am liebsten so eine funktion wie

int rpm=Can.lese_rpm();

Ich wär für eine keine Hilfestellung dankbar!

VG
Daniel

von Horch (Gast)


Lesenswert?

Na super, frage doch mal bei Audi, ob sie dir die Bordnetzdatenbank zur 
Verfügung stellen.

von DanielDuesentrieb (Gast)


Lesenswert?

Über OBD2 kann ich die Daten ja auch "quelloffen" und standarisiert 
auslesen, und OBD2 läuft ja auch über CAN. Die gewünschten Infos müsste 
ich also schon bekommen können.

von Amateur (Gast)


Lesenswert?

Es gibt im Netz, auch rund um den Arduino, mehrere Projekte die genau 
dies machen.
Allerdings musst Du dazu schon eine einfache Abfrage loslassen können.
Bing oder Google helfen z.B.

von Dieter K. (geige_d)


Lesenswert?

Hey DanielDuesentrieb,

dieses Projekt würde mich auch interessieren - wäre also nett wenn Du 
Deine Fortschritte posten würdest!

Ohne konkretes Projektinteresse habe ich mir bisher nur mal 
"vorsichtshalber" diese Adresse notiert:
http://www.canhack.de
Vl kommst Du da ja etwas weiter...

Prinzipiell weiß ich nur aus meinen Erfahrungen mit VAG-Codierungen daß 
man zuerst ein bestimmtes Steuergerät adressieren muß (in Deinem Fall 
mit der Drehzahl wäre dies das Motorsteuergerät,  VAG-Adresse 01). Das 
bietet wie alle anderen STGs verschiedene Modi - u.a. die Codierung 
(Statusbytes lesen/schreiben) sowie die Meßwertblöcke (MWBs). Was für 
Dich dann wohl interessant ist.
Bei meinem Golf 6, (den ich aber nicht mehr besitze) konnte man die 
Drehzahl u.a. in MWB 117, Feld 0 einlesen. Könnte mir vorstellen daß das 
bei Deinem 2008er-A3 identisch ist.
Dies beschreibt die Adressierung mit dem Codiersystem "VCDS", wie das 
auf direkte CAN-Busabfrage umzusetzen ist weiß ich aber nicht.

Bei Interesse kann ich Dir aber z.B. eine exportierte VCDS-CSV-Datei 
sowie die daraus erzeugte Grafik hochladen (da habe ich Ladedruck in 
Abhängigkeit von Drehzahl und Gaspedalstellung aufgezeichnet).

Über die OBD(2)-API wirst Du an die gewünschten Parameter nur sehr 
bedingt rankommen. OBD2 eignet sich grundsätzlich nur zum Auslesen von 
TÜV-... äh CO2-... äh Weltrettungsdaten. Drehzahl solte man da zwar auch 
finden, ansonsten aber wirklich nichts Interessantes.
Für alles andere muß man sich die VAG-spezifischen CAN-Bus-Daten 
verschaffen - nur damit kann man auch die anderen STGs des Audis 
auslesen bzw. ändern.

: Bearbeitet durch User
von Rudolph (Gast)


Lesenswert?

Ähem, also während der Fahrt einem Steuergerät Diagnose aufzudrücken 
dürfte schon als Eingriff ins Bordnetz gelten, dazu sollte man echt 
besser wissen was man da tut und nicht nur ich-klicks-mir-zusammen 
Cowboy sein.

Im Grunde muss man beim CAN nur auf die passende Botschaft warten und 
diese auswerten.
Für sowas dann am besten auch möglichst elektrisch neutral und im 
Listen-Only Modus.

von Rudolph (Gast)


Lesenswert?

DanielDuesentrieb schrieb:
> Ich hätte am liebsten so eine funktion wie
>
> int rpm=Can.lese_rpm();

Sowas gibt es in Zusammenhang mit CAN nicht, die Botschaft die man lesen 
möchte liegt irgendwann mal auf dem Bus - oder auch nicht.
Eine Botschaft kann man im allgemeinen nicht anfordern und auf eine eine 
bestimmt Botschaft zu warten ist gar keine gute Idee.

Der CAN-Controller wird konfiguriert auf eine Botschaft oder eine Gruppe 
von Botschaften zu lauschen und wenn er was empfangen hat wird ein 
Interrupt generiert und das ganze ausgelesen.
Wenns schnell geht verarbeitet man das gleich im Interrupt oder setzt 
vielleicht noch ein Flag für das Hauptprogramm das die Daten mal wieder 
neu und gültig sind.

von DanielDuesentrieb (Gast)


Lesenswert?

An alle Kritiker:

Ich hab so ziemlich alles an meinem Auto verändert, was man nur 
verändern kann und wir haben jede Schraube umgedreht. Es handelt sich um 
einen TT RS mit gut 550PS für die Rennstrecke und den Straßenbetrieb. 
Der Wagen ist komplett TÜV-abgenommen. Es gibt glaub ich weitaus größere 
Dinge, an denen ich schon dran war. Ich hab ein abgeschlossenes Studium 
und bin nicht auf den Kopf gefallen.
Wie auch immer. Ich bin einfach ein bisschen allergisch gegen so etwas 
wie "ich klicks mir zusammen cowboy" und dann noch nichts der Sache 
beizutragen.

Nun. Da der Wunsch geäußert wurde, dass ich meine Fortschritte poste:
Ich kann nun nach anfänglichen Schwierigkeiten die Daten alle über die 
Serielle Schnittstelle auslesen, nur wollte ich zu Diagnosezwecken das 
LCD anhängen. Ich hab ein  HD44780  kompatiblen Controller und kann 
damit ohne Probleme was anzeigen, nur bietet mir das Shield nur 3 
Anschlüsse für den LCD, es muss sich also irgendwie um eine serielle 
Datenübertragung handeln.

Shield und LCD sehen so aus.
Gibt es eine Möglichkeit das zu verarzten und miteinander zu verbinden 
oder brauch ich ein anderes Display ?


MFG
Daniel

von DanielDuesentrieb (Gast)


Lesenswert?

Bevor jetzt einer den unnützen kommentar sendet "da gabs noch gar keinen 
RS" - stimmt. Die Basis ist ein TTS, aber die Bezeichnung wird dem nicht 
mehr gerecht. Wie auch immer ;-)

von Dr. Sommer (Gast)


Lesenswert?

Nimm doch einen Mikrocontroller mit integriertem CAN-Controller, da ist 
das Ansprechen gleich viel einfacher. Externe Controller sind doch nur 
Fummelei. Der vom STM32F103 zB sendet bei Kollisionen immer nochmal, wie 
es vorgesehen ist (kann man aber abschalten). Wenn eine Nachricht 
angekommen ist, gibts nen Interrupt.

von kevin (Gast)


Lesenswert?

Drehzahl und Geschwindigkeit findest du mehrmals die Sekunde auf dem 
Bus, du musst nur wissen in welchem Paket es steht. Dann musst du in 
deinem Controller einen Filter auf genau diese ID setzen.

von kevin (Gast)


Lesenswert?

Und immer im Passive-Mode arbeiten, am besten den TXD Pin des 
Transceivers gar nicht anschließen!!

von Dr. Sommer (Gast)


Lesenswert?

kevin schrieb:
> am besten den TXD Pin des
> Transceivers gar nicht anschließen!!
Genau, um alle Störungen die dann am TXD Pin ankommen auf den Bus 
rauszuhauen.

von kevin (Gast)


Lesenswert?

..dann eben mit einem Pull-Down an GND

von Thomas F. (igel)


Lesenswert?

> ..dann eben mit einem Pull-Down an GND

Wie weit willst du denn den GND noch runterziehen? :-)

Oder doch lieber am TXD?

von kevin (Gast)


Lesenswert?

*nach GND, du quatschkopp

von Dieter K. (geige_d)


Lesenswert?

> Shield und LCD sehen so aus.
Wie? :)

> Gibt es eine Möglichkeit das zu verarzten und miteinander zu verbinden
> oder brauch ich ein anderes Display ?
Ich kenne Dein Shield nicht, aber wenn die I2C-Schnittstelle an den Pins 
A4 und A5 nicht benutzt wird kannst Du damit ein I2C-LCD-Display (sowie 
weitere I2C-Module...) ansteuern - das Ganze begnügt sich dann mit 
diesen 2 Pins + Stromversorgung.

Wie kann man das CAN-Shield denn ansprechen? Wird da eine Bibliothek 
mitgeliefert?

von Thomas (Gast)


Lesenswert?

Hier stehen die Daten die man Abfragen kann:
http://en.wikipedia.org/wiki/OBD-II_PIDs

Hier gibts ne Library:
https://code.google.com/p/mechanic/

Und ein bissl Beispielcode (in dem Fall für ein CAN-Shield von 
Seedstudio http://www.seeedstudio.com/wiki/CAN-BUS_Shield) gibts auch 
noch:
1
#define     LCDCOLS             16
2
#define     LCDROWS             2
3
#define     lcdinitsequence     LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
4
5
/*
6
Hardware:
7
1x Arduino Uno
8
1x CAN-BUS Shield von Seedstudio
9
1x LCD-Display von Sainsmart mit Buttons die am Analog PIN A0 liegen
10
1x Opel Astra H
11
12
Der Opel Astra H unterstuetzt folgende PIDs:
13
0x00 PIDs supported [01 - 20]
14
0x01 Monitor status since DTCs cleared
15
0x04 Calculated engine load value
16
0x05 Engine coolant temperature
17
0x0B Intake manifold absolute pressure
18
0x0C Engine RPM
19
0x0D Vehicle speed
20
0x0F Intake air temperature
21
0x10 MAF air flow rate
22
0x1C OBD standards this vehicle conforms to
23
0x20 PIDs supported [21 - 40]
24
0x21 Distance traveled with malfunction indicator lamp (MIL) on
25
0x23 Fuel Rail Pressure (diesel, or gasoline direct inject)
26
0x2C Commanded EGR
27
0x33 Barometric pressure
28
0x40 PIDs supported [41 - 60]
29
0x41 Monitor status this drive cycle
30
0x42 Control module voltage
31
0x49 Accelerator pedal position D
32
0x4A Accelerator pedal position E
33
*/
34
35
#include <Mechanic.h>
36
#include <SoftwareSerial.h>
37
#include <LiquidCrystal.h>
38
39
// LCD Instanziierung
40
lcdinitsequence
41
42
ObdInterface obd;
43
ObdMessage msg;
44
45
void setup()
46
{
47
// LCD-Display initialisieren
48
delay(2000);                      // Noetig da sonst init des Displays nicht klappt (Spannunsproblem?)
49
lcd.begin(LCDCOLS, LCDROWS);            // LCD mit LCDCOLS Spalten, LCDROWS Zeilen
50
lcd.setBacklightPin(3, POSITIVE);
51
lcd.setCursor(LCDCOLS - strlen(myversion), 0);
52
lcd.print(myversion);
53
lcd.setCursor(0, 1);
54
lcd.print("init...");
55
delay(1000);
56
57
obd.setSlow(false);
58
obd.setExtended(false);
59
obd.setDebug(true);
60
obd.begin();                      // Gibt es einen HARDWARE-Fehler bleiben wir hier haengen
61
lcd.clear();
62
}
63
64
void loop()
65
{
66
char buffer[16];
67
68
// Links oben, Temperatur angesaugte Luft
69
obd.getPidAsString(0x0F, -40.0f, 215.0f, "%d", buffer);
70
lcd.setCursor(8, 2);
71
lcd.print("      ");  
72
lcd.write(0xDF);                // Grad-Zeichen
73
lcd.print("C");
74
lcd.setCursor(8, 2);
75
lcd.print(buffer);
76
77
// Rechts oben: Temperatur Kuehlfluessigkeit
78
obd.getPidAsString(0x05, -40.0f, 215.0f, "%d", buffer);
79
lcd.setCursor(8, 0);
80
lcd.print("      ");  
81
lcd.write(0xDF);                // Grad-Zeichen
82
lcd.print("C");
83
lcd.setCursor(8, 0);
84
lcd.print(buffer);
85
86
// Links unten: Umdrehungsgeschwindigkeit Motor
87
obd.getPidAsString(0x0C, 0.0f, 16383.75f, "%d", buffer);
88
lcd.setCursor(0, 1);
89
lcd.print("     rpm");  
90
lcd.setCursor(0, 1);
91
lcd.print(buffer);
92
93
// Rechts unten: Aktuelle Geschwindigkeit in km/h
94
obd.getPidAsString(0x0D, 0.0f, 255.0f, "%d", buffer);
95
lcd.setCursor(8, 1);
96
lcd.print("    km/h");  
97
lcd.setCursor(8, 1);
98
lcd.print(buffer);
99
100
delay(50);  
101
}

Einen richtigen ODBII-Stecker musst du noch kaufen (gibts z.B. bei 
Watterott) und richtig auf das Shield verbinden.
War glaub ich nur GND, VCC, CAN-H und CAN-L - kein Hexenwerk.

Meld dich bei Fragen.

Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.