signed int (16 bit) über CAN verschicken

Gast #6737598
Lesenswert?

Guten morgen,

ich soll für ein Projekt Debug-Nachrichten über CAN verschicken.
Das funktioniert auch schon (Die Funktion zum senden ist ja schon 
vorgegeben).
Diese werwartet die Adresse (an wem ich verschicke, uint8 array (mit den 
Daten) und die Anzahl der Daten.


Aber wie kann ich Jetzt habe ich hier aber werte, welche sint16 sind. 
Wie kann man diese denn am besten verschicken? Für die Anderen 
Nachrichten habe ich ein Array welches uint16 Werte erwartet (das sind 
nämlich die meisten werte), welches ich dann beim Funktionsaufruf auf 
uint8* caste.
#6737605
Lesenswert?

Sebastian schrieb:
> Diese werwartet die Adresse ... und die Anzahl der Daten.

> Aber wie kann ich Jetzt habe ich hier aber werte, welche sint16 sind.

Wie soll man das verstehen?

> Wie kann man diese denn am besten verschicken?

Indem man die Bits auf mehrere Datenbytes verteilt:

https://images3.programmersought.com/555/31/311da57148fbf07dcf259f58cfdb17fb.JPEG

Sender und Empfänger müssen sich nur über die Reihenfolge einig sein: 
Lo-Byte oder High-Byte zuerst. In fertiger CAN-Software wird das Intel- 
und Motorola-Byte-Order genannt.
Gast #6737609
Lesenswert?

Du schreibst deinen sint16 Wert in das Array. Wenn ich deinen Text 
richtig
interpretiere, müsste das Schreiben ausserhalb der Sendefunktion 
erfolgen.

Du müsstest allerdings folgendes wissen:
An welche Stelle im uint8 Array soll der Wert geschrieben werden?
In welcher Byteoder (LSB oder MSB) wird auf dem Bus gesendet?

Mal ein Beispiel:

uint8 txData[8] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
sint16 dbgValue;

txData[0] = uint8((dbgValue&0xFF00)>>8);
txData[1] = uint8(dbgValue&0x00FF);

SendeCAN(txData, 8);

Dieses Beispiel geht von Byteorder MSB aus und legt den dbg-Wert auf 
Byte 0 und 1 im CAN Frame.
Gast #6737682
Lesenswert?

Martin schrieb:
> dann nimm halt ein sint16 Array und caste es auf uint8*

Das habe ich jetzt auch mal getestet und den zu sendenden wert 
festgelegt
1
tmp_16 = -200;
2
debug_au16[0] = tmp_16;
3
debug_au16[1] = 200;
4
debug_au16[2] = 0xFF;
5
debug_au16[3] = 0xFF;
6
canSend(0x111, (uint8*)debug_au16[0], 8);

jetzt sehe ich im CAN-Trace, dass byte[0]=0x38, byte[1]=0xFF, 
byte[2]=C8, byte[3]=0x00, byte[4]-byte[7]=0xFF

wie kann ich denn von diesem Wert (0x38 und 0xFF) auf die -200 
schließen?
#6737684
Lesenswert?

Der Empfänger muß feststellen können, welches Byte im Paket welche 
Bedutung hat, d.h. Du brauchst ein Protokoll, was man parsen kann.
Man kann sich ein Protokoll selber ausdenken oder irgendein 
Standardprotokoll nehmen.

Gerne werden Strings genommen, da man die in einem Terminal direkt lesen 
kann. Da Stringnachrichten oft >8 Byte sind, braucht einen Pakettyp, der 
aus mehreren CAN-Nachrichten besteht.
#6737695
Lesenswert?

Peter D. schrieb:
> Gerne werden Strings genommen, da man die in einem Terminal direkt lesen
> kann. Da Stringnachrichten oft >8 Byte sind, braucht einen Pakettyp, der
> aus mehreren CAN-Nachrichten besteht.

Über ein Transportprotokoll?

Ich würde den einfacheren Weg gehen, die sint16 im CANdb-Tool in der 
gewollten CAN-Message zu definieren, damit das dann im CAN-Trace oder im 
CAN-Graphen korrekt skaliert angezeigt wird. Dann in der ECU bzw. PLC 
entsprechend dieser Definition befüllen. Den Rest erledigt 
INCA/CANoe/CANape/... dann von selbst.

Wenn der TO einen XCP-Server auf dem Steuergerät/Industriegerät zum 
laufen bringt, geht es mit einem XCP-client wie z.B. eben INCA oder 
CANape noch einfacher. Über ein generiertes A2L bzw. aus ELF generiertem 
A2L kann dann Wahlfrei jede Variable angesehen und ggf. Manipuliert 
werden. Wie ein Debugger eben :)

mfg mf
Gast #6737708
Lesenswert?

Sebastian schrieb:
> wie kann ich denn von diesem Wert (0x38 und 0xFF) auf die -200
> schließen?

Du könntest dich mal ein bissl bemühen, und dir aneignen wie Zahlen in 
der Digitalen Welt gespeichert werden. Stichwort Binärzahlen. Dazu gibt 
es viel in der Literatur und im Internet zu lesen.

http://www.scalingbits.com/book/export/html/46

0xff38 hex = -200 dec

0x0000 - 1 = 0xffff
0x0000 - 2 = 0xfffe
#6737792
Lesenswert?

Niklas G. schrieb:
> Zahlen als Strings über CAN verschicken ist nicht sehr zweckmäßig.

Es sind ja nicht nur reine Zahlen.
Meine Nachrichten sind so aufgebaut:
"Befehl Parametername Wert1 [Wert2] [...]\n"
Ich brauche also nur einen allgemeinen Sniffer, der CAN-Pakete zu einer 
Stringnachricht aneinander reiht und anzeigt.
Das Aneinanderreihen geht ganz einfach. Das erste Byte kennzeichnet den 
Stringtyp bzw. ist die fortlaufende Nummer der zu einer Nachricht 
gehörenden CAN-Pakete (max 16).

Ich kann dann Befehle beliebig hinzufügen oder ändern, ohne das ich 
jedesmal einen neuen Interpreter brauche.
Wir hatten früher auch binär benutzt, aber das war fürs Debuggen ein 
Graus. Alles nur kryptische Hex-Bytes.
Persönliche Seite #6737802
Lesenswert?

Peter D. schrieb:
> Wir hatten früher auch binär benutzt, aber das war fürs Debuggen ein
> Graus. Alles nur kryptische Hex-Bytes.

Schon mal CANoe mit DBC-Daten benutzt? Das dekodiert alles automatisch 
und stellt es lesbar dar. Wenn man eine Nachricht ändert klickt man das 
in CANdb++ fix zusammen, da muss man keinen neuen Interpreter bauen. Im 
Idealfall generiert man sowieso den Code aus den DBC-Dateien, sodass man 
die Definition der Nachricht nur 1x machen muss.

CAN ist sowieso schon langsam, das dann noch mit String-Kodierung noch 
weiter auszubremsen... Dann auch noch die Fehlerbehandlung, wenn 
einzelne Nachrichten in der Folge fehlen...

Und wenn für CANoe das nötige Kleingeld fehlt: Einfach den selben Code 
für den Controller wie für die Analyse auf dem PC nutzen, z.B. eben in 
der Form der Deklarationen der µSer-Library. Dann schreibt man es 1x im 
Code hin und verwendet ihn für beide Seiten.

Peter D. schrieb:
> "Befehl Parametername Wert1 [Wert2] [...]\n"

Das riecht nach dem "Inner Platform Antipattern". CAN hat bereits eine 
Nachrichtenkennung ("Befehl"), die ID. Noch eine weitere ID zu 
übertragen, die von der Hardware dann auch nicht gefiltert werden kann, 
ist redundant. Parameter-Namen ständig erneut zu übertragen frisst 
unnötig Bandbreite. CAN ist sowieso nicht Plug-And-Play, man muss 
sowieso alle Teilnehmer explizit anpassen oder konfigurieren.
#6737836
Lesenswert?

Niklas G. schrieb:
> Wenn man eine Nachricht ändert klickt man das
> in CANdb++ fix zusammen, da muss man keinen neuen Interpreter bauen.

Das geht bei uns nicht. Der CAN-Bus geht nicht direkt auf den PC, 
sondern die Nachrichten werden per Ethernet an den PC übertragen. Daher 
ist das Stringformat sehr bequem.

Niklas G. schrieb:
> CAN ist sowieso schon langsam, das dann noch mit String-Kodierung noch
> weiter auszubremsen...

Das muß man schon dem Anwender überlassen, ob da was bremst. Wir haben 
natürlich vorher untersucht, ob das Stringformat für unsere Anwendungen 
schnell genug ist und das ist es.
Persönliche Seite #6737842
Lesenswert?

Peter D. schrieb:
> Das geht bei uns nicht.

Warum? Dann baut halt einen Interpreter welcher mittels DBC-Dateien das 
Binärformat interpretiert, was zuvor per Ethernet verschickt wurde.

Peter D. schrieb:
> Wir haben
> natürlich vorher untersucht, ob das Stringformat für unsere Anwendungen
> schnell genug ist und das ist es.

Okay, aber das ist dann eine Lösung die nur in diesem Spezialfall 
funktioniert. Viele Fahrzeuge und Anlagen haben sogar mehrere 
CAN-Netzwerke, u.a. weil ein einzelnes nicht genug Bandbreite hat. 
CAN-FD wurde auch deshalb erfunden. Für diese Anwendungen sollte man 
also lieber eine Binärkodierung verwenden. Natürlich auch, weil 
praktisch alle CAN-basierten Systeme auf dem Markt das eben so machen.
Gast #6737849
Lesenswert?

Peter D. schrieb:
> Gerne werden Strings genommen, da man die in einem Terminal direkt lesen
> kann.

Dafür ist CAN aber nicht gedacht. Es kann ja auch passieren das ein 
anderer Client eine Nachricht dazwischen funkt und schon ist dein String 
futsch. In deinem speziellen Fall mag das evtl. nicht möglich sein aber 
das zu verallgemeinern ... hm? Ausserdem geht das ganz schön auf die 
Datenübertragungsrate, also bei Zeitkritischen Anwendungen auch eher 
nicht geeignet.

Die Jungend von heute ... tztztz. Früher konnten Programmierer noch 
programmieren und konnten noch mit Hex und Bin umgehen. ;-)
#6737861
Lesenswert?

Martin schrieb:
> Die Jungend von heute ...

Nö, im Alter (ü60) will man es schön bequem haben.

Ich schreibe auch keine Windows-Anwendungen. Ein Kollege hat mal das 
UDP-Terminal geschrieben und ich benutze es nur, um die CAN-Module 
anzusprechen. Ich kann damit an der eigentlichen Steuerung vorbei mit 
den Modulen sprechen, d.h. auch im Betrieb. Das funktioniert sogar im 
Homeoffice.
Gast #6738436
Lesenswert?

>Sender und Empfänger müssen sich nur über die Reihenfolge einig sein:
>Lo-Byte oder High-Byte zuerst. In fertiger CAN-Software wird das Intel-
>und Motorola-Byte-Order genannt.

Auch das wird im DBC File festgelegt, genauso wie die ID Nachrichten, 
sowie die Zykluszeiten.

Ich bin der Meinung für dein anliegen empfiehlt es sich das TP-Protokoll 
aufzusetzen, falls du mit dem Payload von 8 Byte nicht auskommst.

https://de.wikipedia.org/wiki/ISO_15765-2
#6738994
Lesenswert?

Wolfgang schrieb:
> Udo schrieb:
>> Du müsstest allerdings folgendes wissen:
>> ...
>> In welcher Byteoder (LSB oder MSB) wird auf dem Bus gesendet?
>
> Was spielt das für eine Rolle?
> Hauptsache Sender und Empfänger machen es gleich ;-)

Naja, wenn man die beiden entwickelt, sollte man das schon wissen. Wie 
soll man sonst sicherstellen, dass sie es gleich machen?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren