Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
Nächste ÜberarbeitungBeide Seiten der Revision
light_can [2020/02/16 14:36] – [Lösungsansatz] huwilight_can [2020/02/17 13:57] – [Realisierung] huwi
Zeile 1: Zeile 1:
 ====== Den CAN-Bus mit dem mySTM32 light verwenden ====== ====== Den CAN-Bus mit dem mySTM32 light verwenden ======
-Diese Übung soll zu zweit ausgeführt werden bzw. sind zwei mySTM32 light Boards für diese Übung notwendig.\\ Im bisherigen Tutorial haben Sie den I²C Bus kennengelernt. Dieser Bus dient dazu verschiedene Controller zum Beispiel auf einer Leiterplatte zu verbinden. Wenn die zu vernetzenden Controller weiter auseinander liegen, zum Beispiel können für die Sensoren und Aktuatoren an einer Baumaschine schnell einige Meter Kabellänge zusammenkommen, benutzt man andere Feldbussysteme. Vor allem im Fahrzeugbereich ist der [[https://de.wikipedia.org/wiki/Controller_Area_Network|CAN-Bus]] ein häufig verwendetes Bussystem. CAN steht für Controller Area Network. Der Name sagt also schon, dass es sich hier um ein Netzwerkprotokoll für Mikrocontroller handelt. Im Gegensatz zum I²C Protokoll werden beim CAN sogenannte [[https://de.wikipedia.org/wiki/Datenframe|Frames]] versendet. Diese bestehen aus Steuerinformationen wie dem Nachrichten ID und den zu übertragenden Nutzdaten. Im Standardmodus bietet der Frame 8 Byte Nutzdaten an. Im CAN werden die Informationen üblicherweise nicht Ereignisorientiert einmalig gesendet sondern zyklisch mit einer bestimmten Updaterate zum Beispiel alle 20 oder 100 Millisekunden. Die Updaterate korreliert mit der Wichtigkeit der Nachricht. Das Ausbleiben einer Nachricht impliziert den Ausfall des entsprechenden Knotens.+Diese Übung soll zu zweit ausgeführt werden bzw. sind zwei mySTM32 light Boards für diese Übung notwendig.\\ Im bisherigen Tutorial haben Sie den I²C Bus kennengelernt. Dieser Bus dient dazu verschiedene Controller zum Beispiel auf einer Leiterplatte zu verbinden. Wenn die zu vernetzenden Controller weiter auseinander liegen, zum Beispiel können für die Sensoren und Aktuatoren an einer Baumaschine schnell einige Meter Kabellänge zusammenkommen, benutzt man andere Feldbussysteme. Vor allem im Fahrzeugbereich ist der [[https://de.wikipedia.org/wiki/Controller_Area_Network|CAN-Bus]] ein häufig verwendetes Bussystem. CAN steht für Controller Area Network. Der Name sagt also schon, dass es sich hier um ein Netzwerkprotokoll für Mikrocontroller handelt. Im Gegensatz zum I²C Protokoll werden beim CAN sogenannte [[https://de.wikipedia.org/wiki/Datenframe|Frames]] versendet. Diese bestehen aus Steuerinformationen wie dem Nachrichten ID und den zu übertragenden Nutzdaten. Im Standardmodus bietet der Frame 8 Byte bzw. 8x8 = 64 Bit Nutzdaten an. Im CAN werden die Informationen üblicherweise nicht Ereignisorientiert einmalig gesendet sondern zyklisch mit einer bestimmten Updaterate zum Beispiel alle 20 oder 100 Millisekunden. Die Updaterate korreliert mit der Wichtigkeit der Nachricht. Das Ausbleiben einer Nachricht impliziert den Ausfall des entsprechenden Knotens.
  
 ===== Die Aufgabe ===== ===== Die Aufgabe =====
Zeile 24: Zeile 24:
  
 ===== Lösungsansatz ===== ===== Lösungsansatz =====
-...+Eine CAN-Bus Lösung zu implementieren ist etwas komplexerEs ist notwendig sich mit dem CAN-Bus etwas eingehender zu [[https://www.youtube.com/results?search_query=can-bus+|beschäftigen]]. Bevor wir beginnen sollten uns über folgende Aspekte klar sein: 
 +  * Systemzustände werden zyklisch als Nachrichten auf den Bus gelegt (gesendet) 
 +  * Nachrichten haben keine Empfängeradressen sondern einen ID des abgebildeten Systemzustandes 
 +  * jeder Controller kann die für ihn wichtigen Systemzustände empfangen und darauf reagieren  
 +  * Controller können/müssen die gewünschten Nachrichten (ID's) herausfiltern  
 +  * der/die Systemzustände werden in 64 Bit Nutzdaten (8 Byte) codiert 
 + 
 +Versuchen wir die wichtigen Bausteine für den Systementwurf herauszufinden. Der zu sendende Systemzustand ist ein Taster. Für die Codierung des Tasterzustandes wird übrigens lediglich 1 Bit in der zu sendenden Nachricht benötigen. Der Controller wertet die Taste zyklisch, zum Beispiel alle 100 Millisekunden aus, codiert den Zustand (0/1) in einer CAN Nachricht und sendet diese auf dem CAN-Bus. Der empfangende Controller filtert und decodiert die empfangene Nachricht vom CAN-Bus und schaltet entsprechend die LED.  
  
 {{:uml:taste.jpg?nolink&70|}} {{:uml:smd32pin.jpg?nolink&150|}} {{:stm32light:sendmsg.png?nolink&120|}} {{:stm32light:can.jpg?nolink&150|}} {{:stm32light:recivemsg.png?nolink&120|}} {{:uml:smd32pin.jpg?nolink&150|}} {{::led.jpg?nolink&120|}}\\  {{:uml:taste.jpg?nolink&70|}} {{:uml:smd32pin.jpg?nolink&150|}} {{:stm32light:sendmsg.png?nolink&120|}} {{:stm32light:can.jpg?nolink&150|}} {{:stm32light:recivemsg.png?nolink&120|}} {{:uml:smd32pin.jpg?nolink&150|}} {{::led.jpg?nolink&120|}}\\ 
-{{:stm32light:classsendbutton.png?nolink&120|}} {{:uml:klassecontroller.jpg?nolink&120|}} {{::classsendmsg.png?nolink&120|}} {{:stm32light:classcanbus.png?nolink&120|}} {{:stm32light:classrecevemsg.png?nolink&120|}} {{:uml:klassecontroller.jpg?nolink&120|}} {{:stm32light:classreciveled.png?nolink&120|}}+{{:stm32light:classsendbutton.png?nolink&120|}} {{:uml:klassecontroller.jpg?nolink&120|}} {{::classsendmsg.png?nolink&120|}} {{:stm32light:classcanbus.png?nolink&120|}} {{:stm32light:classrecevemsg.png?nolink&120|}} {{:uml:klassecontroller.jpg?nolink&120|}} {{:stm32light:classreciveled.png?nolink&120|}}\\  
 +{{:stm32light:informationsfluss.png?nolink&800|}}
  
-...+Im Paket **"Middleware/CanSupport/pec_Can"** finden sich geeignete Bibliotheksbausteine für die gestellte AufgabeEs gibt Bausteine für den CAN-Bus und die Sende- und EmpfangsnachrichtenDie für die Lösung wichtigen Elemente sind in der folgenden Darstellung markiert.
  
-{{:stm32light:pec_can.png?1000|}}+{{:stm32light:pec_can.png?direct&900|}}
  
-...+Aus den herausgearbeiteten Systembausteinen lassen sich folgende Grobentwürfe der CAN Lösung ableiten.\\ Zuerst der Grobentwurf für die Senderlösung.
  
-**__MERKE:__ Middleware benutzen = Pakete zuweisen **+{{:stm32light:cansender.png?nolink&800|}} 
 +{{:stm32light:informationsfluss.png?nolink&700|}} 
 + 
 +Dazu der korrespondierende Entwurf der Empfängerlösung. 
 + 
 +{{:stm32light:canrecive.png?nolink&800|}} 
 +{{:stm32light:informationsfluss.png?nolink&700|}} 
 + 
 +Das CAN-Protokoll ist nicht Bestandteil der PEC-Basispakete sondern im Paket Middleware enthalten. Für die Verwendung der CAN-Bibliotheksbausteine ist es notwendig das entsprechende Treiberpaket **"pec_can"** aus dem Ordner **"Middleware/CanSupport"** in das Klassendiagramm einzubinden. 
 + 
 +**__MERKE:__ Middleware benutzen = entsprechendes Paket zuweisen **
  
 ===== Realisierung ===== ===== Realisierung =====
-...+Zunächst ist die Senderlösung zu implementierenBeachten Sie, das Paket **pec_can** in das Klassendiagramm einzubinden.\\ Eine kurze Zusammenfassung der notwendigen Aktionen: 
 +  * neues Klassendiagramm vorbereiten 
 +  * Paket **pec_Can** einbinden 
 +  * Klassen **SendButton**, **CanBus** und **SendMessage** anlegen und verbinden 
 +  * Bibliotheksbausteine **PecButtonClickAndHold**, **PecCanBus**, **PecCanMsgSend** anbinden 
 +  * konkrete Controller Ressourcen **pinA0** und **canPortA11A12_stm32f0** anbinden 
 +  * Operation **onEvent100ms** der Klasse **Controller** überschreiben 
 +  * Operation **onConfig** der Klasse **SendMessage** überschreiben
  
-{{:stm32light:i2cexample.png?direct&1100|}} 
  
-...+{{:stm32light:sendersolution.png?direct&1000|}}
  
->Controller::onWork():void<code c> +In der Operation **onConfig()** der Klasse **MessageRecive** weisen wir dem Messagobjekt den ID 1 zu. 
-// continuous event from the Mainloop + 
-// WENN ... DANN +{{ :stm32light:oncanconfig1.png?nolink&150|}} 
-//      ... +>SendMessage::onConfig():void<code c> 
-// SONST +msgId=0x01; 
-//      ...+
 </code> </code>
  
-{{ :stm32light:stml012a.png?direct&200|}} +Für das zyklische Senden des Zustandes des Tasters nutzen wir das 100 Millisekunden Ereignis der Klasse **Controller**. Den Tasterzustand codieren wir im ersten Datenbyte der Nachricht mit 0 für nicht betätigt und mit 1 für Taster betätigt.   
->Controller::onStart():void<code c> + 
-...+>Controller::onEvent100ms():void{{ :stm32light:seqcansend100ms.png?nolink&380|}}<code c> 
 +if (sendButton.isPressed()) 
 +
 + canBus.sendMessage.msgData.data8[0] = 1; 
 +
 +else 
 +
 + canBus.sendMessage.msgData.data8[0] = 0; 
 +
 +canBus.sendMessage.send();
 </code> </code>
  
-{{ :stm32light:stml012.png?direct&300|}} +Danach kann die Empfängerlösung zu implementiert werden. Beachten Sie, das Paket **pec_can** in das Klassendiagramm einzubinden.\\ Eine kurze Zusammenfassung der notwendigen Aktionen: 
->Controller::onWork():void<code c> +  * neues Klassendiagramm vorbereiten 
-...+  * Paket **pec_Can** einbinden 
 +  * Klassen **ReciveLED**, **CanBus** und **ReciveMessage** anlegen und verbinden 
 +  * Bibliotheksbausteine **PecLed**, **PecCanBus**, **PecCanMsgRecv** anbinden 
 +  * konkrete Controller Ressourcen **pinB0** und **canPortA11A12_stm32f0** anbinden 
 +  * Operation **onRecive** der Klasse **ReciveMessage** überschreiben 
 +  * Operation **onConfig** der Klasse **ReciveMessage** überschreiben 
 + 
 +{{:stm32light:canreciversolution.png?nolink&1000|}} 
 + 
 +Damit die richtige Nachricht empfangen wird weisen wir den ID 1 der erwarteten Empfangsnachricht zu. 
 + 
 +{{ :stm32light:oncanconfig2.png?nolink&150|}} 
 +>ReciveMessage::onConfig():void<code c> 
 +msgId=0x01; 
 </code> </code>
  
-...+Die Dekodierung der Nachricht realisieren wir einfach im Empfangs-Ereignis des Nachrichtenobjektes.
  
 +>ReciveMessage::onRecive():void{{ :stm32light:seqcanrecive.png?nolink&300|}}<code c>
 +if (msgData.data8[0] == 1)
 +{
 + app.reciveLED.on();
 +}
 +else
 +{
 + app.reciveLED.off();
 +}
 +</code>
 ===== Test ===== ===== Test =====
-Übersetzen Sie das Programm. Korrigieren Sie ggf. Schreibfehler. Übertragen Sie das lauffähige Programm in den Programmspeicher des Controllers.+Übersetzen Sie die Lösungen. Korrigieren Sie ggf. Schreibfehler. Übertragen Sie die lauffähigen Programme in den Programmspeicher der Controller.
   - Erstellen (Kompilieren und Linken)   - Erstellen (Kompilieren und Linken)
   - Brennen   - Brennen
-  - verbinden Sie ...+  - verbinden Sie auf den Boards entsprechend Taster 1 mit A0 und die rote LED mit B0 
 +  - Stellen Sie zwischen den Boards ein CAN Verbindung her, beachten Sie CAN Hi=Hi, GND=GND, Lo=Lo
  
-{{:erstellenbrennen.png?350|}}{{:stm32light:flashlight.png?direct&300|}}{{:stm32light:stm32bl2.png?direct&300|}}+{{:erstellenbrennen.png?300|}}{{:stm32light:flashlight.png?direct&300|}}{{:stm32light:stm32canl.png?nolink&450|}}
  
 ====== Videozusammenfassung ====== ====== Videozusammenfassung ======
 Erlernte und gefestigte Arbeitsschritte: Erlernte und gefestigte Arbeitsschritte:
-  - ... +  - Klassendiagramm anlegen und öffnen 
- +  - Diagrammvorlage für PEC Applikation auswählen 
 +  - laden des richtigen Treiber-Pakets  
 +  - **Middleware-Pakete einbinden** 
 +  - gewünschte Bausteine im Explorer suchen und ins Diagramm ziehen 
 +  - Klassen aggregieren, Komponenten bilden 
 +  - Operationen überschreiben 
 +  - den nötigen Quellcode in den Operationen erstellen 
 +  - Erstellen und Brennen eine ARM Applikation im Klassendiagramm 
 Und weil es so schön war hier das Ganze noch mal als Video. Und weil es so schön war hier das Ganze noch mal als Video.
  
Zeile 83: Zeile 147:
  
 ====== Übung ====== ====== Übung ======
-... +Erweitern Sie beide Lösunge so, dass diese jeweils eine SendeTaste und eine EmpfangsLED besitzen und die Board 1 an 2 und Board 2 an ein sendet.
 ====== Weiter mit: ====== ====== Weiter mit: ======
   * [[mystm32_board_light_tutorial|zurück zur Übersicht]]   * [[mystm32_board_light_tutorial|zurück zur Übersicht]]
   * [[ein kleines Projekt mit dem mySTM32 light]] <sub>(erfordert eine SiSy Lizenz ab Version 3.7x)</sub>   * [[ein kleines Projekt mit dem mySTM32 light]] <sub>(erfordert eine SiSy Lizenz ab Version 3.7x)</sub>