Bonsoir, oui encore moi
Je suis encore sur mon projet de drone, et ce dernier ne veut pas décoller.
J'ai mené plusieurs tests sur 2 jours, et j'ai jamais réussi à faire décoller les 4 pieds de mon quadcoptère.
Voici mon matos
ESC :https://fr.aliexpress.com/item/32252435180.html
Je suis sûr à 200% que mes moteurs sont bien montés et tournent dans la bonne direction.
Pour les hélices, pareil elles sont dans le bon sens. Pour preuve, on peut voir sur ma vidéo que l'herbe se "déplace".
Pour le gyro, pareil, ça marche vu que lorsque j'incline plus ou moins mon drone sur tous les côtés, les moteurs tournent aussi plus ou moins vites.
Comme vous pouvez le voir sur la vidéo, mon drone part systématiquement en avant.
Peut importe son angle de début, car quand je mets mon drone un peu en avant il part en avant au décollage, et pareil en arrière ... (pareil quand il est relativement droit)
Pour ce qui est du poids, je suis aux alentours des 800g. Les moteurs devraient donc être capables de soulever le drone, et facilement à plein régime.
J'utilise un module MPU9250 mais pour l'instant que le gyroscope sur les deux axes X et Y (ça suffit pour le moment).
Sans stabilisation, pareil, le drone part en avant. Je pense plutôt alors à un problème de hardware ...
Quoi qu'il en soit, voici mon code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
Servo motA, motB, motC, motD;
int valMotA, valMotB, valMotC, valMotD;
#define MPU9250_ADDRESS 0x68
#define GYRO_FULL_SCALE_1000_DPS 0x10
#define ACC_FULL_SCALE_4_G 0x08
float elapsedTime, time, timePrev;
float gx, gy; // Angles en x et en y
int throttle; // Variable des gazs (Joystick gauche)
///////////////////////////////PITCH PID CONSTANTS///////////////////
float pitch_PID, pitch_error, pitch_previous_error;
double pitch_kp=0.5; //0.5
double pitch_ki=0.003;
double pitch_kd=0.1;
///////////////////////////////ROLL PID CONSTANTS////////////////////
float roll_PID, roll_error, roll_previous_error;
double roll_kp=0.4;//3.55
double roll_ki=0.001;//0.003
double roll_kd=0.1;
int pitch_desired_angle = 0;
int roll_desired_angle = 0;
//////////////////////////////PID FOR PITCH//////////////////////////
float pitch_pid_p=0; // Ces valeurs dépendent des constantes du PID. On les initialisent à 0
float pitch_pid_i=0;
float pitch_pid_d=0;
//////////////////////////////PID FOR ROLL///////////////////////////
float roll_pid_p=0;
float roll_pid_i=0;
float roll_pid_d=0;
// This function read Nbytes bytes from I2C device at address Address.
// Put read bytes starting at register Register in the Data array.
void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
{
// Set register address
Wire.beginTransmission(Address);
Wire.write(Register);
Wire.endTransmission();
// Read Nbytes
Wire.requestFrom(Address, Nbytes);
uint8_t index=0;
while (Wire.available())
Data[index++]=Wire.read();
}
// Write a byte (Data) in device (Address) at register (Register)
void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
{
// Set register address
Wire.beginTransmission(Address);
Wire.write(Register);
Wire.write(Data);
Wire.endTransmission();
}
void setup()
{
Wire.begin();
Serial.begin(115200);
lcd.init();
lcd.backlight();
I2CwriteByte(MPU9250_ADDRESS,29,0x06); // Set accelerometers low pass filter at 5Hz
I2CwriteByte(MPU9250_ADDRESS,26,0x06); // Set gyroscope low pass filter at 5Hz
I2CwriteByte(MPU9250_ADDRESS,27,GYRO_FULL_SCALE_1000_DPS); // Configure gyroscope range
I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_4_G); // Configure accelerometers range
I2CwriteByte(MPU9250_ADDRESS,0x37,0x02); // Set by pass mode for the magnetometer
motA.attach(4, 1000, 2000);
motB.attach(5, 1000, 2000);
motC.attach(6, 1000, 2000);
motD.attach(7, 1000, 2000);
}
void loop()
{
// ____________________________________
// ::: accelerometer and gyroscope :::
timePrev = time;
time = millis();
elapsedTime = (time - timePrev) / 1000;
// Read accelerometer and gyroscope
uint8_t Buf[14];
I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);
throttle = map(analogRead(A1), 0, 1023, 0, 180);
// Create 16 bits values from 8 bits data
// Gyroscope
gx= (-(Buf[2]<<8 | Buf[3])) / 131.0;
gy= (-(Buf[0]<<8 | Buf[1])) / 131.0;
gx = constrain(gx, -63.0, 63.0);
gy = constrain(gy, -63.0, 63.0);
gx = (gx*90.0)/63.0; // Mise sous forme de degrés (de -90 à 90°), car le drone n'ira pas au dessus de 75°
gy = (gy*90.0)/63.0;
valMotA = map(valMotA, 1000, 2000, 0, 180);
valMotB = map(valMotB, 1000, 2000, 0, 180);
valMotC = map(valMotC, 1000, 2000, 0, 180);
valMotD = map(valMotD, 1000, 2000, 0, 180);
if (throttle >= 20) {
PIDcorrection();
}
else {
valMotA = throttle;
valMotB = throttle;
valMotC = throttle;
valMotD = throttle;
}
lcd.setCursor(2,0);
lcd.print(valMotA);
lcd.setCursor(7,1);
lcd.print("A");
lcd.setCursor(8,2);
lcd.print(">");
lcd.setCursor(15,0);
lcd.print(valMotB);
lcd.setCursor(9,2);
lcd.print("<");
lcd.setCursor(10,1);
lcd.print("B");
lcd.setCursor(2,3);
lcd.print(valMotC);
lcd.setCursor(7,3);
lcd.print("C");
lcd.setCursor(15,3);
lcd.print(valMotD);
lcd.setCursor(10,3);
lcd.print("D");
motA.write(valMotA);
motB.write(valMotB);
motC.write(valMotC);
motD.write(valMotD);
delay(50);
lcd.clear();
}
void PIDcorrection() {
pitch_error = gx - pitch_desired_angle;
roll_error = gy - roll_desired_angle;
//----------P---------//
pitch_pid_p = pitch_kp*pitch_error;
roll_pid_p = roll_kp*roll_error;
//----------I---------//
if(-3 <pitch_error <3)
{
pitch_pid_i = pitch_pid_i+(pitch_ki*pitch_error); //El famoso technique des rectangles ^^
}
if(-3 <roll_error <3)
{
roll_pid_i = roll_pid_i+(roll_ki*roll_error);
}
//----------D---------//
pitch_pid_d = pitch_kd*((pitch_error - pitch_previous_error)/elapsedTime); // On divise l'erreur passée par un temps pour avoir une mesure en degrés/secondes
roll_pid_d = roll_kd*((roll_error - roll_previous_error)/elapsedTime);
//---------PID--------//
pitch_PID = pitch_pid_p + pitch_pid_i + pitch_pid_d;
roll_PID = roll_pid_p + roll_pid_i + roll_pid_d;
valMotA = throttle - roll_PID + pitch_PID; //CW
valMotB = throttle + roll_PID + pitch_PID; //CCW
valMotC = throttle - roll_PID - pitch_PID; //CCW
valMotD = throttle + roll_PID - pitch_PID; //CW
roll_previous_error = roll_error; //La boucle est finie, on peut incrémenter
pitch_previous_error = pitch_error;
Serial.print(gx);
Serial.print(" | ");
Serial.println(gy);
if (valMotA > 180) {
valMotA = 180;
}
if (valMotB > 180) {
valMotB = 180;
}
if (valMotC > 180) {
valMotC = 180;
}
if (valMotD > 180) {
valMotD = 180;
}
if (valMotA < 0) {
valMotA = 0;
}
if (valMotB < 0) {
valMotB = 0;
}
if (valMotC < 0) {
valMotC = 0;
}
if (valMotD < 0) {
valMotD = 0;
}
}
Merci encore !
Très bonne soirée à vous