Hallo zusammen, Ich bin gerade an meiner Masterarbeit und versuche eine sinnvolle Datenstruktur für CAN Kommunikation aufzubauen: Dazu verwende ich das STM32E-EVAL evaluation board von ST und möchte über die CAN Schnittstelle mit einem Maxon EPOS2 Motor Controller per CAN kommunizieren. Grundsätzlich bin ich in der Lage, CAN commands an EPOS2 zu senden, um z.B. den Controller zu initialisieren (z.B. im Current-control mode), setpoints zu ändern, den Motor zu starten/stoppen, etc. Dies geschieht über spezielle CAN commands: Über die ID wird bestimmt, welcher CAN Node angesprochen wird (ich möchte schlussendlich 6 motor controller gleichzeitig per can regeln) und die 8 bytes data, welche geschickt werden enthalten eine bestimmte Kodierung (Anweisung). Nun möchte ich die Drehzahl des Motors per CAN von EPOS übertragen bekommen. Dazu sende ich eine Anfrage raus (z.B mit ID 1536+1 für Node 1) und unmittelbar danach erhalte ich die gewünschte Drehzahl unter der ID 1408+1 für Node 1). Das Problem ist nun, wie ich am saubersten diese Kommunikation implementieren kann, denn der ganze Ablauf, bis zum erhalten der Drehzahl spielt sich ja mindestens in zwei files ab: bei mir z.B. in EPOS.c wo ich den "CAN_Transmit" Befehl ausführe und in "stm32f10x_it.h" (in der Funktion "CAN_Transmit"), wo schlussendlich ein Interrupt generiert wird bei Erhalt einer neuen Nachricht. Nun kann es ja sein, dass zwischen Absenden der Anfrage und Eintreffen der Antwort des angefragten Nodes noch andere Messages rein kommen, die im "schlimmsten" Fall zu einer früheren, gleichartigen Anfrage gehören. Die Frage die ich mir nun gestellt habe ich wie ich am besten vorgehe, damit die Antwort bestimmt am richtigen Ort landet, rsp. bin ich auf der Suche nach einem Interface, mit welchem ich mir diese Kommunikation erleichtern könnte. So könnte ich mir z.B. vorstellen, dass ich für jeden der 6 Motoren ein Struct habe mit Node-ID und aktueller Geschwindigkeit und dieses Struct dann irgendwie up-to-date halte. Ich weiss aber nicht, wo ich am besten diese Variable initizlisiere (z.B in "main.c" und dann den pointer dazu global verfügbar abspeichern,???) und vor allem so, dass ich später auch andere messages dazu fügen kann, wie anders verarbeitet/interpretiert werden und dass ich einfach einen Motor hinzufügen/entfernen kann, ohne dass ich in 3 files eine Änderung machen muss. Ich wäre euch sehr dankbar für einen Tipp, denn ich bin auf dem Gebiet als Maschinenbauer überhaupt nicht heimisch:-S Gruss Michael
Man kann ja auch von structs Arrays bilden. Dann definiert man eine Konstante, die einmal für das ganze Projet angibt, wie viele Motoren es gibt. z.B. so: #define NUMBER_OF_MOTORS 6 struct T_Motor motors[NUMBER_OF_MOTORS]; Für die Kommunikation würde ich immer davon ausgehen, dass der zuletzt empfangene Drehzahlwert der aktuellste ist. Dann einfach jede Nachricht auf die ID prüfen und je nach ID den entsprechenden Wert in der zugehörigen Speicherstruktur updaten. Grüße, Peter
> Das Problem ist nun, wie ich am saubersten diese Kommunikation > implementieren kann, denn der ganze Ablauf, bis zum erhalten der > Drehzahl spielt sich ja mindestens in zwei files ab: bei mir z.B. > in EPOS.c wo ich den "CAN_Transmit" Befehl ausführe und in > "stm32f10x_it.h" (in der Funktion "CAN_Transmit"), wo schlussendlich > ein Interrupt generiert wird bei Erhalt einer neuen Nachricht. Am saubersten, in dem du eine ganz klare Trennung einführst. Die CAN Schicht interessiert sich nur für CAN-Messages als Ganzes. Lediglich die ID des/der Kommunikationsteilnehmers ist für diese Schicht noch interessant. Was der Inhalt der Message bedeutet, hat die CAN Schicht nicht zu interessieren. Kommt eine Message rein, dann wird die Message als Ganzes zb in einer Queue abgelegt (zusammen mit der ID, von wem sie gekommen ist). Das ist die Schicht, in der die Interrupts ins Spiel kommen, die du brauchst, damit du keine Message verlierst. Die darüber liegende Schicht wiederrum interessiert sich nicht für CAN Details. Für die ist die darunterliegende Schicht lediglich ein Mittel zum Zweck, damit sie Messages auf die Reise bringen kann bzw. die sie befragen kann, ob in der Zwischenzeit Messages eingetroffen sind. Dazu braucht sie von CAN nichts verstehen und sie braucht auch keine Interrupts. Dafür muss diese Schicht aber darüber Bescheid wissen, was der Inhalt der Messages bedeutet und wie der zusammenzustellen/zu_interpretieren ist. Das ist ihre Domäne. Auf dieser Ebene wird eine Nachricht vom Teilnehmer A zum Teilnehmer B geschickt. Wie dieses Versenden passiert ist nicht mehr ihre Aufgabe.
Hallo hallo, sitze grad an ähnlicher Hardware (Maxon EPOS2+EC Motor), habe bereits den CAN-Controller meines µC soweit am Laufen, nur weiß ich mit dem CANopen Protokoll nicht weiter... @ Michael Merz: Wollte an dieser Stelle fragen, wie du das gelöst hast?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.