Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
light_can [2020/01/15 16:40]
huwi angelegt
light_can [2020/07/07 14:16] (aktuell)
huwi [Übung]
Zeile 1: Zeile 1:
 ====== Den CAN-Bus mit dem mySTM32 light verwenden ====== ====== Den CAN-Bus mit dem mySTM32 light verwenden ======
-...+{{tag>CAN BUS TASTE LED TOGGLE}} 
 +Diese Übung soll zu zweit ausgeführt werden bzwsind 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 =====
-...+{{ :stm32light:uccan.jpg?nolink&700|}} 
 +Es sind zwei Controllerboards über den CAN-Bus zu vrernetzenDabei soll jedes Board über einen Taster und eine LED verfügen. Beim betätigen der Taste soll die LED auf dem jeweils anderen Board leuchten.
  
-**Anforderungen:** +**Anforderungen an die Lösung:** 
-//...//+  * Sende-Taster jeweils an Pin A0 
 +  * Emfangs-LED jeweils an Pin B0 
 +  * CAN-Updaterate 100 Millisekunden 
 +  * Nachrichten IDs Board 1 = 1, Board 2 = 2
  
 ===== Vorbereitung ===== ===== Vorbereitung =====
Zeile 20: Zeile 25:
  
 ===== 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
  
-[[http://shop.myavr.de/index.php?sp=article.sp.php&artID=71|AddOn Temperatursensor LM75]]+Versuchen wir die wichtigen Bausteine für den Systementwurf herauszufindenDer zu sendende Systemzustand ist ein TasterFü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-BusDer 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|}}\\  
 +{{: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|}}
  
-**__MERKE:__ ... ... **+Im Paket **"Middleware/CanSupport/pec_Can"** finden sich geeignete Bibliotheksbausteine für die gestellte Aufgabe. Es gibt Bausteine für den CAN-Bus und die Sende- und Empfangsnachrichten. Die für die Lösung wichtigen Elemente sind in der folgenden Darstellung markiert. 
 + 
 +{{: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. 
 + 
 +{{: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 ======
 +{{tag>Video}}
 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 73: Zeile 148:
 ><html><iframe width="640" height="440" src="https://www.youtube.com/embed/GNvT2T8sD6I" frameborder="0" allowfullscreen></iframe></html> ><html><iframe width="640" height="440" src="https://www.youtube.com/embed/GNvT2T8sD6I" frameborder="0" allowfullscreen></iframe></html>
  
-====== Übung ====== +====== Übung 12 ====== 
-... +Erweitern Sie beide Lösungen 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]]
 +  * [[light all in one|Das Wichtigste in einem Beispiel zusammengefasst]]
   * [[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>
 +
 +====== Suchbegriffe ======
 +