Hi, i'm having troubles with a school project and I'm pretty amateur with programming and electronics.
Basically, I'm developing the control system for an experimental aircraft, and I need to control it's response to the pitch movement moving the elevator with a Servo.
Until now the servo isn't moving and I've tried changing the baud values, pins and if/else logic.
This is the code so far:
Here is a short program that will give you meaningful pitch and roll angles from the MPU-6050, corresponding to one of the standard conventions. What you posted (found in lots of places on the web), is just plain wrong.
// minimal MPU-6050 tilt and roll (sjr). Works with MPU-9250 too.
// works perfectly with GY-521, pitch and roll signs agree with arrows on sensor module 7/2019
//
// Tested with 3.3V eBay Pro Mini with no external pullups on I2C bus (worked with internal pullups)
// Add 4.7K pullup resistors to 3.3V if required. A4 = SDA, A5 = SCL
#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;
void setup() {
Wire.begin(); //begin the wire communication
Wire.beginTransmission(MPU_addr1); //begin, send the slave adress (in this case 68)
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0);
Wire.endTransmission(true); //end the transmission
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(MPU_addr1);
Wire.write(0x3B); //send starting register address, accelerometer high byte
Wire.endTransmission(false); //restart for read
Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
int t = Wire.read();
xa = (t << 8) | Wire.read();
t = Wire.read();
ya = (t << 8) | Wire.read();
t = Wire.read();
za = (t << 8) | Wire.read();
// formula from https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
roll = atan2(ya , za) * 180.0 / PI;
pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied
Serial.print("roll = ");
Serial.print(roll,1);
Serial.print(", pitch = ");
Serial.println(pitch,1);
delay(400);
}
This is part of my thesis, I wasn't suppose to get involved in this part of the job in the first place but my proffesor leave me in the dust with this one and I have to come up with a solution anyway I can. I know I shouldt be involved with this one but it led me here. And no, it can't hurt anyone.
I'm testing with the Arduino UNO, when it's all done im doing it in a Pro Mini.
Conections WERE like this:
IMU to Arduino
VCC--------5 v
SCL--------A5
SDA-------A4
GND------GND
But it turns out I't didn't work with the test so I had to connect ADO-------GND
I'll make sure to print the PWM values to see if they make sense.
I've been testing with other programs to see if it's working and so far it does with this configuration.
example 1:
#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, pitch;
void setup() {
Wire.begin(); //begin the wire communication
Wire.beginTransmission(MPU_addr1); //begin, send the slave adress (in this case 68)
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0);
Wire.endTransmission(true); //end the transmission
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(MPU_addr1);
Wire.write(0x3B); //send starting register address, accelerometer high byte
Wire.endTransmission(false); //restart for read
Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
int t = Wire.read();
ya = (t << 8) | Wire.read();
t = Wire.read();
xa = (t << 8) | Wire.read();
t = Wire.read();
za = (t << 8) | Wire.read();
pitch = atan2(xa , sqrt(xa * xa + za * za)) * 180.0 / PI; //account for roll already applied
Serial.print("pitch angle = ");
Serial.println(pitch,1);
delay(500);
}
example 2:
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Servo.h>
Adafruit_MPU6050 mpu;
int x = 0;
int y = 0;
int z = 0;
Servo servo1;
int value = 0;
void setup(void) {
Serial.begin(9600);
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
// set accelerometer range to +-8G
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
// set gyro range to +- 500 deg/s
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
// set filter bandwidth to 21 Hz
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
delay(100);
servo1.attach(7);
servo1.write(0);
}
void loop() {
/* Get new sensor events with the readings */
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
x = a.acceleration.x;
y = a.acceleration.y;
z = a.acceleration.z;
//Serial.print(x);Serial.print(" ");Serial.println(y);
if (x < 10 && x > 0 && y < 4 && y > -4){
Serial.println("up");
value = map(x, 0, 10, 0, 180);
servo1.write(value);
Serial.print(value);
}
}
It is unlikely to work well, if at all and you can damage the Arduino just by trying. Use a separate power supply, for example 4xAA will work for one small servo.