Dies ist ein Repository für mein Mechatronik Projekt im 4. Semester meines Ingeneurinformatik Studiums. Die Grundidee ist, Kommunikation zwischen Mikrocontrollern kennenzulernen, also, zwei Mikrocontroller miteinander (bestenfalls kabellos) zu verbinden und damit irgendwelche Aktionen auszuführen.
Konkret für dieses Projekt habe ich entschieden, mit meinem eigenen Arm einen Roboterarm zu steuern. Den genauen Aufbau von einem Roboterarm belasse ich zunächst außer Betracht, weil er ziemlich aufwändig sein soll, um mehr als nur Ellbogen biegen zu können :)
Dieses Projekt wurde im VS Code mithilfe PlatformIO Extension entwickelt. Alternativ kannst du auch in nativem ArduinoIDE arbeiten. Um den Code auf dein PC zu haben tuh bitte folgendes:
- Klone dieses Repository auf dein PC mit
git clone https://github.com/Robert35-dll/RoboArm.git - Öffne den heruntergeladenen Ordner in deinem IDE
- Optional: öffne das
code-workspaceDatei, um in VS Code schneller zwischen Teilprojekten zu wechseln
- Optional: öffne das
An dieser Stelle solltest du die Ordnerstruktur vom Projekt sehen:
/Roboarm
|-/ArmReader
| |-/.vscode
| |-/include
| |-/lib
| |-/src
| |-< main.cpp (hier liegt der Code von ArmReader)
| |-/test
| |-< .gitignore
| |-< patformio.ini
|-/ArmWriter
| |-/.vscode
| |-/include
| |-/lib
| |-/src
| |-< main.cpp (hier liegt der Code von ArmWriter)
| |-/test
| |-< .gitignore
| |-< patformio.ini
|-< code-workspace.code-workspace
|-< README.md
Wenn dein PlatformIO bzw. ArduinoIDE noch keine Teilprojekte erkannt hat, musst du selber die Pfade von ArmReader und ArmWriter Ordnern (nicht von main.cpp Dateien) öffnen / angeben.
Wenn beide Teilprojekte erkannt werden, installiere die notwendige Bibliotheken:
- Öffne das
ArmReaderProjekt und installiereRF24Bibliothek - Öffne das
ArmWriterProjekt und installiereRF24undServoBibliotheken - Anschließend kannst du beide Projekte kompilieren lassen und prüfen, ob alles geklappt hat
Siehe BuildTutorial.md
Das gesamte Projekt besteht aus zwei Subsystemen:
ArmReader- liest die Lage vom menschlichen Arm und sendet diese an denArmWriterArmWriter- übernimmt die Lage des menschlichen Arms und steuert den Roboterarm
Diese kommunizieren mittels eines Funkkanals, wobei ArmReader als Sender und ArmWriter als Empfänger funktionieren. Das einzige zu übertragende Objekt ist ein Array mit gemessenen Winkeln und dem Signal vom Joystick.
Im folgendem PAP sind die grundsätzliche Aktivitäten jeweiliges Systems vereinfacht abgebildet:
Die zwei zentrale Codedateien sind die jeweiligen main.cpp Dateien in folgenden Ordnern:
RoboArm/ArmReader/src/main.cppRoboArm/ArmWriter/src/main.cpp
Beide Dateien sind ähnlich aufgebaut und strukturiert:
[*]-[Initialisierung]
[|]-> // Import von Bibliotheken
[|]-> // Definition von Variablen
[|]-> // Deklaration von Prozeduren und Funktionen
|
[*]-[Hauptteil]
[|]-> // void setup() Prozedur
[|]-> // void loop() Prozedur
|
[*]-[Nebenteil]
[|]-> // Definition von weiteren notwendigen Prozeduren und Funktionen
|
[*]-[Andere Prozeduren]
[|]-> Ausgabe Prozeduren zum Testen / Debuggen
Die meisten Stellen wurden ziemlich umfangreich kommentiert. Zum tieferen Einblick auf theoretischen Grundlagen siehe den folgenden Abschnitt.
In diesem Abschnitt werden unterschiedliche theoretische Kenntnisse aufgeschrieben, die ich während des Projekts kennengelernt habe.
I2C steht für Inter-Integrated Circuit und wird hauptsächlich benutzt, um mehrere Peripheriegeräte mit wenigen Kabeln an einen Mikrocontroller anzuschließen. Dies wird durch zwei zentrale "Kommunikationsbände" ermöglicht:
- Serial Data (SDA) - für die tatsächliche Datenübertragung
- Serial Clock (SCL) - für die Synchronisation dieser Datenübertragung zwischen Sendern und Empfängern
sowie die Angabe von einzigartigen IDs für jedes Gerät.
Wichtige Bemerkung: Falls zwei Geräten das gleiche ID von Herstellern gegeben wurden, muss ein davon vor der Initialisierung der Kommunikation geändert werden! Mehr dazu im Abschnitt von Wire Bibliothek.
Die entsprechende Pins gibt es auf allen Arduino Boards. Arduino GIGA hat sogar mehrere SDA / SCL Pins.
Mehr zum Thema in der Arduino I2C Dokumentation.
Arduino hat die Wire Bibliothek vorbereitet, die manche technische grundlegende Operationen übernimmt. Von gängigen Methoden sind:
begin() / end()- um einen I2C Bus zu initialisieren / auflösenbegin- / endTransmission()- um einzelne Datenübertragung zu starten / beendenwrite()- um Daten auf den Bus zu schreiben oder reserviert Bytes für die nächste Übertragungread()- um den nächsten Byte von Daten aus dem Bus zu lesen
Die originale Dokumentation von Arduino wird einem Anfänger nicht viel bei, deswegen empfehle ich sehr, selbständig Beispiele zu finden und daraus zu lernen :)
Um die gemessene Winkeln zu korrigieren, wurde ein Komplementär Filter implementiert, für den drei verschiedene Techniken eingesetzt wurden:
- Dynamische Alpha-Korrektur - um Einflüsse von Accelerometer und Gyroskop bei der Winkelberechnung abhängig von der Amplitude dynamisch anzupassen:
Alpha = abs(AccMagnitude - 1.0) > 0.1 ? 0.02 : 0.045;- High-Pass-Filter - um rasante Lageänderungen zu dämpfen:
GyroCorrection = (PreviousAngle - AccelerometerAngle) * 0.8;- Bias-Korrektur (Low-Pass-Filter) - um langfristige Drifts zu vermindern:
GyroBias += GyroAngle * 0.0001;Letztendlich sind alle drei Teilberechnungen in der Formel für Komplementär Filter benutzt worden:
CorrectedAngle = Alpha * (PreviousAngle + (GyroAngle - GyroBias) * milliseconds)
+ (1 - Alpha) * (AccelerometerAngle + GyroCorrection);Mehr zum Thema in meinem Chat mit Copilot.
Die MPU6050 Module verfügen gleichzeitig über einen Accelerometer und einen Gyroskop die ebenfalls gleichzeitig zur Messung von Winkeln und daher Bestimmung der Lage verwendet werden können. Der Unterschied zwischen den beiden Mechanismen kann grob vereinfacht so interpretiert werden:
- Accelerometer - bestimmt die Winkeln mit Referenz zur Erdbeschleunigung
- Gyroskop - bestimmt die Winkelgeschwindigkeiten mit Referenz zur letzten stabilen Lage
Daher macht es meistens Sinn, beide Geräte gleichzeitig zu verwenden, um die Messgenauigkeit zu erhöhen.
Mehr zum Thema in diesem Artikel von Last Minute Engineers.
Für eine Funkverbindung reichen gut die nRF24L01 Module mit eigener RF24 Bibliothek aus. Diese werden per SPI Protokoll mit weiteren "Kommunikationsbändern" an den Mikrocontroller angeschlossen:
- Master In - Slave Out (MISO) - für die Datenübertragung von Peripheriegeräten (ggf. nRF24) zum Controller
- Master Out - Slave In (MOSI) - für die Datenübertragung vom Controller zu den Peripheriegeräten (ggf. nRF24)
- Serial Clock (SCL) - für die Synchronisation dieser Datenübertragung zwischen Sendern und Empfängern (das gleiche wie bei I2C Protokoll)
- Chip Select (CS / CSN) - für den Auswahl eines Peripheriegeräts (ggf. nur eines nRF24) zur nächsten Kommunikation
- Chip Enable (CE) - für die Aktivierung eines Peripheriegeräts (ggf. nRF24)
Mit der nRF24 Bibliothek kann ein Funkkanal (Datenrate, Kanal, Puffergröße, etc.) genau eingestellt werden. Hier sind paar Hinweise zur Anwendung:
- Die Einstellungen sollten einzigartig für den Anwendungsraum sein, um die Störungen durch andere Funkgeräte zu vermeiden.
- Alle Daten (bis zu 32 Bytes standardmäßig) werden mit der ´write()´ Methode byteweise ohne implizite Umwandlung geschickt. Die überschüssige Bytes werden beim Senden ignoriert!
Mehr zum nRF24L01 Modul in diesem Tutorial vom Wolles Elektronikkiste.
Mehr zum Thema SPI in diesem Artikel von Analog Dialogue.
