Hallo. Ich habe bereits erfolgreich mit RS232, I2C und SPI gearbeitet.
Als nächstes würde ich mich gerne mit CAN beschäftigen. Als Hardware
habe ich an 2 PICs mit CAN Modul gedacht, die sich einfach nur Daten
schicken sollen. Programmieren würde ich diese entweder mit MikroC
(sofern die Demo reicht) oder ansonsten mit MPLABX und XC8.
CAN-Transceiver habe ich auch, sodass es eigentlich losgehen kann, aber
ich weiß nicht wie genau. Es scheint einiges komplizierter als SPI zu
sein, auch wegen der Kollisionenerkennung usw.
Also wie funktioniert es genau und was muss ich beachten?
Was ist CANopen und wozu brauche ich das? Ich stelle es mir so vor, dass
CANopen dafür sorgt, dass ein gewisser RAM/ROM Bereich bei allen
Teilnehmern gleich sind. Quasi wie globale Variablen.
Wenn ich mit der Materie einigermaßen sicher umgehen kann, würde ich es
in Richtung Haus-Automation verwenden wollen. Gibt es da speziell noch
etwas zu beachten? Hilft mir da CANopen weiter oder gibt es etwas
passenderes? Reicht es da nicht einfach Nachrichten zu verschicken und
die angesprochenen Partner reagieren dann? Ein Lichtschalter braucht ja
z.B. nicht die Temperaturen aller Räume zu wissen.
Ich würde mich zwar freuen, wenn jemand ein Teil oder sogar alle Fragen
beantwortet, meine eigentliche Frage ist aber, ob es eine gute
Hilfequelle gibt oder vielleicht sogar eine Art Tutorial (Video oder
Text). Irgendwas, womit ich mir die Antworten auf meine Fragen selber
erarbeiten kann. Also erstmal Grundlagen und Allgemeines über CAN und
dann idealer Weise noch CAN in Richtung Haus-Automation.
Vielen Dank
ich schrieb:> Was ist CANopen und wozu brauche ich das?
Also, CAN alleine kannst Du am ehesten mit einer nackten
Ethernet-Netzwerkkarte vergleichen: CAN kann nur Datenpakete verschicken
und Empfangen. Dabei ist keinerlei Protokoll definiert.
CANopen ist nun alles andere. Wieder verglichen mit Internet: CANopen
ist wie ARP, IP, DNS, TCP und HTTP, SMTP etc. mit Remote-Konfiguration.
D.h. CANopen geht von ganz unten, wie die einzelnen CAN-Nachrichten
aufgebaut sind, bis ganz oben, mit Device-Profiles die bestimmte Geräte
beschreiben, einschließlich den Zwischenschichten.
ich schrieb:> CANopen dafür sorgt, dass ein gewisser RAM/ROM Bereich bei allen> Teilnehmern gleich sind. Quasi wie globale Variablen.
Naja, so könnte man es in etwa sehen, sobald alle Knoten konfiguriert
wurden.
We CAN schrieb:> ich schrieb:>> Was ist CANopen und wozu brauche ich das?>> Also, CAN alleine kannst Du am ehesten mit einer nackten> Ethernet-Netzwerkkarte vergleichen: CAN kann nur Datenpakete verschicken> und Empfangen. Dabei ist keinerlei Protokoll definiert.
Ist ja i.d.R. bei SPI oder I2C auch der Fall. Reicht ja für banale
Sachen aus.
Kennt denn jemand eine Quelle oder Tutorial um sich CAN näher zu führen?
Finde da irgendwie nichts gescheites. Meist nur so ganz oberflächlich.
CAN ist so einfach, da braucht's kein Tutorial. Man lese sich auf
WIkipedia durch wie es funktioniert, lese sich die Dokumentation des CAN
Controllers durch, nehme einen Beispiel Code für diesen und passe ihn
an.
Warum du dir das Leben mit einem externen CAN Controller, für den man
sich noch mit SPI rumschlagen muss, schwer machst, ist Nicht ganz klar.
Nimm doch einfach einen Mikrocontroller mit integriertem CAN Controller,
dann hat der Hersteller auch Beispielcodes die du direkt einbauen
kannst.Bestimmt gibt's auch PIC's die das haben, ansonsten halt ARM oder
AVR.
Und CANopen ist sehr komplex, das "brauchst" du nur wenn du dein Produkt
mit "CANopen kompatibel" bewerben oder über CANopen Konfigurationstools
konfigurieren können willst. Zum Ansprechen fremder CANopen-Geräte musst
du CANopen nicht implementieren. Wenn du gar keine fremden
CANopen-Geräte einbauen willst (und daher auch kein CANopen
Konfigurationstool verwenden) ist CANopen vollkommen überflüssig.
Ich glaube, ich habe deinen Text falsch gelesen. Wenn du das so meintest
dass du eine PIC mit integriertem CAN-Controller nimmst, ignoriere
meinen Text dazu, sorry.
ich schrieb:> Es scheint einiges komplizierter als SPI zu> sein, auch wegen der Kollisionenerkennung usw.
Das Handling auf dem Bus regelt Dein CAN-Controller weitgehend für Dich.
Message-Box konfigurieren, mit Daten füllen, Senden auslösen.
Die Message-Box wird dann automatisch versuchen die Botschaft auf dem
Bus loszuwerden.
Hat man zum Beispiel nur einen Teilnehmer, die Botschaft geht also nicht
durch weil das Acknowledge fehlt, dann fängt die Message-Box wieder und
wieder an das zu senden und wird nie fertig.
Sendet gleichzeitg ein anderer Teilnehmer mit einer niedrigeren ID, also
höherer Prio dann wird die Übertragung automatisch gestopt und nochmal
versucht die Botschaft auf den Bus zu legen wenn dieser frei ist.
Gibt halt so ein paar Fehler die man abfangen kann, wie zum Beispiel das
eine Botschaft die reinkommt nicht die richtige Länge hat.
Genau, der PIC hat ein CAN-Modul, dessen Pins mit CAN_RX & CAN_TX
beschriftet sind. Diese kommen dann an den Transceiver, der daraus dann
CANH &CANL "macht".
SPI ist ja eigentlich nur ein Buffer füllen und dann mit dme Clock bit
für bit zu schreiben und gleichzeitig zu lesen. Recht Simpel.
I2C hat zusätzlich noch eine Zieladresse. Da wird dann nicht
hleichzeitig gelesen und geschrieben, da nur eine Datenleitung. Ein
Slave kann die als Ack auf 0 ziehen. Ok.
Aber wie geht das mit der Datenkollision bei CAN? Bei Wikipedia steht,
dass beim senden beprüft wird, ob wer anderes sendet. Wenn nun aber ein
Teilnehmer sendet und mit dem ersten Bit anfängt (laut Wiki ist das eine
0), woher weiß er dann, dass die 0, die am Bus ist, seine eigene ist und
nicht z.B. das Bit 5 des Identifiers eines anderen Teilnehmers, der
bereits sendet? Oder schalten alle Teilnehmer auf "Busy" sobald ein
Teilnehmer eine 0 liefert?
Oder auch: Wie geht das mit dem Ack? Die ID sagt ja, von wem die
Nachricht ist. Was ist nun, wenn darauf niemand reagiert? Oder was ist,
wenn darauf 2 Teilnehmer reagieren? Wodurch stellt man sicher, dass das
Ack von beiden kommt und nicht nur von einem?
Ich denke, ich werde mir das einfach mal aufbauen und testen. Ich will
bloß nicht, dass ich mir das irgendwie "falsch" beibringe. Je
komplizierter/komplexer etwas ist, desto mehr kann man falsch bzw.
unschön machen. Es soll z.B. nicht so kommen, dass ich das iwie zum
laufen kriege, doch wenn ich dann aber meinen Code zeige, jemand sagen
kann: "Wieso vergewaltigst du den Bus denn so, nimm doch xy oder mach es
so und so". Lieber gleich richtig lernen.
Genauso wie programmieren. Wenn sich das jemand selbst beibringt, kann
es dazu führen, dass andere, die das gelehrt bekommen haben, die Hände
über den Kopf zusammenschlagen und Augenkrebs bekommen.
Das ist ja der Trick beim CAN - es wird nicht nur stumpf gesendet,
sondern simulatan auch empfangen, was gerade auf dem Bus passiert. Und
so kann ein Sender feststellen, dass er von einem anderen Sender "platt
gemacht" wurde (höhere Priorität), also dass, was er versucht zu senden
klapt oder eben auch nicht.
Das unschöne an der Sache - es wird mit dominantem und rezessivem Pegel
gearbeitet. Ermöglicht erst obige Vorgehensweise, begrenzt dadurch aber
Datenrate und Bandbreite.
Von wem und von wievielen das ACK kommt, hat nichts zu bedeuten -
Hauptsache, eines kommt (in der Realität sendet jeder Knoten ein ACK).
Das heisst aber nur, dass die Botschaft formal richtig war. Nicht mehr,
nicht weniger. Ob sich überhaupt jemand dafür interessiert oder ob der
Empfänger, den es interessieren sollte, diese auch korrekt empfangen
hat, erfährt der Sender damit nicht. Heisst nur: Paket war korrekt, Bus
ist in Ordnung, es gibt mindestens einen anderen Teilnehmer.
Gibt aber wirklich genug Literatur zu den grundlegenden CAN-Themen.
ich schrieb:> woher weiß er dann, dass die 0, die am Bus ist, seine eigene ist und> nicht z.B. das Bit 5 des Identifiers eines anderen Teilnehmers, der> bereits sendet?
Jeder CAN-Knoten hört ständig mit, und weiß deshalb, was gerade auf dem
Bus los ist, also welches Bit da gerade gesendet wird. Daher weiß ein
Knoten auch, wann er überhaupt probieren darf, sein eigenes Paket zu
senden. Und wenn ein CAN-Knoten sendet, liest er Bit für Bit ständig vom
Bus zurück, und überprüft, ob jedes Bit korrekt auf dem Bus steht.
Sobald ein andere CAN-Knoten das eigene, "schwache" Bit überstimmt hat,
beendet der CAN-Knoten mit dem schwachen Bit die Sendung, und versucht
es später wieder.
We CAN schrieb:> Daher weiß ein> Knoten auch, wann er überhaupt probieren darf, sein eigenes Paket zu senden.
Das habe ich mir gedacht. Auf der anderen Seite heißt es aber auch, dass
bei einer Kollision der Teilnehmer mit der höheren Priorität (kleineren
ID) Vorrang bekommt. Gilt das nur bei exakt gleichem Start?
Denn sonst: Wenn jemand mit der ID 3 sendet und ein Teilnehmer mit ID 2
zwischenfunkt, müsste doch der 2. Teilnehmer senden dürfen, da bei einer
Kollision die Priorität entscheidet. Der 1. Teilnehmer wird aber nie
erfahren, welche ID der andere hat, da die Kollision ja schon am Anfang
auftritt und die Übertragung abgebrochen wird. Die vom 1. Tn. gesendete
Nachricht könnte durch die Kollision aber verfälscht sein, weshalb er ja
auch nochmal senden müsste. Wenn die Kollision auftritt, bevor der 1.
Tn. die erste 1 seiner ID gesendet hat, weiß also kein Teilnehmer, wer
denn die höhere Priorität hat und somit, wer nun senden darf.
Wenn es nicht so ist und alle Teilnehmer nicht senden, sobald einer den
Bus belegt, ist das bei schnellen Reaktionen (z.B. Airbag) doch
kontraproduktiv, oder?
Ist nicht kontraproduktiv, da man die worst case Zeit, die ein Knoten
zum senden brauch offline berechnen kann.
Man weiß ja, dass im ungünstigsten Fall man ein Bit nach dem der Störer
den Bus belegt den Airbag auslösen will, dann kennt man die maximale
Länge der Nachricht, die der Störer sendet und daher weiß man vorher
schon, ob der Airbag rechtzeitig auslöst.
ich schrieb:> We CAN schrieb:>> Daher weiß ein>> Knoten auch, wann er überhaupt probieren darf, sein eigenes Paket zu senden.>> Das habe ich mir gedacht. Auf der anderen Seite heißt es aber auch, dass> bei einer Kollision der Teilnehmer mit der höheren Priorität (kleineren> ID) Vorrang bekommt. Gilt das nur bei exakt gleichem Start?
Ja. Es gibt aber auch keinen anderen Fall, da ein Teilnehmer nur
beginnen darf, wenn kein anderer Teilnehmer gerade am Senden ist.
> Denn sonst: Wenn jemand mit der ID 3 sendet und ein Teilnehmer mit ID 2> zwischenfunkt, müsste doch der 2. Teilnehmer senden dürfen, da bei einer> Kollision die Priorität entscheidet. Der 1. Teilnehmer wird aber nie> erfahren, welche ID der andere hat, da die Kollision ja schon am Anfang> auftritt und die Übertragung abgebrochen wird. Die vom 1. Tn. gesendete> Nachricht könnte durch die Kollision aber verfälscht sein, weshalb er ja> auch nochmal senden müsste. Wenn die Kollision auftritt, bevor der 1.> Tn. die erste 1 seiner ID gesendet hat, weiß also kein Teilnehmer, wer> denn die höhere Priorität hat und somit, wer nun senden darf.
Es gibt keine Kollision im Ethernetsinne. Die Erklärung beschreibt nur,
was hinten rauskommt. Der Gewinn der niedrigen ID ergibt sich dadurch,
dass die höhere ID verfälscht wird. Und diese hört auf. Die Nachricht
des Gewinners wird nicht verfälscht.
> Wenn es nicht so ist und alle Teilnehmer nicht senden, sobald einer den> Bus belegt, ist das bei schnellen Reaktionen (z.B. Airbag) doch> kontraproduktiv, oder?
Es gibt im Auto nicht nur einen großen CAN Bus mit allen Teilnehmern
gemeinsam. Sondern viele verschiedene.
Du hast insofern aber recht, dass man die Übertragunszeiten der anderen
Teilnehmer bei seinen Überlegungen berücksichtigen muss, wenn man in den
zeitkritischen Bereich kommt.