Variables entre les boucles

Bonjour!

J'ai aujourd'hui un petit problème avec les boucles, les variables ne peuvent pas "voyager" entre ces dernières.
Voici mon code (une petite partie, pour simplifier):

 void loop () { 
lcd.setCursor(5,1);
lcd.print(pitch_error); }

void PIDcorrection() {

  pitch_error = gx - desired_angle;
}

J'initialise pour l'instant la variable desired_angle à 0, mais elle sera changée en fonction de l'inclinaison du joystick.

J'ai remarqué que quand je n'utilise pas la boucle PIDcorrection et que je fais simplement

 lcd.setCursor(5,1);
lcd.print(gx - 0);

Ca marche (logique) mais pas avec la variable. On dirait qu'elle ne "survit" pas entre les void.

Merci, et désolé du dérangement pour un problème aussi basique :slight_smile:

Si tu ne dis pas où sont sont déclarées les variables, difficile de dire quoi que ce soit.

Bon, déjà, je suis sûr que votre bout de code, tel qu'il est, ne peut pas se compiler... parce que nulle part vous ne définissez les variables.
est ce que pitch-error , et surtout gx et desired_angle sont des variables globales (c'est la façon la plus simple d'ibtenir qu'elles ne soient pas écrasées)?

Bonjour, désolé

Voici mes déclarations de variables:

 float gx
float pitch_error
int desired_angle = 0;

Pour lire la valeur du gyroscope (gx) je fais:

 gx= (-(Buf[2]<<8 | Buf[3])) / 131.0;
gx = constrain(gx, -63.0, 63.0);
gx = (gx*90.0)/63.0;

J'ai aussi un petit problème pour mes angles de gyro en x et y.

Ca fonctionne très bien, sauf que j'aimerais que, passé les 90°, ça se "bloque" comme si le gyro pouvait nous donner des valeurs max de 90°, sauf que quand je dépasse cette dernière valeur, les valeurs redescendent jusqu'à 0. Donc impossible de faire un constrain ou autre

Dans l'état, personne ne peut imaginer si vos variables sont globales ou locales à une fonction: pour l'amour du grand Spaghetti Volant, copiez le code depuis le début du sketch -si j'ose dire- jusqu'à la foncrion incriminée....

quant au comportement après 90
vous pouvez revenir à zero par un modulo ex 95 devient 5; 120 devient 30
vous pouvez "trinquer" ex: 95 devient 90, 120 devient 90 aussi...
vous pouvez doner quelques valeurs pour qu'in essaye une formule....

dbrion06:
Dans l'état, personne ne peut imaginer si vos variables sont globales ou locales à une fonction: pour l'amour du grand Spaghetti Volant, copiez le code depuis le début du sketch -si j'ose dire- jusqu'à la foncrion incriminée....

quant au comportement après 90
vous pouvez revenir à zero par un modulo ex 95 devient 5; 120 devient 30
vous pouvez "trinquer" ex: 95 devient 90, 120 devient 90 aussi...
vous pouvez doner quelques valeurs pour qu'in essaye une formule....

Je ne suis pas sur mon Pc là, mais les variables sont globales étant donné qu'elle sont déclarées avant le setup

Je ne comprends pas bien votre idée de modulo, en quoi cela ferait la différence entre un angle "normal" et un angle au dessus de 90° vu que la donnee de sortie est la même ?

95%90 = 5 (reste de la division) pour le modulo
ceil(x,90) == 90 si x>=90 (plafonnement) == x sinon.

Que voulez vous faire comme traitement? Donnez des valeurs et le résultat attendu....

Edited Une autre cause classique (mais ça reste de la speculation) de "perte" de variables est un débordement de tableaux....

Voici mon code complet:

 #include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#define MPU9250_ADDRESS 0x68
 
#define GYRO_FULL_SCALE_1000_DPS 0x10
 
#define ACC_FULL_SCALE_4_G 0x08

byte valMotA, valMotB, valMotC, valMotD;

float elapsedTime, time, timePrev;

float PID, error, previous_error;
float gx, gy, gz, ax, ay, az;

///////////////////////////////ROLL PID CONSTANTS////////////////////
float roll_PID, roll_error, roll_previous_error;
double roll_kp=3.55;//3.55
double roll_ki=0.003;//0.003
double roll_kd=2.05;

///////////////////////////////PITCH PID CONSTANTS///////////////////
float pitch_PID, pitch_error, pitch_previous_error;
double pitch_kp=3.55;
double pitch_ki=0.003;
double pitch_kd=2.05;

int desired_angle = 0;

//////////////////////////////PID FOR ROLL///////////////////////////
float roll_pid_p=0; // Ces valeurs dépendent des constantes du PID. On les initialisent à 0
float roll_pid_i=0;
float roll_pid_d=0;

//////////////////////////////PID FOR PITCH//////////////////////////
float pitch_pid_p=0;
float pitch_pid_i=0;
float pitch_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

valMotA = 90;
valMotB = 90;
valMotC = 90;
valMotD = 90;
}
 
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);
 
// 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;
gz= (Buf[4]<<8 | Buf[5]) / 131.0;

// Accelerometer
ax= (-(Buf[8]<<8 | Buf[9])) / 16384.0;
ay= (-(Buf[10]<<8 | Buf[11])) / 16384.0;
az= (Buf[12]<<8 | Buf[13]) / 16384.0;

gx = constrain(gx, -63.0, 63.0);
gy = constrain(gy, -63.0, 63.0);
gz = constrain(gz, -63.0, 63.0);

gx = (gx*90.0)/63.0;
gy = (gy*90.0)/63.0;
gz = (gz*90.0)/63.0;

// Gyroscope
Serial.print (gx); 
Serial.print ("   ");
Serial.print (gy);
Serial.print ("   ");
Serial.print (gy);
Serial.print ("    |    ");

// Accelerometer
Serial.print (ax); 
Serial.print ("   ");
Serial.print (ay);
Serial.print ("   ");
Serial.print (az); 
Serial.println ("    |    ");

lcd.setCursor(0,0);
lcd.print(valMotA);
lcd.setCursor(5,0);
lcd.print(valMotB);
lcd.setCursor(10,0);
lcd.print(valMotC);
lcd.setCursor(15,0);
lcd.print(valMotD);

lcd.setCursor(5,1);
lcd.print(pitch_error);


delay(100); 

}

void PIDcorrection() {

  pitch_error = gx - desired_angle;
  roll_error = gy - 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);  
  }
  if(-3 <roll_error <3)
  {
    roll_pid_i = roll_pid_i+(roll_ki*roll_error);  
  }

  //----------D---------//  
  pitch_pid_d = pitch_kd*((pitch_error - previous_error)/elapsedTime);
  roll_pid_d = roll_kd*((roll_error - 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 = valMotA + roll_PID - pitch_PID; //CW
  valMotB = valMotB - roll_PID - pitch_PID; //CCW
  valMotC = valMotC + roll_PID + pitch_PID; //CW
  valMotD = valMotD - roll_PID + pitch_PID; //CCW

  roll_previous_error = roll_error; //La boucle est finie, on peut incrémenter
  pitch_previous_error = pitch_error;
  
}

Voici mes valeurs de gx mesurées:

 -0.91
-0.62
-1.78
-0.31
0.08
-0.45
1.21
-1.82
1.45
2.06
10.25
15.94
26.73
39.66
47.68
55.04
60.98
69.56
74.11
78.85
82.53
85.28
87.63
89.56
89.84
90.00
89.30
87.50
86.04
88.10
85.81
83.12
80.82
76.12
75.25
73.10
69.06
67.64
62.14
59.42
57.46
56.01
54.37
51.83
48.87
48.91
45.25
43.94
41.24
40.34
37.22
36.01
34.89
32.80
31.25
30.88
29.66
28.97
26.38
25.83
23.47
20.82
18.83
17.57
15.34
13.03
12.18
11.43

J'ai simplement effectué une rotation sur l'axe x du gyroscope à 180°

Normalement, je reçois une valeur qui plafonne à 90° étant donné que "j'augmente" la valeur en x à chaques fois.

Si j'avais fait une rotation à 90° dans le même sens puis une de 90° dans le sens inverse, j'avais le même résultat.

Je viens de comprendre pourquoi ça marche pas !
Tout bêtement, je n'ai pas appelé le vois en faisant
PIDcorrection();

Je m'empresse de tester ça