I'm just trying to understand the problem and the only point that regards the output of the engines is the writeMicroseconds (). I repeat with the radio signal the problem was given by the pulseIn () function too slow for the purpose.
I attach below the function that writes the pwm values
void pid(Servo mt[],float desired_angle[],float error[],float Total_angle[],float p[],float i[],float d[],float previous_error[],float elapsedTime,float PID[],float speedVec[],volatile int radioChannelCommands[]){
int yawValue;
//controllo che i valori pwm dei canali siano entro l'intervallo [1000;2000]
for(int i=0;i<4;i++){
if(radioChannelCommands < 1000)
_ radioChannelCommands = 1000;_
_ if(radioChannelCommands > 2000)
radioChannelCommands = 2000;
* }
//dopo aver normalizzato i valori mappo i comandi di roll e pitch ai rispettivi angoli della modalità stabilized*_
* desired_angle[0] = map(radioChannelCommands[0],1000,2000,45,-45);
desired_angle[1] = map(radioChannelCommands[1],1000,2000,45,-45);
//Serial.println("Angoli desiderati --> " + String(desired_angle[0]) + " " + String(desired_angle[1]));
error[0] = Total_angle[0] - desired_angle[0]; //calcolo l'errore tra l'angolo desiderato e quello misurato effettivamente
error[1] = Total_angle[1] - desired_angle[1]; //calcolo l'errore tra l'angolo desiderato e quello misurato effettivamente*
* Serial.println("Errori --> " + String(error[0]) + " " + String(error[1]));*
* //Applico il valore proporzionale dei PID*
_ p[0] = kperror[0];
p[1] = kperror[1];
* //L'integrale come spiegato nella documentazione agisce solo in un intorno relativamente stretto allo zero. Io ho scelto da [-2 ; +2]. Essendo l'inverso dell'azione derivativa esso ne smorza il comportamento*
* if(-3 < error[1] <3){
i[1] = i[1] + (kierror[1]);
* }
if(-3 < error[0] <3){
i[0] = i[0] + (kierror[0]);
* }
//La derivata, o componente derivativa, agisce sulla velocità di convergenza dell'errore*
d[0] = kd*((error[0] - previous_error[0])/elapsedTime);
d[1] = kd*((error[1] - previous_error[1])/elapsedTime);
* //Il PID finale è la somma delle tre componenti calcolate*
* PID[0] = p[0] + i[0] + d[0];
PID[1] = p[1] + i[1] + d[1];
//Serial.println("I PID per i due assi --> " + String(PID[0]) + " " + String(PID[1]));
/ Il PID agisce in un intervallo massimo che va da -1000 microsecondi a +1000 microsecondi. Matematicamente [-1000;+1000].
* Dato che comunque è praticamente impossibile che esso debba agire su tutta la scala, ovvero portare i valori da 2000 a 1000_
_ * e viceversa ci limitiamo a farlo lavorare in un intervallo [-600;+600] che è più che sufficiente a bilanciare i sistema e_
_ * alleggerisce il runtime*/
* if(PID[1] < -600){PID[1]=-600;}
if(PID[1] > 600) {PID[1]=600; }
if(PID[0] < -600){PID[0]=-600;}
if(PID[0] > 600) {PID[0]=600;}
if(radioChannelCommands[3] > 1510){
yawValue = map(radioChannelCommands[3],1500,2000,0,150); //ho scelto che la differenza massima tra i motori sulle diagonali durante la manovra sia al massimo 200*
speedVec[0] = /115 +/ radioChannelCommands[2] - PID[1] + PID[0] - yawValue;
speedVec[1] = /115 +/ radioChannelCommands[2] - PID[1] - PID[0] + yawValue;
speedVec[2] = /115 +/ radioChannelCommands[2] + PID[1] + PID[0] + yawValue;
speedVec[3] = /115 +/ radioChannelCommands[2] + PID[1] - PID[0] - yawValue;
* }
else if(radioChannelCommands[3] < 1490){
yawValue = map(radioChannelCommands[3],1500,2000,50,150); //ho scelto che la differenza massima tra i motori sulle diagonali durante la manovra sia al massimo 200*
speedVec[0] = /115 +/ radioChannelCommands[2] - PID[1] + PID[0] + yawValue;
speedVec[1] = /115 +/ radioChannelCommands[2] - PID[1] - PID[0] - yawValue;
speedVec[2] = /115 +/ radioChannelCommands[2] + PID[1] + PID[0] - yawValue;
speedVec[3] = /115 +/ radioChannelCommands[2] + PID[1] - PID[0] + yawValue;
* }
else{
speedVec[0] = /115 +/ radioChannelCommands[2] - PID[1] + PID[0];
speedVec[1] = /115 +/ radioChannelCommands[2] - PID[1] - PID[0];
speedVec[2] = /115 +/ radioChannelCommands[2] + PID[1] + PID[0];
speedVec[3] = /115 +/ radioChannelCommands[2] + PID[1] - PID[0];
}
//Questo controllo è fondamentale per evitare che qualcuno possa settare regimi minimi pericolosi in grado di arrecare gravi danni a persone o cose*
* if(MIN_RPM >= 1000 && MIN_RPM <= 1150 ){
if(speedVec[0] < MIN_RPM){ speedVec[0] = MIN_RPM; }*
* if(speedVec[0] > 2000){ speedVec[0] = 2000; }_
if(speedVec[1] < MIN_RPM){ speedVec[1] = MIN_RPM; }
_ if(speedVec[1] > 2000){ speedVec[1] = 2000; }_
if(speedVec[2] < MIN_RPM){ speedVec[2] = MIN_RPM; }
_ if(speedVec[2] > 2000){ speedVec[2] = 2000; }_
if(speedVec[3] < MIN_RPM){ speedVec[3] = MIN_RPM; }
_ if(speedVec[3] > 2000){ speedVec[3] = 2000; }
}else{
if(speedVec[0] < 1050){ speedVec[0] = 1050; }
if(speedVec[0] > 2000){ speedVec[0] = 2000; }
if(speedVec[1] < 1050){ speedVec[1] = 1050; }
if(speedVec[1] > 2000){ speedVec[1] = 2000; }
if(speedVec[2] < 1050){ speedVec[2] = 1050; }
if(speedVec[2] > 2000){ speedVec[2] = 2000; }
if(speedVec[3] < 1050){ speedVec[3] = 1050; }
if(speedVec[3] > 2000){ speedVec[3] = 2000; }
}
//Serial.println("i valori dei pid sui 4 motori --> " + String(speedVec[0]) + " " + String(speedVec[1]) + " " + String(speedVec[2]) + " " + String(speedVec[3]));
// delay(4000);
//dopo aver filtrato tutti i valori tramite PID e verificata la loro validità nella scala PWM [1000;2000] posso scrivere i 4 valori sui motori*
* mt[0].writeMicroseconds(speedVec[0]);
mt[1].writeMicroseconds(speedVec[1]);
mt[2].writeMicroseconds(speedVec[2]);
mt[3].writeMicroseconds(speedVec[3]);*_
* previous_error[0] = error[0]; //pitch error diventa pitch previous error.
previous_error[1] = error[1]; //roll error diventa roll previous error.
_ //delay(3000);
}*_