Hello everyone. I made a simple gimbal by using arduino uno, 3 MG996R servos and MPU6050. Actually everything works fine except the Z axis servo. The X and Y axis servos moves correctly and fine but Z axis servo cannot keep the balance and shakes.
Here’s the code
#include <Wire.h>
#include <MPU6050.h>
#include <Servo.h>
//Kutuphaneleri ekledik
MPU6050 mpu;
Servo servoX;
Servo servoY;
Servo servoZ;
//MPU6050 sensorunu ve uc eksende hareket edecek servo motorları tanimladik
void setup() {
Serial.begin(9600);
Wire.begin();
mpu.initialize();
servoX.attach(9); // X eksenine bağlı servo
servoY.attach(10); // Y eksenine bağlı servo
servoZ.attach(11); // Z eksenine bağlı servo
}
//seri ve I2C haberlesmeyi baslattik, servolarin hangi pinlerde bagli oldugunu tanimladik
void loop() {
int16_t ax, ay, az, gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy,&gz);
//MPU6050 sensorunden gelen ivme(a) ve hiz(g) verilerini aldik
if (isnan(ax) || isnan(ay) || isnan(az) || isnan(gx) || isnan(gy) || isnan(gz)) {
Serial.println("Sensör verileri okunamıyor!");
delay(10);
return;
}
//gelen verilerde okunamayan bir deger varsa ekrana bir hata mesaji gonderdik
float accX = ax / 16384.0;
float accY = ay / 16384.0;
float accZ = az / 16384.0;
float angleX = atan2(accX, sqrt(1 - accX * accX)) * 180.0 / PI;
float angleY = atan2(accY, sqrt(1 - accY * accY)) * 180.0 / PI;
float accZnorm = constrain(accZ, -1.0, 1.0); // Sınırları -1 ile 1 arasında tut
float angleZ = asin(accZnorm) * 180.0 / PI;
//aldigimiz ivme verilerini kullanarak x,y ve z eksenindeki acilari hesapladik
angleX = constrain(angleX, -90, 90);
angleY = constrain(angleY, -90, 90);
angleZ = constrain(angleZ, -90, 90);
//elde ettigimiz acilari servolarin hareket acilari icerisinde sinirladik
int servoPositionX = map(angleX, -90, 90, 0, 180);
int servoPositionY = map(angleY, -90, 90, 0, 180);
int servoPositionZ = map(angleZ, -90, 90, 0, 180);
//hesaplanan aci degerlerini servolarin kabul ettigi aci araliklarinda sinirladik
servoX.write(servoPositionX);
servoY.write(servoPositionY);
servoZ.write(servoPositionZ);
//servo motorlari belirlenen acilara hareket ettirdik
Serial.print("Açı (X): "); Serial.print(angleX);
Serial.print(" | Açı (Y): "); Serial.print(angleY);
Serial.print(" | Açı (Z): "); Serial.print(angleZ);
Serial.print(" | Servo X Pozisyonu: "); Serial.print(servoPositionX);
Serial.print(" | Servo Y Pozisyonu: "); Serial.println(servoPositionY);
Serial.print(" | Servo Z Pozisyonu: "); Serial.println(servoPositionZ);
//kodun ve kurdugumuz sistemin saglikli calisip calismadigini gormek icin sensor verilerini ve motorlarin hareket ettigi acilari serial monitor'e yazdirdik
delay(10); //sensor verilerinin ve motorlarin 10 milisaniyede bir guncellenmesini sagladik
}