Servus Grüazi und hallo
ja ich hab den code vergessen sorry. Ich hab auch nachgebrütet und bin drauf gekommen die falsche bibliothekt verwendet.
mit der MPU6550_light ging es nicht aber mit der MPU6050 und diesem code
// v3.4.0 – MPU6050 FINAL
// Korrekte Achsen, stabiler Stillstand, Chip kann nach unten liegen
#include <Wire.h>
#include <MPU6050.h>
#include <math.h>
MPU6050 mpu;
// Winkel
float pitch = 0.0;
float roll = 0.0;
// Gyro-Offsets
float gyroOffsetX = 0.0;
float gyroOffsetY = 0.0;
// Zeit
unsigned long lastTime = 0;
// Filter & Loop
const float ALPHA = 0.90; // Debug-tauglich bei 5 Hz
const int LOOP_DELAY = 200; // ms
// --------------------------------------------------
float normalizeAngle(float angle) {
while (angle > 180.0) angle -= 360.0;
while (angle < -180.0) angle += 360.0;
return angle;
}
// --------------------------------------------------
void calibrateGyro() {
const int samples = 1000;
long sumX = 0, sumY = 0;
Serial.println("Gyro-Kalibrierung... ruhig liegen lassen");
for (int i = 0; i < samples; i++) {
int16_t gx, gy, gz;
mpu.getRotation(&gx, &gy, &gz);
sumX += gx;
sumY += gy;
delay(2);
}
gyroOffsetX = sumX / (float)samples;
gyroOffsetY = sumY / (float)samples;
Serial.print("Offset GX: "); Serial.println(gyroOffsetX);
Serial.print("Offset GY: "); Serial.println(gyroOffsetY);
}
// --------------------------------------------------
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println("MPU6050 Fehler");
while (1);
}
Serial.println("MPU6050 bereit (v3.4)");
calibrateGyro();
// Startwinkel aus Accelerometer setzen
int16_t ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
float Ax = ax / 16384.0;
float Ay = ay / 16384.0;
float Az = az / 16384.0;
pitch = atan2(-Ax, sqrt(Ay * Ay + Az * Az)) * 180.0 / PI;
roll = atan2(Ay, sqrt(Ax * Ax + Az * Az)) * 180.0 / PI;
lastTime = micros();
}
// --------------------------------------------------
void loop() {
int16_t ax, ay, az;
int16_t gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
unsigned long now = micros();
float dt = (now - lastTime) / 1000000.0;
lastTime = now;
float Ax = ax / 16384.0;
float Ay = ay / 16384.0;
float Az = az / 16384.0;
// KORREKTE Gyro-Zuordnung
float gyroPitch = (gy - gyroOffsetY) / 131.0;
float gyroRoll = (gx - gyroOffsetX) / 131.0;
float accPitch = atan2(-Ax, sqrt(Ay * Ay + Az * Az)) * 180.0 / PI;
float accRoll = atan2(Ay, sqrt(Ax * Ax + Az * Az)) * 180.0 / PI;
pitch = ALPHA * (pitch + gyroPitch * dt) + (1.0 - ALPHA) * accPitch;
roll = ALPHA * (roll + gyroRoll * dt) + (1.0 - ALPHA) * accRoll;
pitch = normalizeAngle(pitch);
roll = normalizeAngle(roll);
Serial.print("Pitch: ");
Serial.print(pitch, 2);
Serial.print(" Roll: ");
Serial.println(roll, 2);
delay(LOOP_DELAY);
}
kommen verwertbare werte raus
Das kippen und ausgleichen kommt mit dem code
#include <Wire.h>
#include <MPU6050.h>
#include <ESP32Servo.h>
#include <math.h>
MPU6050 mpu;
// -------- SERVO SETUP --------
Servo servoA;
Servo servoB;
const int SERVO_A_PIN = 16;
const int SERVO_B_PIN = 17;
const float SERVO_CENTER = 90.0;
const float SERVO_MIN = 45.0;
const float SERVO_MAX = 135.0;
const float MAX_HUB = 45.0;
// -------- Bewegung --------
float currentHub = 0.0;
const float MAX_HUB_SPEED = 60.0; // °/s
// -------- PID --------
float Kp = 2.2; // <<< NUR P-AKTIV
float Ki = 0.0;
float Kd = 0.0;
float pidIntegral = 0.0;
float lastError = 0.0;
float targetPitch = 0.0;
// -------- FILTER --------
const float ALPHA = 0.90;
float pitch = 0.0;
float gyroOffsetY = 0.0;
unsigned long lastTime = 0;
// ------------------------------------------------
float constrainFloat(float v, float mn, float mx) {
if (v < mn) return mn;
if (v > mx) return mx;
return v;
}
float normalizeAngle(float a) {
while (a > 180.0) a -= 360.0;
while (a < -180.0) a += 360.0;
return a;
}
// ------------------------------------------------
void calibrateGyro() {
long sum = 0;
const int samples = 800;
Serial.println("Gyro-Kalibrierung... ruhig liegen lassen");
for (int i = 0; i < samples; i++) {
int16_t gx, gy, gz;
mpu.getRotation(&gx, &gy, &gz);
sum += gy;
delay(2);
}
gyroOffsetY = sum / (float)samples;
Serial.println("Kalibrierung fertig");
}
// ------------------------------------------------
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println("MPU6050 Fehler!");
while (1);
}
calibrateGyro();
// Startwinkel
int16_t ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
float Ax = ax / 16384.0;
float Ay = ay / 16384.0;
float Az = az / 16384.0;
pitch = atan2(-Ax, sqrt(Ay * Ay + Az * Az)) * 180.0 / PI;
servoA.attach(SERVO_A_PIN);
servoB.attach(SERVO_B_PIN);
servoA.write(SERVO_CENTER);
servoB.write(SERVO_CENTER);
lastTime = micros();
Serial.println("v4.4 gestartet – Kp = 1.0");
}
// ------------------------------------------------
void loop() {
int16_t ax, ay, az, gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
unsigned long now = micros();
float dt = (now - lastTime) / 1e6;
lastTime = now;
// -------- SENSOR --------
float Ax = ax / 16384.0;
float Ay = ay / 16384.0;
float Az = az / 16384.0;
float accPitch = atan2(-Ax, sqrt(Ay * Ay + Az * Az)) * 180.0 / PI;
float gyroPitch = (gy - gyroOffsetY) / 131.0;
pitch = ALPHA * (pitch + gyroPitch * dt) + (1.0 - ALPHA) * accPitch;
pitch = normalizeAngle(pitch);
// -------- PID --------
float error = pitch - targetPitch;
float pidOut = Kp * error;
// -------- HUB --------
float targetHub = constrainFloat(pidOut, -MAX_HUB, MAX_HUB);
// -------- WEICHE BEWEGUNG --------
float maxStep = MAX_HUB_SPEED * dt;
float diff = targetHub - currentHub;
if (fabs(diff) > maxStep) {
currentHub += (diff > 0 ? maxStep : -maxStep);
} else {
currentHub = targetHub;
}
// -------- SERVO OUTPUT --------
float servoPosA = SERVO_CENTER + currentHub;
float servoPosB = SERVO_CENTER - currentHub;
servoPosA = constrainFloat(servoPosA, SERVO_MIN, SERVO_MAX);
servoPosB = constrainFloat(servoPosB, SERVO_MIN, SERVO_MAX);
servoA.write(servoPosA);
servoB.write(servoPosB);
// -------- DEBUG --------
Serial.print("Pitch: ");
Serial.print(pitch, 2);
Serial.print(" Hub: ");
Serial.println(currentHub, 2);
delay(5);
}
schon ganz gut an
das mixen der Achsen damit die oben abgebildete Mechanik funktioniert ist echt fordernd
ich hab mir die Codes aus dem netz zusammengestoppelt sicher ist das eine oder andere überflüssig aber gelernter Programmierer bin ich keiner.
ich werd mal weiter basteln vielleicht komm ich ja ans ziel :)