Guten Morgen,
vorerst einmal, ich bin neu hier im Forum =] Habe aber schon ein wenig
mitgelesen und über die Suchfunktion nach meinem Thema gesucht, leider
nicht fündig geworden.
Ich bin derzeit dabei ein OBD-Interface mit einem ATmega32 aufzubauen.
Als Scnittstelle zum Auto habe das Diamex DXM-Modul, dass mir alle
Protokolle aufschlüsselt, ich muss lediglich eine serielle Kommunikation
zw. DXM Modul und ATmega herstellen.
Soweit klappt das auch erstmal alles ganz gut, siehe obiges Bild! Jetzt
hab ich folgendes Problem, ich will die Daten nicht nur anzeigen,
sondern bspw. mit anderen Größen verknüpfen, vor allem muss man sie erst
noch decodieren. Bsp.: auf dem Bild zu sehen 41 05 43
"41" ist der Identifier vom Motorsteuergerät
"05" ist der PID, Parameter Identifier, hier Kühlertemperatur
"43" ist der tatsächliche Wert: 4*16 + 3 = 67, jetzt noch 40°C abziehen
und dann ist die Kühlertemperatur von 27°C berechnet (ist auch korrekt
so ;-))
Im Programm selbst habe ich den String als char* vorliegen, habe schon
mit sprintf und sscanf versucht, der Controller stürzt dann ab,
respektive resettet sich immer wieder selbst.
1
sprintf(buffer,"%c%c",inbuffer[6],inbuffer[7]);
2
sscanf(buffer,"%x",&tmp_CoolantTemp);
3
4
tmp_CoolantTemp=tmp_CoolantTemp-40;
Ich hoffe ihr könnt mir weiterhelfen. Ist es eventuell ratsam einen
anderen µC zu nehmen, wie z.B. einen 32bit?
Ich freue mich riesig auf Antworten und verbleibe bis dahin
mit freundlichen Grüßen
Marc Nitze
haben die Daten denn immer dieses XA YB ZC Format? wenn ja, würde ich
einfach immer die beiden einzelnen Zeichen/chars nehmen und einfach
Zahl1 = 10*(X-0x30)+(A-0x30)
etc machen
Marc N. schrieb:> Ich hoffe ihr könnt mir weiterhelfen. Ist es eventuell ratsam einen> anderen µC zu nehmen, wie z.B. einen 32bit?
Was soll das bringen.
Ratsam wäre ein C-Buch und ein paar Übungsstunden auf dem PC
Also:
Ich hab dein Problem jetzt noch nicht wirklich verstanden.
Allerdings drängt sich die Frage auf, warum du da jetzt einen Umweg über
sprintf/sscanf machst.
tmp_CoolantTemp = inbuffer[6] * 16 + inbuffer[7];
scheint das zu sein, was du suchst.
Karl heinz Buchegger schrieb:> tmp_CoolantTemp = inbuffer[6] * 16 + inbuffer[7];> scheint das zu sein, was du suchst.
Wird für ASCII-Hex-Zahlen so nicht gehen...
Marc N. schrieb:> Ich hoffe ihr könnt mir weiterhelfen.
Hart aber herzlich wäre sowas:
1
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
Das Format ändert sich für andere PID's, bspw. die Motordrehzahl. Da
sind dann 2 Bytes auszuwerten, siehe die Zeile darüber. Dort erfolgt die
Umrechnung mit:
((A*256)+B)/4 = x -> 41 0C 0C E5, dabei ist 0C das Byte A, E5, das Byte
B... Zudem kann bei jedem der PID's noch "CAN ERROR" zurückkommen,
leider^^
Grüße
Marc
Karl heinz Buchegger schrieb:> Allerdings drängt sich die Frage auf, warum du da jetzt einen Umweg über> sprintf/sscanf machst.>> tmp_CoolantTemp = inbuffer[6] * 16 + inbuffer[7];>> scheint das zu sein, was du suchst.
Oder wenn das Hex Zahlen sein sollen:
Lothar Miller schrieb:> Karl heinz Buchegger schrieb:>> tmp_CoolantTemp = inbuffer[6] * 16 + inbuffer[7];>> scheint das zu sein, was du suchst.> Wird für ASCII-Hex-Zahlen so nicht gehen...
Habs auch grad bemerkt.
Die Info ist mir beim ersten Durchlesen der Frage entgangen.
Marc N. schrieb:> Das Format ändert sich für andere PID's, bspw. die Motordrehzahl. Da> sind dann 2 Bytes auszuwerten,
Das macht nichts.
Bau dir eine Funktion die erst mal 1 Byte entsprechend umwandelt.
Die nimmst du dann als Baustein um mehrere Bytes entsprechend
umzuwandeln.
Genau aus dem Grund hat man ja Funktionen.
Damit man aus einfachen Basisfunktionalitäten komplexere
Funktionalitäten zusammensetzen kann.
>> Ich kann diese Funktion nicht nachvollziehen, sie wandelt mir ein> Hex-Byte in einen Integer um, korrekt? Wie tut sie das?
indem sie unterscheidet, ob es sich beim ASCII Zeichen um eines im
Bereich '0' bis '9' handelt oder nicht (dann kann es nur noch ein
Buchstabe 'A' bis 'F' sein)
isdigit macht das. Das stellt fest ob es sich bei einem Zeichen um eines
im Bereich '0' bis '9' handelt.
Wenn ja, dann wird vom Zeichen, eigentlich dessen ASCII Code, der ASCII
Code von '0' abgezogen. Aus '0' wird 0, aus '1' wird 1, etc.
Dasselbe bei den Buchstaben
Aus 'A' muss 10 werden, aus 'B' muss 11 werden etc.
Zieht man daher vom Zeichen den ASCII Code von 'A' ab, dann wird 'A' zu
0, 'B' zu 1, 'C' zu 2 etc. Dann noch 10 dazuzählen und aus 0, 1, 2, 3
wird 10, 11, 12 13 ....
x - 'A' + 10
Lothar hat das 'A' + 10 zusammengezogen (hätte er nicht machen müssen.
das macht der Compiler auch).
Und das ? :
Das ist einfach nur die kurze C-Schreibweise für
if ( a )
b = c;
else
b = d;
oder in Kurzform
b = a ? c : d;
und da das alles Basissachen in der C Programmierung sind, bleibe ich
nach wie vor dabei, dass dein Hauptfehler darin besteht, dass du kein
C-Buch durchgearbeitet hast. Eine Sprache wie C kann man nicht nach dem
Muster Versuch und Irrtum erlernen. Dazu hat sie viel zu viele
Feinheiten und Nuancen. Geht man da nicht systematisch ran, dann ist
hinterher das Geschrei immer groß, dass C soooo kompliziert und
fehleranfällig wäre.
isdigit(x) ? x - '0' : x - 'W'
wenn x eine Zahl ist dann wird x-'0' gerechnet (also ASCII 0)
sonst wird x-'W' gerechnet (also ASCII W)
Schau dir mal die ASCII Tabelle an. Die '9' ist z.B. die dez 57, wird
davon nun '0' (also dez 48) abgezogen, so erhälst du deine int 9
Marc N. schrieb:> Ich kann diese Funktion nicht nachvollziehen, sie wandelt mir ein> Hex-Byte in einen Integer um, korrekt? Wie tut sie das?
Erst mal das Makro:
es wandelt ein Ascii-Zeichen in einen Integer zwischen 0..15 um. Zum
Nachvollziehen ist eine ASCII-Tabelle sinnvoll...
Statt:
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
könnte man auch schreiben:
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'a' + 10)
Weil 0xa = 10 ist...
Am Rande sollte man wissen, dass das Makro nur für "kleine" Hex-Zahlen
funktioniert 0..9, a..f
Für "große" Hex-Zahlen (0..9, A..F) wäre das hier nötig:
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'A' + 10)
bzw:
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - '7')
Vielleicht wirds jetzt klarer?
Vielen Dank auf jeden Fall für eure Hilfe! Werde mal nach einem
geeigneten Buch suchen! Hoffe, dass ich dennoch bei weiteren Fragen auf
euch zurückgreifen darf!
Grüße
Marc
Marc N. schrieb:> Vielen Dank auf jeden Fall für eure Hilfe! Werde mal nach einem> geeigneten Buch suchen! Hoffe, dass ich dennoch bei weiteren Fragen auf> euch zurückgreifen darf!
Natürlich.
Aber du hast einfach mehr von der Sprache, wenn dein Verständnis nicht
auf in Foren zusammengefragtem Halbwissen beruht.
Kernighan&Ritchie Programmieren in C
ist zb der Klassiker der C-Bücher