Zum Hauptinhalt springen

💥 Testen


⭐ Vorbereitung​

  1. Verbinde das Shuttle über USB-C mit deinem Laptop oder Computer.
  2. Öffne die Arduino App auf dem Laptop ( wenn du mit einem eigenen Laptop arbeitest Öffne Arduino-IDE )
  3. Bei dem arbeiten mit eigenen Laptop installiere die Bibliotheken "Servo" (Adafruit) und "MPU6050_tockn" (tockn) (von uns zur verfügung gestellte Laptops haben das bereits installiert)
  4. Lade den Test-Sketch hoch.
  5. Öffne den Serial-Monitor in der Arduino-IDE

✨ Test-Sketch​

Zeige Test-Sketch
#include <Arduino.h>
#include <Servo.h>
#include <Wire.h>
#include <MPU6050_tockn.h>

// Enable or disable specific features using these defines
#define RATELIMIT // Limits how fast the servos can move
#define SMOOTHANGLE // Smooths servo movement
#define LIMITACTIVE // Restricts servo movement to a safe range






//Verändern für Blinken im Intervall ( blincken kurze pause blinken lange pause ...)
int an = 200;
int kurzePause = 300;
int langePause = 500;






// Define servo control pins as constants
const int servoLeftPin = 9;
const int servoRightPin = 10;



// Create servo objects
Servo servoLeft;
Servo servoRight;

// Create MPU6050 sensor object
MPU6050 mpu6050(Wire);

// Servo positions
int positionLeft = 90;
int positionRight = 90;

// Define LED pins as constants
const int beaconLedPinRed = 3;
const int beaconLedPinGreen = 5;
const int beaconLedPinBlue = 6;
const int portLedPin = 7;
const int starboardLedPin = 8;

// Define temperature sensor pin
const int tempSensPin = 14;

// Temperature measurement variables
const int callCount = 5; // Number of measurements to average
int callTemp[callCount];
float tempAverage;

// ---------- Rainbow timing ----------
unsigned long lastRainbowMs = 0;
const uint16_t rainbowStepMs = 15; // smaller = faster rainbow
uint16_t rainbowHue = 0; // 0..359

// Function to apply Exponential Moving Average (EMA) for smoothing
float ema(float currentEMA, int newValue, float alpha) {
return alpha * newValue + (1 - alpha) * currentEMA;
}

// Function to limit the rate of change in servo position
int rateLimit(int desiredPosition, int currentPosition, int maxChange) {
int change = desiredPosition - currentPosition;
if (change > maxChange) change = maxChange;
else if (change < -maxChange) change = -maxChange;
return currentPosition + change;
}

// ---- HSV (0..359, 0..255, 0..255) to RGB (0..255) ----
static void hsvToRgb(uint16_t h, uint8_t s, uint8_t v, uint8_t &r, uint8_t &g, uint8_t &b) {
if (s == 0) { r = g = b = v; return; }

// Convert hue to region [0..5] and remainder
uint16_t region = h / 60; // 0..5
uint16_t rem = (h % 60) * 255 / 60; // 0..255

uint8_t p = (uint16_t)v * (255 - s) / 255;
uint8_t q = (uint16_t)v * (255 - ((uint16_t)s * rem) / 255) / 255;
uint8_t t = (uint16_t)v * (255 - ((uint16_t)s * (255 - rem)) / 255) / 255;

switch (region) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
default: r = v; g = p; b = q; break; // case 5
}
}

// Function to initialize hardware
void setup() {
servoLeft.attach(servoLeftPin);
servoRight.attach(servoRightPin);

servoLeft.write(positionLeft);
servoRight.write(positionRight);

Serial.begin(9600);
Wire.begin();

mpu6050.begin();
mpu6050.calcGyroOffsets(true);

pinMode(beaconLedPinRed, OUTPUT);
pinMode(beaconLedPinGreen, OUTPUT);
pinMode(beaconLedPinBlue, OUTPUT);
pinMode(portLedPin, OUTPUT);
pinMode(starboardLedPin, OUTPUT);

pinMode(tempSensPin, INPUT);
}

// Function to update servo positions based on MPU6050 sensor readings
void updateServoControl() {
mpu6050.update();

static float smoothedPositionLeft = 90;
static float smoothedPositionRight = 90;

#ifdef SMOOTHANGLE
smoothedPositionLeft = ema(smoothedPositionLeft, 90 - (mpu6050.getAngleY() + mpu6050.getAngleX()), 0.1);
smoothedPositionRight = ema(smoothedPositionRight, 90 + (mpu6050.getAngleY() - mpu6050.getAngleX()), 0.1);
#else
smoothedPositionLeft = 90 - (mpu6050.getAngleY() + mpu6050.getAngleX());
smoothedPositionRight = 90 + (mpu6050.getAngleY() - mpu6050.getAngleX());
#endif

#ifdef RATELIMIT
positionLeft = rateLimit((int)smoothedPositionLeft, positionLeft, 25);
positionRight = rateLimit((int)smoothedPositionRight, positionRight, 25);
#else
positionLeft = smoothedPositionLeft;
positionRight = smoothedPositionRight;
#endif

#ifdef LIMITACTIVE
positionLeft = min(135, max(10, positionLeft));
positionRight = min(135, max(10, positionRight));
#endif

servoLeft.write(positionLeft);
servoRight.write(positionRight);
}

// Function to update temperature readings
void updateTemperature() {
tempAverage = 0;
for (int k = 0; k < callCount; k++) {
callTemp[k] = analogRead(tempSensPin);
tempAverage += callTemp[k];
}
tempAverage /= callCount;
}

// Rainbow effect on the RGB beacon LED
void updateBeaconRainbow() {
unsigned long now = millis();
if (now - lastRainbowMs < rainbowStepMs) return;
lastRainbowMs = now;

// advance hue
rainbowHue++;
if (rainbowHue >= 360) rainbowHue = 0;

uint8_t r, g, b;
hsvToRgb(rainbowHue, 255, 255, r, g, b); // full saturation + brightness

Serial.print("Light: ");
Serial.print(r);
Serial.print(g);
Serial.println(b);

analogWrite(beaconLedPinRed, r);
analogWrite(beaconLedPinGreen, g);
analogWrite(beaconLedPinBlue, b);
}
// -------- Navigation light double pulse (digital only) --------

unsigned long navLastMs = 0;

const unsigned long pulseOnTime = an; // LED ON duration
const unsigned long pulseOffTime = kurzePause; // short gap between pulses
const unsigned long pauseTime = langePause; // long pause after two pulses

uint8_t navState = 0;

void updateNavigationLights() {
unsigned long now = millis();

switch (navState) {

// --- First pulse ON ---
case 0:
digitalWrite(portLedPin, HIGH);
digitalWrite(starboardLedPin, HIGH);
navLastMs = now;
navState = 1;
break;

// --- First pulse OFF ---
case 1:
if (now - navLastMs >= pulseOnTime) {
digitalWrite(portLedPin, LOW);
digitalWrite(starboardLedPin, LOW);
navLastMs = now;
navState = 2;
}
break;

// --- Second pulse ON ---
case 2:
if (now - navLastMs >= pulseOffTime) {
digitalWrite(portLedPin, HIGH);
digitalWrite(starboardLedPin, HIGH);
navLastMs = now;
navState = 3;
}
break;

// --- Second pulse OFF ---
case 3:
if (now - navLastMs >= pulseOnTime) {
digitalWrite(portLedPin, LOW);
digitalWrite(starboardLedPin, LOW);
navLastMs = now;
navState = 4;
}
break;

// --- Long pause ---
case 4:
if (now - navLastMs >= pauseTime) {
navState = 0;
}
break;
}
}



void loop() {
updateServoControl();
updateTemperature();
updateBeaconRainbow();
updateNavigationLights();

Serial.print("Servo Left: ");
Serial.println(positionLeft);
Serial.print("Servo Right: ");
Serial.println(positionRight);

}

🌟 Was sollte passieren?​

  • Die Navigationslichter blinken.
  • Die Beacon-LED hat einen Regenbogenartigen Effekt.
  • Die Servos bewegen sich jenach position des Shuttels.
  • Der MPU6050 liefert Sensordaten per Serial Monitor.

💫 Fehlersuche​

  • Servos reagieren nicht? → Pins kontrollieren, Stromversorgung prüfen
  • MPU liefert keine Daten? → I²C-Verbindung und Adressierung prüfen
  • LEDs blinken nicht? → Prüfe Pinbelegung und Polung
  • Fehler nicht gelöst? → Kontrolliere deine Löt- und Crimpverbindungen