Cuadricoptero con arduino (ya esta armado y vuela solo falta la autonivelacion )

hola amigos buenos dias.

he recurido a crearme una cuenta y entrar a este foro porque ando en busca de ayuda y algo desesperado

listo empiezo, he armado un cuadricoctero y ya despega y se mueve en todas las direcciones incluso he logrado hacerlo girar en su propio eje pero solo en superficies lisas donde no requiere despegar. lo he armado con estos elementos
marco dji de 450mm
motores de 920kv
esc de 30a
y una bateria lipo de 5500mah
un arduino uno
un modulo bluetooth hc 06
y un acelerometro gy61 ( tambien poseo el mpu6050)

he visto un tutorial en youtube de un chico que lo esta haciendo y fue de donde saque el codigo base pero este mismo no funcionada solo aceleraba y ya y yo he configurado lo antes mencionado el problema que tengo ahora en este momento es que no puedo activar la autonivelacion lo he configurado con que se active con una letra pero no es nada conveniente ya que la reacción puede ser lenta y a la hora de hundirlo ya puede ser muy tarde, he intentado hacer un contador y que después de u numero determinado de pulsos el se active automáticamente pero tampoco sirvió les presento el código que funciona

aqui les presento el codigo
</>
///////////////////////
///////////////////////
#include <Servo.h> //Incluye la libreria servo para control de los motores Brushless
Servo mot; //Declara estos objetos como Servos
Servo mot2;
Servo mot3;
Servo mot4;

const int pinServo = 9; //Establece los pines para los variadores de velocidad
const int pinServo2 = 10;
const int pinServo3 = 11;
const int pinServo4 = 12;

int angulo = 10; //Variable que controla la velocidad va de 0 a 180
int pulsoMin = 1000; //Pulso minimo y maximo dependiendo del ESC
int pulsoMax = 3000;
int estado; //inicia los motores en 0

//Pines de lectura analogica
const int xPin = 0;
const int yPin = 1;
const int zPin = 2;

//los valores minimo y maximo vienen del
//acelerometro cuando esta quieto
//
int minVal = 333;
int maxVal = 405;
int a = 0;
int angulo2; //Valores para el control individual de cada motor
int angulo3;
int angulo4;
int angulo5;
int i = 0;

//para guardar los valores calculados
double x;
double y;
double z;
double xmax; //Variables para guardar los valores de calibracion
double xmin;
double ymax;
double ymin;
double zmax;
double zmin;

void setup() {
mot.attach(pinServo, pulsoMin, pulsoMax); //Fija las propiedades a cada motor
mot2.attach(pinServo2, pulsoMin, pulsoMax);
mot3.attach(pinServo3, pulsoMin, pulsoMax);
mot4.attach(pinServo4, pulsoMin, pulsoMax);
Serial.begin(9600);
}

void loop() {

//Lee los velores analogicos de el acelerometro
int xRead = analogRead(xPin);
int yRead = analogRead(yPin);
int zRead = analogRead(zPin);

//Convertir los valores leidos a grados -90 to 90 - Nescesario para atan2
int xAng = map(xRead, minVal, maxVal, -90, 90);
int yAng = map(yRead, minVal, maxVal, -90, 90);
int zAng = map(zRead, minVal, maxVal, -90, 90);

//Calcula los valores de 360 grados entonces: atan2(-yAng, -zAng)
//atan2 muestra los valores de -π to π (radianes)
//convierte radianes a grados
x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);

if (a == 0) { //Para guardar los valores de calibracion y que no sean modificados

xmax = x;
xmin = x;
ymax = y;
ymin = y;
zmax = z;
zmin = z;
a = 2;

}
////////////////////////////////////////////////////////////////////////
/////////////////////CONTROL DE ESTABILIZACION//////////////////////////
////////////////////////////////////////////////////////////////////////

if (estado == d) {

if (x == xmax && y == ymax && z == zmax) { //Detecta que el drone esta volando estable
mot.write(angulo);
mot2.write(angulo);
mot3.write(angulo);
mot4.write(angulo);
}
if (x == xmax && y == ymax && z == zmax) { //Detecta que el drone esta volando estable
mot.write(angulo);
mot2.write(angulo);
mot3.write(angulo);
mot4.write(angulo);
}

if (y < ymin && z > zmax ) { //Detecta y corrige una inclinacion hacia mot4
angulo2 = angulo;
angulo2 += 5;
mot4.write(angulo2);

}
if (x < xmax && y < ymin && z < zmin) { //Detecta y corrige una inclinacion hacia mot3
angulo3 = angulo;
angulo3 += 5;
mot3.write(angulo3);

}
if (x > xmin && y > ymax && z > zmax) { //Detecta y corrige una inclinacion hacia mot2
angulo4 = angulo;
angulo4 += 5;
mot2.write(angulo4);

}
if ( y > ymax && z < zmin) { //Detecta y corrige una inclinacion hacia mot2
angulo5 = angulo;
angulo5 += 5;
mot.write(angulo5);

}
}

if (Serial.available() > 0) {

estado = Serial.read();
//Lee los valores que le mandamos por bluetooth

////////////////////////////////////////////////////////////////////////
////////////////////////CONTROL DEL MOVIMIENTO//////////////////////////
////////////////////////////////////////////////////////////////////////
if (estado == ‘a’) { //Aumenta la velocidad de los motores
angulo += 10;
mot.write(angulo);
mot2.write(angulo);
mot3.write(angulo);
mot4.write(angulo);
}

if (estado == ‘b’) { //Detiene los motores

angulo = 0;
mot.write(angulo);
mot2.write(angulo);
mot3.write(angulo);
mot4.write(angulo);

}

if (estado == ‘c’ && angulo > 0) { //Disminuye la velocidad de los motores
angulo -= 10;
mot.write(angulo);
mot2.write(angulo);
mot3.write(angulo);
mot4.write(angulo);

}
/* if (estado == ‘d’) { //giro sobre tu propio eje a la izquierda
angulo4 = angulo;
angulo3 = angulo;
angulo4 += 5;
angulo3 += 5;
mot2.write(angulo4);
mot3.write(angulo3);
delay(500);

}
"if (estado == ‘e’) { //giro sobre tu propio eje a la derecha
angulo2 = angulo;
angulo5 = angulo;
angulo2 += 5;
angulo5 += 5;
mot.write(angulo2);
mot4.write(angulo5);
delay(500);
}
*/

if (estado == ‘f’) { //reversa
angulo3 = angulo;
angulo2 = angulo;
angulo3 += 5;
angulo2 += 5;
mot.write(angulo3);
mot2.write(angulo2);
delay(500);

}
if (estado == ‘h’) { //hacia el frente
angulo5 = angulo;
angulo4 = angulo;
angulo5 += 5;
angulo4 += 5;
mot3.write(angulo5);
mot4.write(angulo4);
delay(500);

}
if (estado == ‘i’) { //ladeo izquierdo
angulo2 = angulo;
angulo4 = angulo;
angulo4 += 5;
angulo2 += 5;
mot.write(angulo2);
mot3.write(angulo4);
delay(500);

}
if (estado == ‘j’) { //ladeo derecho
angulo5 = angulo;
angulo3 = angulo;
angulo5 += 5;
angulo3 += 5;
mot2.write(angulo3);
mot4.write(angulo5);
delay(500);

}

estado = ‘z’; //Para no trabar el ESC

}
</>

no se como configurar la autonivelacion para que inicie en u momento detemrinado ya que en 90° el dron ya despega he querido colocar esa condicion pero no se efectua eficientemente, tambien intente dejar la autonivelacion libre sin condiciones pero me generaba un error los motores arrancaban apenas le daba voltaje al sistema y lo hacian a destiempo y sobre todo arrancaban cuando querian jajaj y ha destiempo incluso sin haber emparejado con el modulo mi pregunta es la siguiente se podra lograr lo que deseo con este modulo o tendre que usar el mpu6050 he intentado utilizar este ya mencionado y la lectura de datos no se efectua correctamente podria adartar las funciones para autonivelacion pero no se como leer los datos correctamente, muchas gracias por su tiempo.

Hola SiulTemplario

Antes de comenzar quiero pedirte que por favor leas las normas del foro ya que tu código está mal pegado en tu mensaje.
Luego de leer las normas, por favor, edítalo.

Luego de esto, quiero contarte que el foro de Arduino no es el mejor lugar para preguntar por algo que tiene más relación con el aeromodelismo, pero tienes suerte, habemos algunas personas (en este foro) que tuvimos nuestra experiencia al respecto. En mi caso soy aeromodelista.

Por lo que expresas entiendo que lo estarías controlando con el movil o una tablet usando Bluetooth, eso es un crimen, y más para un 450. :smiley: :smiley: :smiley:

Pasemos a los sensores que le instalaste:
Dices que tienes un acelerómetro y no comentas más nada. Ese es el único sensor que tienes? Si es el único tenemos un problema porque te faltan por lo menos 3 sensores, giróscopo, brújula y barómetro. Mi primer cuadri también fue con Arduino y lo volé sólo dos veces, luego le puse una Naze32 de 10DOF (10 dots of freedom o 10 puntos de libertad). Yo ya tenía emisora y receptor de Radio Control antes de armarlo. Pero sigamos con tu tema.

Yo te aconsejo conseguir, por lo menos, un mando de consola WII que tiene algunos de esos sensores o directamente comprar una plaquita GY-80.

Blog de Patagonia Technology donde comentan el GY-80

Si no recuerdo mal, esa plaquita la conecté a los conectores I2C de la Arduino. Pero cuidado, porque requiere de 3,3V para trabajar, si la conectamos a la Arduino directamente la podemos quemar.

En cuanto al software para hacer funcionar todo esto, te recomiendo usar el de Multiwii.

Entrada a mi blog donde habla de Multiwii y como conseguir su firmware para Arduino.

Tienes que aprender un poco más, porque usando Bluetooth, sólo tienes unos pocos metros de alcance, sin embargo, usando una radio para tal fin, tienes algunos cientos de metros de alcance, entre 100 y 200, por lo menos.

Esta es la radio más económica, yo tengo una de esas y me acompaña hace algunos años, tengo otras más, pero no viene al caso.

Esta es la mía, pero ambas son la misma emisora del mismo fabricante, con distintas marcas. Todas las radios vienen con su respectivo receptor para poner, en tu caso, en el cuadricóptero.

Y por último, mientras escribía esto, encontré como conectar los mandos de una WII NUNCHUK, igualmente, si tienes que comprar el mando de la WII, te sale más económico usar una GY-80.

Saludos y espero tus comentarios!

Hola muchas gracias por responder lo siento por lo de no saber cómo postear mi código t segundo me acaba de llegar el sensor mpu6050 el que tiene acelerómetro y giroscopio sé que ese sensor es algo difícil de controlar sé que hay que colocar un filtro complementario y no sé cómo hacerlo, ahora último pude flasear el multiwii en la placa Arduino uno con el sensor mpu6050 pero no logro manejarlo con el celular.
Ya me pedí un control pero demorará unas semanas y quisiera poner a volar a este muchacho así sean unos metros.
Muchas gracias y espero puedas orientarme en lo que puedas.