Hallo,
ich bin zur Zeit dabei, ein Programm (c) zu schreiben, welches aus einem
Textdokument CAN-Daten einließt und als CAN-Botschaft über einen
Transceiver ausgibt. Klappt soweit auch alles. Ich würde nur gerne mal
um Hilfe bitten, wie ich meine ID's vergleiche.
Und zwar muss ich u.a. unterschiedliche ID's (Integer) auf irgendeine
Art und Weise vergleichen um heraus zubekommen, ob es sich dabei um
einen Stadard Frame (11-Bit) oder einen Extended Frame handelt (29-Bit).
Es gibt also Integer die z.B. wie folgt aussehen (Extended):
1B000012x, 1BFC0C11x, 1BFC0C21x.
Und Integer die so aussehen (Standard):
86, B4, 121.
Je nachdem um welches Format es sich handelt muss ich einen IF-Vergleich
starten und 2 Unterschiedliche Wege in meinem Programm gehen.
Nur jetzt die Frage? Wie prüfe ich am schlausten ob es sich um ein
Stadard oder Extended Format handelt?
Falls Ihr einen Tipp für mich habt, dann bitte so, dass auch ein
interessierte Anfänger wie ich damit klar kommt.
Vielen Dank,
Jim
Was wenn es ein Extended Frame mit 29 bit ist, aber dennoch eine kleine
Zahl als ID wie 86 drinsteht? Du musst das IDE bit des CAN Controllers
abfragen, um zwischen Extended und Standard Format zu unterscheiden.
Ich kann das IDE Bit nicht abfragen weil es erst durch den
CAN-Transceiver erzeugt wird.
Im Textdokument einlesen tue ich lediglich die ID, den DLC und die
Daten. den Rest baut der Transceiver nachm senden von alleine.
Da muss es noch eine andere Möglichkeit geben ;-)
Jim Street schrieb:> Ich kann das IDE Bit nicht abfragen weil es erst durch den> CAN-Transceiver erzeugt wird.
Nein, das macht der CAN-Controller. Der Transceiver ist nur ein dummer
Levelshifter. Außerdem sendet der CAN-Controller als Wert des IDE-Bits
exakt das, was die Software ihm gibt.
> Im Textdokument einlesen tue ich lediglich die ID, den DLC und die> Daten. den Rest baut der Transceiver nachm senden von alleine.
Kann nicht, man muss ihm das IDE-Bit mitgeben.
Wenn du jetzt lediglich herausfinden willst ob eine gegebene ID in das
Standard Format hineinpasst, vergleiche doch einfach mit der maximal
möglichen ID von 0x7FF. Ist sie größer, brauchst du ein Extended Frame,
ist sie kleiner oder gleich, reicht ein Standard Frame.
Hey, vielen Dank.
Mit der maximal möglichen ID für Standard-Frame von 0x7FF zu vergleichen
ist eine gute Idee.
Kann ich dafür dann die üblichen Vergleichsoperatoren nutzen oder
funktioniert das nicht weil es Hexadezimal ist? Also wie Folgt:
int ID_ausgelesen=0x121;
int ID_maximal=0x7FF;
If (ID_ausgelesen <= ID_maximal){
printf ("Es handelt sich um ein Stadard-Frame");
}
If (ID_ausgelesen > ID_maximal){
printf ("Es handelt sich um ein Extended-Frame");
}
Jim Street schrieb:> Hey, vielen Dank.>> Mit der maximal möglichen ID für Standard-Frame von 0x7FF zu vergleichen> ist eine gute Idee.>> Kann ich dafür dann die üblichen Vergleichsoperatoren nutzen oder> funktioniert das nicht weil es Hexadezimal ist?
Irgendwie verstehe ich dein Problem nicht.
Liest du nun eine Zahl als echte Zahl oder hast du nur einen String als
Leseergebnis?
So etwas wie Hex oder Dezimal existiert in einem Computer gar nicht.
Eine Zahl ist einfach nur ein Bitmuster im Speicher (und genau genommen
ist es damit noch nicht einmal eine Zahl. Zur Zahl wird es erst, wenn du
es wie eine Zahl behandelst). Hex oder Dezimal sind nur unterschiedliche
Schreibweisen von immer demselben. Sie dienen hauptsächlich der
textuellen Darstellung für uns Menschen aber im Rechner gibt es da
keinen Unterschied. Ob man das Bitmuster
1
00101100
als Dezimal 44 oder als Hexadezimal 0x2C anschreibt, ist eine reine
Konvention bei der Ausgabe (und natürlich auch bei der Eingabe), aber
rechnerintern ist es immer dasselbe Bitmuster.
> int ID_ausgelesen=0x121;
Hier wird an die Variable das Bitmuster
1
0000000100100001
zugewiesen.
Du hättest genausogut auch
1
intID_ausgelesen=289;
schreiben können. Denn die beiden Schreibweisen 0x121 und 289 bezeichnen
dasselbe Bitmuster. Und nur dieses Bitmuster ist es, das letzten Endes
für den Rechner interessant ist, wenn er den Vergleich macht. Das eine
Bitmuster kennzeichnet eine Zahl (zb 0x121 oder eben dezimal 289) das
entweder größer oder gleich oder kleiner als das Bitmuster einer anderen
Zahl (die du eben als 0x7FF als Hexadezimalzahl hingeschrieben hast, du
hättest genausogut auch die Dezimalzahl 2047 benutzen können) ist.
Welche Schreibweise du benutzt hast, um die Bitmuster für die Zahlen
anzugeben, interessiert den Computer aber nicht mehr. Wenn das Programm
läuft, existieren nur noch die Bitmuster und nichts anderes mehr.
Die unterschiedlicen Schreibweisen benutzt man je nachdem, was man als
Programmierer erreichen möchte.
Wenn ich haben will, dass ich im C Code möglichst einfach das Bitmuster
wiedererkennen kann (weil das unter Umständen wichtig ist), dann benutze
ich Hexadezimalzahlen
1
intvar=0x0155;
hier kann ich (da ich vertraut mit Hex-Zahlen bin), sofort und ohne
Probleme ablesen, dass ich es mit einem Bitmuster von
1
0000000101010101
zu tun habe und weil an dieser Stelle im Programm es zb wichtig ist, die
1-Bits an den richtigen Stellen zu haben, möchte ich das im Programm
auch leicht erkennen können. Wohingegen der Dezimalwert an dieser Stelle
eher unwichtig ist.
Unsinnig wäre es aber, bei einer Uhrzeit zb die Minutenangabe
hexadezimal anzugeben. Denn hier interessiert mich das Bitmuster
überhaupt nicht. Hier ist mir der numerische Wert der 35. Minute
wichtiger. Daher schreibe ich hier
1
intminute=35;
und nicht
1
intminute=0x23;
auch wenn beides völlig gleichwertig ist. Aber aus leicht ersichtlichen
Gründen, enthält die dezimale Angabe für mich als Mensch eine leichter
zu dekodierende Information (5 minuten nach halb), die an dieser Stelle
wichtiger ist als das Bitmuster 00100011, das sich aus beiden Angaben
ergibt.
Hallo Karl Heinz,
Zur Erklärung:
Ich lese aus einem Textdokument folgendes ein:
0.111111 1 1BCC0C21x Rx d 8 00 01 00 00 00 03 06 28
0.222222 1 121 Rx d 8 00 01 00 00 00 03 06 29
...
Diese Daten filter ich im Programm dann nach dem Zeitstempel, der ID,
dem DLC und den Daten. Und dann schicke ich diese Infos mit einer
CAN-Sendefunktion weg. Über einen CAN-Transceiver kann ich dann schöne
Fahrzeug-CAN-Botschaften erzeugen und auf den Bus senden.
Zur Frage:
Ich muss in der CAN-Sendefunktion vorab deklarieren ob es sich um einen
Standard Frame Format (11-Bit) oder einen Extended Format (29-Bit)
handelt.
Und genau hierfür muss ich die ID's miteinander vergleichen.
Und so wie ich aus deiner Nachricht herauslese ist es jetzt möglich, den
Hexadezimalwert 1BCC0C21x und 121 mit dem größtmöglichen Wert einer
Standard-ID (7FF) zu vergleichen, ja?
Das wäre Top ;-)
LG
die 0x7FF lassen sich unmittelbar in Bit aufdröseln. Das Bitmuster
lautet
1
0000011111111111
und man sieht sofort, dass das Wesentliche an dieser Zahl darin besteht,
dass sie aus 11 Stück 1 Bits besteht. Da diese Infirmation (11 Stück 1
Bits) die wichtigere ist, benutzt du eine Hex-Zahl und nicht die
gleichwertige Dezimalzahl 2047, bei der man erst mal kurz überlegen
muss, warum ausgerechnet 2047)
Und PS:
Wenn du mit Bytes bzw Words oder noch größeren Einheiten hantierst, dann
ist in deinem Zusammenhand der richtge Datentyp auf jeden Fall ein
unsigned Datentyp. D.h. bei dir dann wohl ein unsigned int.
Denn du willst auf keinen Fall haben, dass dir bei bestimmten Bits eine
Vorzeicheninterpretation des Bitmusters in die Quere kommt.
Jim Street schrieb:> If (ID_ausgelesen <= ID_maximal){> printf ("Es handelt sich um ein Stadard-Frame");> }
Könnte auch von einem extended Frame stammen.
Deshalb ist es immer wichtig diese Information mitzugeben. D.h. Du mußt
schauen, dass dein Textfile bereits entsprechend generiert wird.
> Diese Daten filter ich im Programm dann nach dem Zeitstempel, der ID,> dem DLC und den Daten. Und dann schicke ich diese Infos mit einer> CAN-Sendefunktion weg. Über einen CAN-Transceiver kann ich dann schöne> Fahrzeug-CAN-Botschaften erzeugen und auf den Bus senden.
Man mischt selten Standard und Extended Frames. Du kannst daher im
allgemeinen davon ausgehen, wenn dein Dokument große IDs enthält, dass
auch die kleinen IDs extended Nachrichten sind.
Wenn Du selbst loggst, kannst Du es natürlich mal nachprüfen.
Steffen hilf mir mal auf die Sprünge.
So wie ich das sehe ist 'Standard' oder 'Extended' eine Frage dessen,
was ich meinem Sende-IC anweise was es generieren soll. Ob ich die ID
0x0080 als Stamdard oder Extended auf den Weg bringe ist doch so gesehen
für den Sender ziemlich irrelevant (ausser dass ich ihm natürlich die
Anweisung dazu geben muss, wenn er es nicht selbst macht). Klar, der
Empfänger muss Extended unterstützen, aber für den macht es auch keinen
Unterschied ob er jetzt eine ID 0x0080 per Standard oder per Extended
Frame empfängt.
Oder hab ich da jetzt einen groben Fehler in der Denke?
Oder wird das eventuell tatsächlich so gehandhabt, dass Standard-0x80
eine andere Nachricht darstellt als Extended-0x80? Würde mir zwar
seltsam vorkommen, aber man weiss ja nie ...
So gesehen könnte man eigentlich alles als Extended auf den Weg bringen
oder der ganz einfachen Strategie folgen:
Alles was in der ID klein genug ist, kann per Standard rausgehen. Alles
was in der ID für Standard zu gross ist, muss Extended rausgehen.
(Jetzt mal unter Hintanstellen, dass natürlich mehr Bit auch mehr
Übertragungszeit bedeutet)
Ach, dass ist ja doof.
Also gibt es auch extended-Nachrichten die kleiner als 0x7FF sind :-(
Naja also dann brauche ich eine andere Lösung.
Es ist leider so, dass es eine gemische Menge an Standard und Extended
Nachrichten in diesem Dokument gibt. Und das muss auch zwingendermaßen
so sein. Lässt sich nicht ändern.
Und ich kann das Dokument auch nicht umschreiben. Es ist wie oben
beschrieben aufgebaut.
0.111111 1 1BCC0C21x Rx d 8 00 01 00 00 00 03 06 28
0.222222 1 121 Rx d 8 00 01 00 00 00 03 06 29
[Zeitstempel - 1 - ID - RX - d - DLC - Daten]
Habt Ihr noch ne Idee ? :-/
LG
Karl Heinz schrieb:> Oder wird das eventuell tatsächlich so gehandhabt, dass Standard-0x80> eine andere Nachricht darstellt als Extended-0x80?
Normal nicht. Aber wenn der Empfänger gemein ist, könnte er das tun.
Jim Street schrieb:> Naja also dann brauche ich eine andere Lösung.
Es ist unmöglich. Du kannst die nicht vorhandene Information, ob eine
Nachricht mit ID <= 0x7FF jetzt Extended oder Standard ist, nicht
einfach heraufbeschwören. Du könntest höchstens nachsehen, ob die
Empfänger Nachrichten im Extended Format mit ID <= 0x7FF gleich
behandeln wie Nachrichten im Standard Format. In diesem Fall reicht der
einfache Vergleich der ID.
Jim Street schrieb:> Habt Ihr noch ne Idee ? :-/
Ja.
Was bedeutet das x hier
1
1BCC0C21x
Wenn es hexadezimal bedeutet, dann sollte man dem, der sich das
ausgedacht hat gleich mal vorsorglich eine reinhauen.
Wenn du Glück hast, dann bedeutet es 'Extended' und der Autor des
Schreibcodes ist aus dem Schneider und kriegt keine reingehauen sondern
kriegt ein Lob.
Wer schreibt die Datei denn? Steht da immer eine 1 nach dem Zeitstempel
oder ist das vll. die Information die du suchst (Extended Bit gesetzt,
nicht gesetzt)?
Dr. Sommer schrieb:> Karl Heinz schrieb:>> Oder wird das eventuell tatsächlich so gehandhabt, dass Standard-0x80>> eine andere Nachricht darstellt als Extended-0x80?> Normal nicht. Aber wenn der Empfänger gemein ist, könnte er das tun.
Das ist ja fies.
Also wieder mal: nicht definiert wie hier zu verfahren ist?
Jim Street schrieb:> 0.111111 1 1BCC0C21x Rx d 8 00 01 00 00 00 03 06 28> 0.222222 1 121 Rx d 8 00 01 00 00 00 03 06 29>> [Zeitstempel - 1 - ID - RX - d - DLC - Daten]>> Habt Ihr noch ne Idee ? :-/
In deinen ganzen Beispielen hängt bei Extended-CAN-Botschaften immer ein
x hinter der ID, bei Standard-CAN aber nicht. Ds läßt vermuten, daß das
x für extended steht. Nimm doch einfach das.
Karl Heinz schrieb:> Dr. Sommer schrieb:>> Karl Heinz schrieb:>>> Oder wird das eventuell tatsächlich so gehandhabt, dass Standard-0x80>>> eine andere Nachricht darstellt als Extended-0x80?>> Normal nicht. Aber wenn der Empfänger gemein ist, könnte er das tun.>> Das ist ja fies.> Also wieder mal: nicht definiert wie hier zu verfahren ist?
Naja, bei CAN ist es ganz klar so, daß Standard-ID 0x80 und Extended-ID
0x80 verschiedene Botschaften sind. Ein Empfänger kann sich aber
natürlich dazu entscheiden, die so zu behandeln, als seien sie gleich.
Wenn man nicht explizit weiß, daß er das tut, muß man eben
unterscheiden.
Karl Heinz schrieb:> Ob ich die ID> 0x0080 als Stamdard oder Extended auf den Weg bringe ist doch so gesehen> für den Sender ziemlich irrelevant (ausser dass ich ihm natürlich die> Anweisung dazu geben muss, wenn er es nicht selbst macht).
Technisch betrachtet sind dies zwei verschiedene Arten von Frames. Wenn
natürlich beide Seiten das IDE Bit nicht auswerten, gleicht sich das
wieder aus.
Aber z.B. definiert CANopen (Protokoll auf Basis CAN), das die NMT
Nachricht mit Standard ID 0 übertragen wird. Auf extended 0 düfen
korrekte Geräte nicht reagieren. Diese könnte man dann einem anderen
Dienst zuweisen.
Eine extended 0 wird mit 29bit statt mit 11bit übertragen. Braucht also
auch länger auf dem Bus.
Kommt auf Empfängerseite auch noch der Akzeptanzfilter hinzu, wird
garantiert auch das IDE Bit mit maskiert.
Kurz: Du solltest das richtige Format nutzen. Alles andere ist
Glücksache, je nach Implementierung.
Steffen Rose schrieb:> Kurz: Du solltest das richtige Format nutzen. Alles andere ist> Glücksache, je nach Implementierung.
Danke (auch an die anderen).
Das scheint dann ein potentieller Stolperstein zu sein, auf den man
achten sollte.
Karl Heinz schrieb:> Also wieder mal: nicht definiert wie hier zu verfahren ist?
Wenn man das höhere Protokoll kennt, ist auch klar, in welchem Format
die Daten gesendet werden sollen.
Karl Heinz schrieb:> Das scheint dann ein potentieller Stolperstein zu sein, auf den man> achten sollte.
Naja, wenn man das Protokoll nicht hat - Die Analyzer zeigen das Format
auch an. Man sollte sich dann so nah wie möglich am Original halten.
Hallo,
ja Till, meine Datei ist, wie du schon sagst, ein originaler Mitschnitt
eines Traces von Vectors CANoe. Das ja schonmal super, dass du das
erkannt hast. Dadurch kann ich dir folgende Frage stellen:
Weißt du wer das x dahinter setzt? Setzt das CANoe dahinter, damit ich
weiß, dass es sich um ein extended Frame handelt?
Weil mir ist auch bewusst, dass das x nicht im Hexadezimalen vormommt.
Muss ich das x auch wieder auf den BUS senden? oder muss ich das durch
irgendeine Art herausfiltern?
Also schließlich scheint es mir so, als wenn ich dieses misteriöse x
nutzen muss um die beiden Nachrichten miteinander zu vergleichen, ja?
Vielen Dank für eure aktive Mitarbeit.
Jim
Jim Street schrieb:> Muss ich das x auch wieder auf den BUS senden? oder muss ich das durch> irgendeine Art herausfiltern?
Das x ist einfach nur eine Kennung, so dass dein Programm weiss, was es
mit dieser Adresse anfangen soll.
> Also schließlich scheint es mir so, als wenn ich dieses misteriöse x> nutzen muss um die beiden Nachrichten miteinander zu vergleichen, ja?
Du brauchst überhaupt keine Nachrichten vergleichen. Wenn hinter der
Adresse ein x steht, dann schickst du eine extended Nachricht, wenn
nicht dann eben nicht. Es ist einfach nur ein Steuerzeichen, dass dein
Programm nutzen kann um zu entscheiden, wie es vorzugehen hat.
Das ist nicht anders als bei ganz normalen Dateihandling. In jedem
dateiformat gibt es nicht nur Nutzdaten, die die eigentliche Datenfracht
darstellen, sondern immer auch Steuerdaten, die den Lese- und
Auswerteprozess leiten.
Hallo Jim,
Karl hat glaube ich schon alles wichtige gesagt.
Für mich ist noch nicht klar, wie dein Programm die CAN-Botschaften
schickt (welches CAN Interface, welche Software ist beteiligt).
Nur so kann man dir helfen, was du wie einstellen musst um CAN
Botschaften mit Standard oder Extended ID rauszuschicken.
Jim Street schrieb:> Weißt du wer das x dahinter setzt? Setzt das CANoe dahinter, damit ich> weiß, dass es sich um ein extended Frame handelt?
Wer denn sonst?
> Muss ich das x auch wieder auf den BUS senden? oder muss ich das durch> irgendeine Art herausfiltern?
Was verstehst du denn unter "das x auf den Bus senden"? Mal angenommen,
du wolltest das senden, wie würdest du das tun?
Hallo,
also das Problem ist, dass ich bei der von mir genutzten
CAN-Sendefunktion, vorher sagen muss, ob es sich um einen Standard-Frame
oder ein Extended-Frame handelt. Demnach werden die jeweiligen Parameter
geändert.
Und weil ich eine große Anzahl von CAN-Botschaften einlese, wo beide
Arten bei sind, muss ich vor dem Senden eine If-Entscheidung machen, ob
es sich bei der jeweiligen Nachricht um Extended oder Standard handelt.
Nur nach dieser Entscheidung kann ich jeweils die richtige
CAN-Sendefunktion auswählen.
Nachdem die richtige Sendefunktion ausgewählt wurde, werden die
originalen Botschaften auf einen originalen BUS gesendet.
Also wenn ich nur Extended Nachrichten oder nur Standard Nachrichten
einlese klappt auch alles einwandfrei. Dann kann ich ja vorneweg schon
sagen welche der beiden Sendefunktionen genutzt werden soll.
Nur in diesem Fall jetzt muss ich die beiden Fälle halt differenzieren.
Daher brauche ich eine Möglichkeit, die beiden Arten von Nachrichten,
welche sich nun ja anscheinend ausschließlich in der ID unterscheiden
von einander zu trennen.
Genau gesagt muss ich 2 Integer von einander unterscheiden. Zum Beispiel
"1BCC0C21x" und "121".
Habt ihr für mich (ich bin im programieren noch Anfänger) eine gute
Möglichkeit diese Werte von einander zu unterscheiden? Kann ich zum
Beispiel irgendwie sagen:
- Wenn am Ende ein x steht dann ist es ein Extended. oder
- Wenn es mehr als 3 Stellen im Integer sind ist es ein Extended.
??
Danke für die Hilfe
Jim Street schrieb:> Genau gesagt muss ich 2 Integer von einander unterscheiden. Zum Beispiel> "1BCC0C21x" und "121".>> Habt ihr für mich (ich bin im programieren noch Anfänger) eine gute> Möglichkeit diese Werte von einander zu unterscheiden? Kann ich zum> Beispiel irgendwie sagen:> - Wenn am Ende ein x steht dann ist es ein Extended. oder> - Wenn es mehr als 3 Stellen im Integer sind ist es ein Extended.> ??
Natürlich geht das. Wenn Du die Daten aus der Textdatei liest, hast Du
erstmal keine Integer, sondern Strings. Die kannst Du darauf prüfen, ob
sie ein x am Ende haben oder nicht. Zum Beispiel so:
Jim Street schrieb:> Nur in diesem Fall jetzt muss ich die beiden Fälle halt differenzieren.> Daher brauche ich eine Möglichkeit, die beiden Arten von Nachrichten,> welche sich nun ja anscheinend ausschließlich in der ID unterscheiden> von einander zu trennen.
Nein, sie unterscheiden sich in dem x.
> Genau gesagt muss ich 2 Integer von einander unterscheiden. Zum Beispiel> "1BCC0C21x" und "121".
Das x ist nicht Teil des Integers. Es ergibt als Integer überhaupt
keinen Sinn. Das ist, wie wenn irgendwo eine Telefonnummer angegeben
ist:
Tel:0123/456789
Dann tippst du das "Tel:" ja auch nicht als Teil der Nummer ins Telefon
ein. Es ist nur die Info, daß das, was danach steht, die Telefonnummer
ist.
> Habt ihr für mich (ich bin im programieren noch Anfänger) eine gute> Möglichkeit diese Werte von einander zu unterscheiden? Kann ich zum> Beispiel irgendwie sagen:> - Wenn am Ende ein x steht dann ist es ein Extended. oder
Genau so mußt du es machen. Wenn am Ende ein x steht, ist das Extended,
und das, was davor steht, ist die ID.
> - Wenn es mehr als 3 Stellen im Integer sind ist es ein Extended.
Das wäre nicht korrekt.
Hans schrieb:> Natürlich geht das. Wenn Du die Daten aus der Textdatei liest, hast Du> erstmal keine Integer, sondern Strings. Die kannst Du darauf prüfen, ob> sie ein x am Ende haben oder nicht. Zum Beispiel so:> char* idStr; // aus Datei gelesen> if (idStr[strlen(idStr) - 1] == 'x') {> // Extended Frame> } else {> // Normaler Frame> }
Und dann mit strtol einen integer draus machen:
1
longid=strtol(idStr,NULL,16);
Das x wird dabei ignoriert, da strtol beim ersten Zeichen, das nicht
konvertiert werden kann, aufhört.