Catégories
Algorithme Arduino Asservissement Asservissement Arduino automatique Projets Arduino Projets électroniques

Projet Arduino: La Commande Incrémentale – Version 2 [TUTO]

Objectifs

  1. Savoir implémenter une boucle de régulation
  2. Savoir le principe de la Commande Incrémentale
  3. Savoir implémenter une moyenne glissante
  4. Savoir asservir un signal PWM

Applications

  1.  Asservissement de la vitesse
  2. Systèmes de régulation automatique
  3. Convertisseurs AC/DC, DC/AC, DC/DC, etc. Asservis
  4. Asservissement de la température, humidité, etc.
  5. Et, d’autres applications !

Principe de fonctionnement

schémas Commande incrémentale - version améliorée - V2

Nous avons abordé dans la V1 le concept et comment implémenter une commande incrémentale avec Arduino. Le point  fort d’une commande incrémentale est sa convergence assurée vers la consigne Quelle que soit la charge avec une erreur statique nulle. C’est une commande générique contrairement aux stratégies d’asservissement traditionnelles par correcteurs (P, PI, PID, etc.). En revanche, le temps de réponse est un peu long. La version actuelle permet d’améliorer la stabilité de la commande (réduction des ondulations autour de la consigne) et réduire le temps de réponse. Les améliorations, on était apportés en particulier au filtre moyenneur. L’idée consiste à garder en mémoire les valeurs moyennes calculées (les moyennes précédentes). La valeur filtrée actuelle sera donc la somme des valeurs moyennes précédentes et la valeur actuelle du port A0. Le reste du programme reste le même comme celui de la V1.

Voir la version #1 concernant  le fonctionnement.

Voir le tuto pour plus de détails techniques.

Programme complet

#define Out         9       
#define In A0
#define Consigne 2.5 // Tension de la consigne
#define N 150 // Moyenne: valeur initiale (setup)
#define NMoy 100 // Moyenne glissante (loop)
#define Epsilon 1E-3 // Epsilon
#define StepCyc 1E-2 // Pas d'incrémentation du Rapport Cyclique / Cycle


float v_fil=0.0;
float v_fil_old=0.0;
bool LoopCyc=false;
float somme =0.0;
float vin_volat=0.0;
float valMoy[NMoy];
int Vin_A0=0;
int I=0;
float OutPWM=0; //Consigne*255.0/5.0;


void setup()
{
// Pinout
pinMode(Out, OUTPUT);
analogWrite(Out, 180);

// Calcul de la moyenne actuelle
for (int i=0; i<N; i++)
{
vin_volat=(float)analogRead(A0)*5.0/1023.0;
somme+=vin_volat;
}
v_fil=(somme/(float)N);
somme=0.0;

// Initialisation du tableau des VM
for (int i=0; i<NMoy; i++) valMoy[i]= v_fil;

// Affichage
Serial.begin(115200);
}

void loop()
{

// 1. Lecture de l'entrée A0
vin_volat=(float)analogRead(A0)*5.0/1023.0;

// 2. Filtrage: Calcul de la Moyenne Glissante
for (int i=0; i<NMoy; i++) somme+=valMoy[i];
v_fil=(somme/(float)NMoy);
somme=0.0;

// 3. Mise à jour du tableau des VM
valMoy[I]=(v_fil+vin_volat)/2.0;
I++; I%=NMoy;

/*4. Mise à jour de la commande */
// 4.1: Consigne Atteinte
if (((v_fil>=Consigne -1.5*Epsilon) && (v_fil<=Consigne +1.5*Epsilon)))
{
return; // Ne rien faire!
}

// 4.2: Incrémentation
if ((v_fil<Consigne))
{
OutPWM+=StepCyc;
if (OutPWM>=255.0) OutPWM-=StepCyc;
}

// 4.3: Décrémentation
if ( (v_fil>Consigne))
{
OutPWM-=StepCyc;
if (OutPWM<=0.0) OutPWM+=StepCyc;
}

//5. Génération de la commande PWM
analogWrite(Out, (unsigned int)OutPWM);
v_fil_old= v_fil;

// 6. Affichage (Test Seulement)
Serial.print(vin_volat);
Serial.print(",");
Serial.print(Consigne);
Serial.print(",");
Serial.print(v_fil);
Serial.print(",");
Serial.println(OutPWM*5.0/255.0);

/*
LoopCyc=!LoopCyc;
Serial.println(LoopCyc);
*/
}

On verra  prochainement la version améliorée du code. N’oublie pas de laisser un commentaire, ça nous encourage pour continuer  à partager des projets 🙂

Laisser un commentaire