Benutzer-Werkzeuge

Webseiten-Werkzeuge


mechatronik:sose24:radioantenne_ausrichten

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
mechatronik:sose24:radioantenne_ausrichten [2024/08/01 12:30]
Jonny5 [Schaltplan:]
mechatronik:sose24:radioantenne_ausrichten [2024/08/04 13:05] (aktuell)
Jonny5 [Durchlauf:]
Zeile 15: Zeile 15:
 ===== Schaltplan: ===== ===== Schaltplan: =====
 {{:​mechatronik:​sose24:​screenshot_2024-07-23_142215.png?​500|}} \\ {{:​mechatronik:​sose24:​screenshot_2024-07-23_142215.png?​500|}} \\
-Bild 1 \\ +Bild 1 
-===== ESP32:​===== +
-Dieses Bauteil spielt bei Antirector eine entscheidende Rolle. Deswegen folgt hier eine kurze Erläuterung:​+
  
-Der ESP32 ist eine kostengünstige ​und mit geringem Leistungsbedarf ausgeführte 32-Bit-Mikrocontrollerfamilie ​der chinesischen Firma Espressif, die im Jahr 2016 vorgestellt wurde. Die Mikrocontroller ermöglichen durch ihre offene Bauweise ​den Aufbau und die Vernetzung von netzwerkbasierten Aktuatoren und Sensoren.+Das Herzstück unserer Schaltung ist der Arduino Uno. Er gibt Befehle an die jeweiligen Motoren und verarbeitet die Messdaten des ESP32. Folgende Pins werden verwendet: Pin 2 für die serielle Kommunikation mit dem ESP32, Pin 3 für die Richtungssteuerung des Servomotors,​ Pin 5 für die Richtungssteuerung des Schrittmotors ​ und Pin 6 für dessen Schrittweite. \\ 
 +Das ESP32 ist ein Mikrocontroller,​ der über eine eingebaute/​angebaute (je nach Bauart) Antenne verfügt ​und es ermöglicht,​ sich über WLAN oder Bluetooth ​mit anderen Geräte zu vernetzen. In unserem Fall ist es mit einem mobilen Hotspot verbunden, dessen Signalstärke gemessen werden soll. Um die Messwerte an den Arduino Uno zu senden, ist der TX-Pin (T für "​Transmit"​) des ESP32 mit dem RX-Pin (R für "​Receive"​) des Arduinos verbunden. Auf diese Weise kann serielle Kommunikation zwischen den beiden Mikrocontrollern stattfinden. \\ 
 +Der Nema 17 ist für das Azimut zuständig, also für die Drehung ​der Antenne in der horizontalen Ebene. Jeder Schritt entspricht einem Drehwinkel von 1,8 Grad. Der Nema 17 kann aber auch Halbschritte ausführen, was 800 Schritte auf 360 Grad ergibt. Das ermöglicht eine präzise Ausrichtungsveränderung der Antenne, die wir für unser Projekt längst nicht voll ausgenutzt habenFür die Steuerung des Nema 17 haben wir einen DRV8825-Schrittmotortreiber verwendet. Dieser bestimmt die Richtung ​ ,in die sich der Schrittmotor dreht. \\ 
 +Zuletzt ist da noch der Servomotor für die Elevation, also die Drehbewegung in der vertikalen Ebene. Zwei Kabel bilden die Pole für die Spannungsversorgung,​ ein drittes gibt die Drehrichtung an. \\ 
 +Die 12V-Spannungsquelle versorgt ​den Schrittmotor, ​die 5V-Spannungsquelle den Servomotor über den Schrittmotortreiber.
  
-{{:​mechatronik:​sose24:​esp32-devkitc-v4-pinout.png?​600|Pinout des ESP32}} \\ 
-Bild 2: Pinout des ESP32 
  
 +
 +
 +
 +===== Code: =====
 +<​code>​
 +// Libraries
 +#include <​SoftwareSerial.h>​
 +#include <​Servo.h>​
 +#include <​Stepper.h>​
 +
 +// Pins
 +const byte rxPin = 2;
 +const byte servoPin = 3;
 +const byte stepperStepPin = 5;
 +const byte stepperDirPin = 6;
 +
 +const byte ledRSSIPin = 8;
 +const byte ledRSSI2Pin = 9;
 +const byte ledRSSI3Pin = 10;
 +
 +const byte buttonScanPin = 4;
 +
 +//config
 +SoftwareSerial SerialESP(rxPin,​ -1); 
 +
 +Servo servoX;
 +Stepper stepperZ(800,​ stepperStepPin,​ stepperDirPin);​
 +
 +//Servo
 +int currentPositionX = 90;
 +int bestPositionX = 90;
 +float bestSignalX = 1000;
 +
 +//Stepper
 +int currentPositionZ = 0;
 +int bestPositionZ = 9;
 +float bestSignalZ = 1000;
 +
 +//​RSSI-Reading
 +int rssi = 0;
 +const int numReadings = 5;
 +int rssiArray[numReadings];​
 +int readIndex = 0;
 +int readCount = 0;
 +
 +//​Steuerbedingungen
 +bool scanningCompleteZ = false;
 +bool scanningCompleteX = false;
 +bool scanEnabled = false;
 +bool scanButtonPressed = false;
 +
 +//​Entprellen
 +unsigned long lastButtonPressTime = 0;
 +const int debounceDelay = 50;
 +
 +//Serieller Befehl
 +String command = "";​
 +
 +void setup() {
 +//pins
 +  pinMode(rxPin,​ INPUT);
 +  pinMode(servoPin,​ OUTPUT);
 +  pinMode(ledRSSIPin,​ OUTPUT);
 +  pinMode(ledRSSI2Pin,​ OUTPUT);
 +  pinMode(ledRSSI3Pin,​ OUTPUT);
 +  pinMode(buttonScanPin,​ INPUT_PULLUP);​
 +//Serielle Verbindungen
 +  Serial.begin(9600);​
 +  SerialESP.begin(9600);​
 +//Servo Setup
 +  servoX.attach(servoPin);​
 +  servoX.write(90);​
 +//Stepper Setup
 +  stepperZ.setSpeed(100);​ //
 +//​Initialisieren des Read Arrays
 +  for (int i = 0; i < numReadings;​ i++) {
 +    rssiArray[i] = 0;
 +  }
 +//Wartezeit und Bereitschaft
 +  delay(500);
 +  Serial.println();​
 +  Serial.println("​Hello There!"​);​
 +  delay(500);
 +  Serial.println(F("​E.R.O.S. ready"​));​
 +}
 +
 +void loop() {
 +//Lesen des Seriellen Befehls
 +if (Serial.available() > 0) {
 +  command = Serial.readStringUntil('​\n'​);​
 +  command.trim();​
 +}
 +//Starten des Scans durch Button oder Befehl
 +if ((digitalRead(buttonScanPin) == LOW && !scanButtonPressed && millis() - lastButtonPressTime > debounceDelay) || (command.equalsIgnoreCase("​scan"​))) {
 +//​Entprellen und einmaliges Drücken
 +  lastButtonPressTime = millis();
 +  scanButtonPressed = true;
 +
 +  Serial.println(F("​starting SCAN"​));​
 +//Stepper zurück auf 0 (falls bereits gescant)
 +  stepperZ.step(-currentPositionZ);​ //
 +  currentPositionZ = 0;
 +  bestPositionZ = 0;
 +//Servo zurück auf 90 (falls bereits gescant)
 +  currentPositionX = 90;
 +  bestPositionX = 90;
 +  servoX.write(90);​
 +  delay(500); //Wartezeit während sich der Servo bewegt (nach jedem servo.write)
 +//​Aktivieren der Bedingung fürs Scannen und Zurücksetzen der Ergebnisse
 +  scanEnabled = true;
 +  scanningCompleteX = false;
 +  scanningCompleteZ = false;
 +  bestSignalX = 1000;
 +  bestSignalZ = 1000;
 +//​Rücksetzen und Initialisieren der Readings
 +  readIndex = 0;
 +  readCount = 0;
 +  for (int i = 0; i < numReadings;​ i++) {
 +    rssiArray[i] = 0;
 +  }
 +//Ausgeben der ersten (Start) Position
 +  Serial.print(F("​Z:​ "));
 +  Serial.print(currentPositionZ);​
 +  Serial.print(F("​ | X: "));
 +  Serial.println(currentPositionX);​
 +//Leerung des Seriellen Befehls
 +  command = "";​
 +} else if (digitalRead(buttonScanPin) == HIGH) {
 +//Reset des Buttons, sobald nicht mehr gedrückt (gegen Gedrückthalten)
 +  scanButtonPressed = false;
 +}
 +
 +//Scan Programm (wird durch das obere aktiviert, nur wenn Signal vorhanden)
 +if (scanEnabled && !scanningCompleteX && rssi != 0) {
 +//Empfang des Signals durch ESP jede Sekunde als Trigger
 +  if (SerialESP.available() > 0) {
 +//Einlesen des Signals
 +    String rssiRX = SerialESP.readStringUntil('​\n'​);​
 +    rssi = rssiRX.toInt();​
 +    Serial.print(F("​RSSI:​ -"));
 +    Serial.println(rssi);​
 +
 +    rssiArray[readIndex] = rssi;
 +    readIndex = (readIndex + 1) % numReadings;​
 +    if (readCount < numReadings) {
 +      readCount++;​
 +    }
 +//​Auswertung wenn 5 Signale empfangen wurden
 +    if (readCount == numReadings) {
 +      int sum = 0;
 +      for (int i = 0; i < numReadings;​ i++) {
 +        sum += rssiArray[i];​
 +      }
 +//​Durchschnitt aus den Signalen
 +      float average = (float)sum / numReadings;​
 +
 +      Serial.print(F("​⌀ RSSI: -"));
 +      Serial.println(average);​
 +      Serial.println();​
 +//nur während Stepper Drehung
 +      if (!scanningCompleteZ) {
 +        if (average < bestSignalZ) {
 +//Speichern des besten Signals und der entsprechenden Stepper Position
 +          bestSignalZ = average;
 +          bestPositionZ = currentPositionZ;​
 +        }
 +//​Einstellen der nächsten Stepper Position
 +        currentPositionZ += 100;
 +      }
 +//nur während Servo Drehung
 +      if (scanningCompleteZ) {
 +        if (average < bestSignalX) {
 +//Speichern des besten Signals und der entsprechenden Servo Position
 +          bestSignalX = average;
 +          bestPositionX = currentPositionX;​
 +        }
 +//​Einstellen der nächsten Servo Position
 +        currentPositionX += 15;
 +      }
 +//Prüfung ob Stepper einmal durch ist
 +      if (currentPositionZ > 700 && !scanningCompleteZ) {
 +//​Übermitteln der besten gemessenen Stepper Position
 +        Serial.print(F("​best Z: "));
 +        Serial.print(bestPositionZ);​
 +        Serial.print(F("​ | best ⌀ RSSI: -"));
 +        Serial.println(bestSignalZ);​
 +//Anfahren und Einstellen der besten Stepper Position
 +        stepperZ.step(-(700-bestPositionZ));​ //
 +        currentPositionZ = bestPositionZ;​
 +//Reset der Readings
 +        readIndex = 0;
 +        readCount = 0;
 +        for (int i = 0; i < numReadings;​ i++) {
 +          rssiArray[i] = 0;
 +        }
 +//Servo auf Startposition für Servo Drehung
 +        currentPositionX = 45;
 +        servoX.write(45);​
 +        delay(500);
 +//​Bedingungen,​ dass der Stepper fertig ist
 +        scanningCompleteZ = true;
 +//Prüfung ob Stepper noch nicht fertig ist
 +      } else if (!scanningCompleteZ){
 +//Anfahren der nächsten Stepper Position
 +        stepperZ.step(100);​
 +//Reset der Readings
 +        readIndex = 0;
 +        readCount = 0;
 +        for (int i = 0; i < numReadings;​ i++) {
 +          rssiArray[i] = 0;
 +        }
 +//​Übermitteln der Position
 +        Serial.print(F("​Z:​ "));
 +        Serial.print(currentPositionZ);​
 +        Serial.print(F("​ | X: "));
 +        Serial.println(currentPositionX);​
 +      }
 +//Prüfung ob Servo fertig ist
 +      if (currentPositionX > 135) {
 +//​Bedingungen,​ dass der Scan nicht weiterläuft
 +        scanningCompleteX = true;
 +        scanEnabled = false;
 +//​Übermitteln der besten Positionen
 +        Serial.println(F("​SCAN completed:"​));​
 +        Serial.print(F("​best Z: "));
 +        Serial.print(bestPositionZ);​
 +        Serial.print(F("​ | best X: "));
 +        Serial.print(bestPositionX);​
 +        Serial.print(F("​ | best ⌀ RSSI: -"));
 +        Serial.println(bestSignalX);​
 +//​Einstellen und Anfahren der besten Servo Position
 +        currentPositionX = bestPositionX;​
 +        servoX.write(bestPositionX);​
 +        delay(500);
 +//Prüfung ob Servo noch nicht fertig ist
 +      } else if (scanningCompleteZ) {
 +//Anfahren der nächsten Servo Position
 +          servoX.write(currentPositionX);​
 +          delay(500);
 +//Reset der Readings
 +          readIndex = 0;
 +          readCount = 0;
 +          for (int i = 0; i < numReadings;​ i++) {
 +            rssiArray[i] = 0;
 +          }
 +//​Übermitteln der Position
 +          Serial.print(F("​Z:​ "));
 +          Serial.print(currentPositionZ);​
 +          Serial.print(F("​ | X: "));
 +          Serial.println(currentPositionX);​
 +      }
 +    }
 +  }
 +} else {
 +//​Aktualisierung des Signals während Scan nicht läuft für LEDs
 +    if (SerialESP.available() > 0) {
 +      String rssiRX = SerialESP.readStringUntil('​\n'​);​
 +      rssi = rssiRX.toInt();​
 +    }
 +}
 +
 +}
 +</​code>​
 ===== 3D-Druck: ===== ===== 3D-Druck: =====
 Ein weiterführendes Ziel des Projektes war es, eine Yagi-Antenne selbst zu bauen und diese mit Hilfe von zwei Motoren zu bewegen. Ein weiterführendes Ziel des Projektes war es, eine Yagi-Antenne selbst zu bauen und diese mit Hilfe von zwei Motoren zu bewegen.
Zeile 32: Zeile 295:
 Auch die Antenne selbst soll zum Teil gedruckt werden, da das Material nicht leitend und leicht ist. Dazu haben wir zum einen eine Halterung für die Antenne konstuiert, die genau auf den Servomotor passt und den nötigen Abstand zu diesem gewährleistet. Der Abstand ist wichtig, damit die Antenne beim Drehen nicht mit Ihren Direktoren an dem Servo- oder Schrittmoter hängen bleibt. Auch die Antenne selbst soll zum Teil gedruckt werden, da das Material nicht leitend und leicht ist. Dazu haben wir zum einen eine Halterung für die Antenne konstuiert, die genau auf den Servomotor passt und den nötigen Abstand zu diesem gewährleistet. Der Abstand ist wichtig, damit die Antenne beim Drehen nicht mit Ihren Direktoren an dem Servo- oder Schrittmoter hängen bleibt.
  
-{{:​mechatronik:​sose24:​a246f981-d17c-4406-9f3b-2c7bbb17b5df.jpeg?​700|Servo-Halterug und Halterung für den Boom der Antenne}}+{{:​mechatronik:​sose24:​a246f981-d17c-4406-9f3b-2c7bbb17b5df.jpeg?​500|Servo-Halterug und Halterung für den Boom der Antenne}}
  
 Bild 3: Servo-Motor in Halterung auf Schrittmotor und Halterung für den Boom der Antenne Bild 3: Servo-Motor in Halterung auf Schrittmotor und Halterung für den Boom der Antenne
 +
 +===== Durchlauf: =====
 +
 +{{:​mechatronik:​sose24:​antirector_durchlauf.mp4|}} \\
 +Bitte ignoriert die LEDs und Taster auf dem Breadboard. Das Video zeigt eine Vorversion, in welcher noch Statusanzeige und Knöpfe für bestimmte Befehle integriert waren. Erst nach der Aufnahme haben wir die Schaltung reduziert. Das Prinzip bleibt aber dasselbe.
 +
 ===== Fazit: ===== ===== Fazit: =====
 Dass Antirector ein cooles System mit Realitätsnutzen ist, sehen wir nach wie vor so. (Beispiel: [[https://​www.youtube.com/​watch?​v=udqbDNeuZ58 |Starlink]]). Die Zusammensetzung unserer Gruppe war relativ gut, da wir für jeden Teilbereich des Systems jemanden hatten, der/die sich gerne damit beschäftigte und somit kein Bereich unterbesetzt blieb. \\ In seiner jetzigen Form stellt Antirector eine absolute Basis dar, die noch um einiges erweitert werden müsste. Natürlich war es nicht der Plan unserer Gruppe, ein marktreifes Produkt auf die Beine zu stellen. Nichtsdestotrotz besteht bei den Themen Zeitmanagement und Kommunikation für das nächste Projekt noch Luft nach oben. Es wäre sinnvoll gewesen, sich zuallererst ausführlich damit auseinanderzusetzen,​ welche genauen Anforderungen man an das fertige System stellt. Auf diese Art und Weise ließen sich Aufgabenpakete mit Deadlines leichter erstellen.\\ Von dieser kleinen Kritik abgesehen, hat es uns dennoch Spaß gemacht, an diesem Projekt zu arbeiten und einige Ideen in die Tat umzusetzen. Dass Antirector ein cooles System mit Realitätsnutzen ist, sehen wir nach wie vor so. (Beispiel: [[https://​www.youtube.com/​watch?​v=udqbDNeuZ58 |Starlink]]). Die Zusammensetzung unserer Gruppe war relativ gut, da wir für jeden Teilbereich des Systems jemanden hatten, der/die sich gerne damit beschäftigte und somit kein Bereich unterbesetzt blieb. \\ In seiner jetzigen Form stellt Antirector eine absolute Basis dar, die noch um einiges erweitert werden müsste. Natürlich war es nicht der Plan unserer Gruppe, ein marktreifes Produkt auf die Beine zu stellen. Nichtsdestotrotz besteht bei den Themen Zeitmanagement und Kommunikation für das nächste Projekt noch Luft nach oben. Es wäre sinnvoll gewesen, sich zuallererst ausführlich damit auseinanderzusetzen,​ welche genauen Anforderungen man an das fertige System stellt. Auf diese Art und Weise ließen sich Aufgabenpakete mit Deadlines leichter erstellen.\\ Von dieser kleinen Kritik abgesehen, hat es uns dennoch Spaß gemacht, an diesem Projekt zu arbeiten und einige Ideen in die Tat umzusetzen.
 +
 +
  
 **Quellen:​**\\ **Quellen:​**\\
mechatronik/sose24/radioantenne_ausrichten.1722508250.txt.gz · Zuletzt geändert: 2024/08/01 12:30 von Jonny5