Forum: Mikrocontroller und Digitale Elektronik Can Bus MCP2515 Ack


von Thomas (Gast)


Lesenswert?

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!

von Bastian W. (jackfrost)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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?

von H.Joachim S. (crazyhorse)


Lesenswert?

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 :-)

von Thomas (Gast)


Lesenswert?

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?

von Thomas (kosmos)


Lesenswert?

er überprüft "live" die angelegten Pegel ob diese auch so bleiben wie es 
vorgesehen ist.

von H.Joachim S. (crazyhorse)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Thomas (kosmos)


Lesenswert?

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.

von Thomas F. (igel)


Lesenswert?

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...

von Erik (Gast)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

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?

von Erik (Gast)


Lesenswert?

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 ?

von Erik (Gast)


Lesenswert?

Korrigiere 19 Header Bits + 12 Trailer Bits + 16 CRC Bits + 8 Data 
Bytes, also rund 14 Byte + Stuffing.

von Thomas (Gast)


Lesenswert?

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?

von Thomas (Gast)


Lesenswert?

Thomas schrieb:
> Der Identifier ist 11 Bit groß, somit ist der maximale Wert 2048,
> welchen ich als Identifier verwenden kann?

Ich frage deshalb, weil die arduino-libary lässt ein uint32 als 
identifier zu.

https://github.com/coryjfowler/MCP_CAN_lib/blob/master/mcp_can.h

von Erik (Gast)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

Erik schrieb:
> Als alternative extended ID.

Danke!

Ihr habt mir total weitergeholfen, danke!

lG

von Thomas (Gast)


Lesenswert?

Habe jetzt doch noch eine Frage / Problem.

Habe hier ein PiCan 2 Board, welches mit einem Raspberry betrieben wird:
https://www.amazon.de/NEU-PiCan2-CAN-Bus-Board-Raspberry/dp/B01HBWI8BW/ref=sr_1_1?ie=UTF8&qid=1518729646&sr=8-1&keywords=pican+2

Für Arduino habe ich folgendes:
http://www.dx.com/de/p/mcp2515-can-bus-module-tja1050-receiver-spi-module-blue-434988?tc=EUR&ta=AT&gclid=EAIaIQobChMI8cCY8Oyo2QIV4bXtCh2ltQ5vEAYYASABEgJ0ufD_BwE#.WoX5yeciFPY

Wenn ich nur Arduinos verwende, funktionert auch alles wunderbar. Sobald 
ich meinen Raspberry im CAN- Bus hinzufüge, kann ich keine Nachrichten 
mehr verschicken.

Sollten diese miteinander kompatibel sein?

lG

von Thomas (Gast)


Lesenswert?

Geschwindigkeit 125k & 500k auf je beide Seiten habe ich schon getestet, 
das gleiche Problem

von Bastian W. (jackfrost)


Lesenswert?

Hi,

Miss mal die Pegel CAN High und CAN Low passen ?

Normal sollte es gehen , kannst welche Fehler liest du aus dem MCP2515 
aus ?

Gruß JackFrost

von Fabian F. (fabian_f55)


Lesenswert?

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)

von Thomas (Gast)


Lesenswert?

Ok, ganz blöder Fehler.
Der NiRen am Arduino wird mit 8Mhz betrieben, hatte 16Mhz angegeben.

Nun läufts perfekt :)

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.