Hallo,
hätte da eine Frage zum MCP2515 und dem Acknowledged.
1.) Nehmen wir an, ich habe 5 Nodes (A-E). Node A sendet eine Nachricht,
Node B Acknowledged diese. Kann nun passieren, dass Node E diese
Nachricht nicht erhält, da eine Kollosion nach Node B auftritt? Oder
kann ich davon ausgehen, wenn eine Nachricht Acknowledged wird, dann
diese auch alle Teilnehmer erhalten haben (soinfern die Leitung nicht
unterbrochen wurde und die Hardware korrekt arbeitet)
2.) Wenn eine Kollision auftritt, verschickt der MCP2515 die Nachricht
nochmals, oder muss ich diesen Fehler abfangen und die Software die
Nachricht nochmals verschicken?
3.) Es gibt den "Error Active", "Error Passive" und "Bus off" Status
beim Error Handling. Wenn einmal "Bus off" erreicht ist, ist der
Teilnehmer dann für immer offline, bis dieser neu gestartet wird? Ich
verwende Arduino & diese Libary:
https://github.com/coryjfowler/MCP_CAN_lib/blob/master/mcp_can.h
Dort finde ich keine Infos, welche das "Bus off" betrifft, wie ich
dieses steuern könnte.
Ein MCP2515 Controller, welcher keinen Hardware- Defekt hat, wird
niemals den "Bus off" Status erreichen, oder?
danke!
Hi,
zu 1:
Beim CAN hört jeder Teilnehmer auf den Bus und prüft ob das was er
sendet auch auf dem Bus ist. Sollte ein rezessives Bit durch ein
dominantes über schrieben werden bricht der Sender mit dem rezessivem
Bit ab und startet wenn der Bus frei ist erneut.
Ich meine im one Shot Mode wird nicht erneut gesendet.
Gruß JackFrost
Bastian W. schrieb:> Beim CAN hört jeder Teilnehmer auf den Bus und prüft ob das was er> sendet auch auf dem Bus ist. Sollte ein rezessives Bit durch ein> dominantes über schrieben werden bricht der Sender mit dem rezessivem> Bit ab und startet wenn der Bus frei ist erneut.
Heißt also praktisch, ich kann davon ausgehen, wenn die Hardware korrekt
funktioniert und die Verkabelung korrekt ist, dass die CAN- Pakete auch
am Ziel ankommen.
In der oben genannten Libary gibt mir die sendMsg() Funktion ein OK oder
ERROR zurück. Bedeuetet, ein ERROR bekomme ich nur, wenn es ein
gravierendes Problem gibt?
Oder muss ich den ERROR abfangen und die Nachricht nochmals schicken?
Es gibt beim CAN erstmal kein Ziel, es gibt nur Datenschleudern. Und der
Sender erfährt nicht, ob irgendjemand, der diese Botschaft auswerten
will/soll, diese auch bekommen hat. Der jeweilge Sender ist zufrieden,
wenn er seine eigene Botschaft fehlerfrei zurücklesen konnte und von
min. einem anderen Knoten ein ack bekommen hat
Das kann man alles noch draufsetzen, ohne weitere Protokollebenen ist es
aber so.
Entsteht ein Fehler, versucht der jeweilige Controller, seine Botschaft
selbständig erneut loszuwerden, da brauchst du dich nicht drum kümmern.
Häufen sich die Fehler, hört er irgendwann auf - spätestens dann
solltest du dich drum kümmern :-)
Probleme gibts eigentlich nur, wenn die Buslast extrem wird (dann kann
es passieren, dass niedrig priorisierte Botschaften kein Zeitfenster
finden) oder eben die Verkabelung/Abschluss nicht korrekt sind. Das
Zeitfenster ist bei hohen Datenraten und langen Kabeln knapp. Bewegst du
dich im Rahmen der Normen, sind Fehler extrem selten.
So weit so kurz :-)
Danke für die Infos!
H.Joachim S. schrieb:> er jeweilge Sender ist zufrieden,> wenn er seine eigene Botschaft fehlerfrei zurücklesen konnte
Hab mich schon einiges, was CAN betrifft eingelesen, nur eines verstehe
ich jetzt nicht. Wie kann der Controller seine eigene Nachricht
zurücklesen? Die Daten werden über beide Leitungen gesendet, wobei auf
einer Leitung HIGH/LOW vertauscht wird (ist das so richtig).
Wie oder woher bekommt er nun seine eigene Nachricht zurück?
Thomas schrieb:> Wie oder woher bekommt er nun seine eigene Nachricht zurück?
Da musst das Zusammenspiel Controller/Transceiver sehen.
Der Receiver ist immer an und liefert den aktuellen Busverkehr. Und so
kommen die Daten vom Controllerausgang -> Transmitter -> Bus -> Receiver
-> Controllereingang auch wieder an, wird dort mit dem gesendeten
verglichen (macht er selbständig) und weiss danach, ob die Daten korrekt
auf dem Bus gelandet sind oder jemand anders dazwischengefunkt hat (das
kann normalerweise nur in der Arbitrierungsphase passieren), aber auch
alle anderen Bits werden verglichen.
Danke, wieder dazu gelernt :)...
Eine Frage noch, im Wikipedia Artikel liest man:
====
Verwenden beide Teilnehmer den gleichen Identifier, wird nicht sofort
ein Error-Frame erzeugt (siehe Frame-Aufbau), sondern erst bei einer
Kollision innerhalb der restlichen Bits, was durch die Arbitrierung
ausgeschlossen sein sollte. Daher empfiehlt der Standard, dass ein
Identifier auch nur von maximal einem Teilnehmer verwendet werden soll.
====
https://github.com/coryjfowler/MCP_CAN_lib
Wenn ich diese Libary hernehme, ist der Identifier bei der sendMsg
Funktion der erste Parameter oder (also der Teil, welcher den Inhalt der
Nachricht beschreibt)?
INT8U sendMsgBuf(INT32U id, INT8U ext, INT8U len, INT8U *buf);
Wenn ich nun 2 Geräte mit der gleichen Funktion in meinen CAN Bus habe,
welche Temperatur und Luftfeuchtigkeit alle 2 Sekunden in das Netzwerk
schicken, so muss je ein anderer Identifier verwenden?
Identifier 0x01: Gerät 1 Temperatur
Identifier 0x02: Gerät 2 Temperatur
Identifier 0x03: Gerät 3 Luftfeuchte
Identifier 0x04: Gerät 4 Luftfeuchte
Richtig so oder?
Ursprünglich wollte ich für beide Geräte für die Temperatur Identifier 1
verwenden, und für die Feuchtigkeit 2, und im Data- Feld dann eine ID
des Geräts speichern, aber das ist ja damit hinfällig.
Thomas schrieb:> 1.) Nehmen wir an, ich habe 5 Nodes (A-E). Node A sendet eine Nachricht,> Node B Acknowledged diese.
Jeder aktive Busteilnehmer ACKed einen korrekt empfangenen Frame.
Unabhängig davon, ob er sich für den Inhalt interessiert.
> kann ich davon ausgehen, wenn eine Nachricht Acknowledged wird, dann> diese auch alle Teilnehmer erhalten haben
Du kannst davon ausgehen, dass mindestens ein Teilnehmer den Frame
korrekt empfangen hat.
ja jeder Teilnehmer sollte unterschiedliche IDs verwenden. Anstatt das
alle Temperatur senden, senden sie eben Temperatur 1, Temperatur 2,....
wichtig ist das später bei der Priorisierung durch Wahl eines niedrigen
Identifiers.
Wie gesagt das ACK geben alle zurück die es empfangen haben, du kannst
es aber nicht auswerten wer es bekommen hat.
Wenn du das machen willst musst die die Teilnehmer nochmal extra
Antworten lassen, was durch Remote Frame auch automatisierbar ist.
Ich gehe allerdings nicht den Umweg über SPI und MCP2515 sondern nehme
gleich einen µC der den CAN-Controller integriert hat(ATMega16-M1) in
der Arduino Welt ist aber der MCP2515 immer dazwischen.
Thomas schrieb:> Identifier 0x01: Gerät 1 Temperatur> Identifier 0x02: Gerät 2 Temperatur> Identifier 0x03: Gerät 3 Luftfeuchte> Identifier 0x04: Gerät 4 Luftfeuchte> Ursprünglich wollte ich für beide Geräte für die Temperatur Identifier 1> verwenden, und für die Feuchtigkeit 2, und im Data- Feld dann eine ID> des Geräts speichern, aber das ist ja damit hinfällig.
Jep, genau das ist verkehrt. Keine doppelten IDs in unterschiedlichen
Busteilnehmern.
So könnte das besser aussehen:
Gerät 1:
ID 0x001 Temperatur 1 und Feuchte 1 (gibt ja 8 Datenbytes)
ID 0x002 Temperatur 2 und Feuchte 2
ID 0x003 Temperatur 3 und Feuchte 3
Gerät 2:
ID 0x010 Temperatur 4 und Feuchte 4
ID 0x011 Temperatur 5 und Feuchte 5
usw...
H.Joachim S. schrieb:> Entsteht ein Fehler, versucht der jeweilige Controller, seine Botschaft> selbständig erneut loszuwerden, da brauchst du dich nicht drum kümmern.
Da würde ich mich nicht immer zwingend drauf verlassen, kann iA
eingestellt werden.
Danke, ihr seit Spitze :-) ...
Eine Fragen noch zur Geschwindigkeit.
Bei einer maximalen Leitungslänge von 125m (in der Relität werden es
maximal 40m sein) sollte ich eine Geschwindigkeit von 500kbits/s
erreichen, das sind 500.000 bits -> 62500 bytes in der Sekunde.
Ein CAN Paket ist maximal 52 Bytes groß.
Würde ich nun rein theoretisch 200 CAN Pakete (=10400 Bytes) in der
Sekunde versenden, sollte das überhaupt kein Problem sein oder?
Thomas schrieb:> Ein CAN Paket ist maximal 52 Bytes groß.
Ein Classic CAN Frame hat 16 Arbitration Bits + 16 CRC Bits und max 8
Byte.
Das sind bei mir 14 Bytes in Summe. Oder meinst du CAN-FD ?
Erik schrieb:> Ein Classic CAN Frame hat 16 Arbitration Bits + 16 CRC Bits und max 8> Byte.> Das sind bei mir 14 Bytes in Summe. Oder meinst du CAN-FD ?
Oh, hab mich verlessen. Sehe gerade, CRC etc. sind ja bits und nicht
Bytes. Somit sind es 14 bytes.
Der Identifier ist 11 Bit groß, somit ist der maximale Wert 2048,
welchen ich als Identifier verwenden kann?
Thomas schrieb:> Der Identifier ist 11 Bit groß, somit ist der maximale Wert 2048,> welchen ich als Identifier verwenden kann?
2047...
... wenn du in dem CAN Netz tun kannst was du willst. :)
Als alternative extended ID.
CAN sollte grundsätzlich unabhänig von der Platform sein. Wenn der Bus
zusammenbricht kann es an verschiedenen Dingen liegen.
Timing-Error:
Die beiden Teilnehmer senden nicht mit der gleichen Baudrate. (Entweder
völlig daneben, wie z.B. 500kBit vs. 125kbit, oder nur ein wenig wie
z.B 990kbit und 1 Mbit). Letzteres kann durch eine ungenaue clock-source
oder falsche Sampling-point Einstellungen passieren.
Das führt in der Regel dazu, dass ein Sender endlos versucht seine
Botschaft zu senden, aber kein ack bekommt. Die anderen Reden dann nicht
mehr, weil der Bus ständig belegt ist. Wenn man das mit einem
Bus-Monitor anschaut, zeigt der dann meistens "BUS-HEAVY" an.
Ansonsten kommt es zu fehlern wenn ein Teilnehmer CAN FD nach ISO
verwendet und andere Teilnehmer CAN FD nach Bosch Spezifikation.
Außerdem kann noch die Terminierung falsch sein (Überterminiert bei 3
Abschlusswiderständen)