Comment mettre en place un asservissement numérique ?

NIVEAU 3

Objectifs

  • Mettre en oeuvre un système asservi numérique

Pré-requis

Pourquoi asservir un système ?

Afin de comprendre pourquoi il est important d’asservir un système pour le controler, je vous conseille d’aller voir les quelques vidéos suivantes, proposées par Mathworks.

Asservissement linéaire continu

Attention On ne rentrera pas dans le détail de l’asservissement linéaire continu dans ce tutoriel, ni dans les différentes possibilités de le corriger en cas d’instabilité ou de mauvaise réponse temporelle.

Pour pouvoir contrôler au mieux une grandeur physique sur laquelle on veut agir (température d’un four, position d’un objet contrôlé par un moteur…), il est indispensable d’asservir cette grandeur à une consigne souhaitée. Il est également indispensable de pouvoir mesurer cette grandeur afin de la comparer à un signal de consigne.

Dans le cas de systèmes linéaires, on peut réaliser cet asservissement à l’aide d’un système totalement analogique.

Le schéma suivant montre une boucle d’asservissement classique, intégrant un correcteur (étudié dans le module Automatique).

Une valeur de consigne est comparée à la grandeur mesurée afin de générer un signal d’erreur qui servira à la commande du système à piloter. Lorsque la grandeur considérée atteindra la valeur de consigne (à quelques facteurs prêts…), l’erreur tendra alors vers 0.

Dans le schéma précédent, on peut citer les éléments suivants :

  • \(H(p)\) : la chaîne d’action permettant de passer d’une grandeur électrique à la grandeur souhaitée. Elle peut être décomposée en 2 sous-systèmes :
    • \(Sys(p)\) : le système que l’on cherche à piloter (moteur, module Peltier), qui convertit la plupart du temps une grandeur électrique en une grandeur physique autre : mouvement, chaleur…
    • \(H'(p)\) : la transformation de la grandeur de consigne (souvent électrique) en un signal de pilotage accepté par le système à commander
  • \(R(p)\) : la chaîne de retour permettant d’avoir une image de la grandeur à contrôler. Elle peut être décomposée en 2 sous-systèmes :
    • \(M(p)\) : le capteur qui convertit la grandeur physique d’intérêt vers une grandeur électrique exploitable : capteur de pression, encodeur de position, thermistance…
    • \(R'(p)\) : la transformation de la grandeur physique mesurée par le capteur en un signal comparable au signal de consigne
  • \(C(p)\) (optionnel) : le correcteur de l’asservissement, permettant de rendre plus stable et plus rapide le système asservi

Asservissement numérique d’un système

Implémentation sur Nucleo via MBED

Exemple 1 : Contrôle en position d’une MCC avec encodeur

Pour cette section, il est important d’avoir réalisé le tutoriel suivant : Faire varier la vitesse d’un moteur à courant continu3.

Etude du moteur

MCC de type : POLOLU 3239 / Encodeur 24 positions / Rapport de réduction 20.4:1.

Le moteur peut être alimenté jusqu’à 12V DC. Il est équipé d’un réducteur de 20.4:1. Lorsqu’il est alimenté avec une tension continue de 12 V, le constructeur stipule que la vitesse de rotation est de 370 tours par minute.
Le courant à vide à cette tension est de 200 mA.

Ce moteur possède un couple de 3 kg.cm. Il peut consommer jusqu’à 2.1 A chargé.

Pour le piloter, nous allons utiliser un composant de type L293D (pont en H – voir Faire varier la vitesse d’un moteur à courant continu).

Etude de l’encodeur de position

Le moteur étudié précédemment est associé à un capteur de type encodeur de vitesse à 24 positions. Il est placé sur le moteur et permet alors d’avoir 979.62 fronts par tour, lorsqu’on cumule les deux sorties en quadrature (A et B) du capteur.

Il sera alors possible d’avoir une précision sur la position de 360°/979.2 = 0.37°.

Code complet

Cet exemple nécessite la bibliothèque QEI pour l’encodeur de position (disponible ici).

#include "mbed.h"
#include "QEI.h"

DigitalOut  my_led(LED1);
DigitalIn   bouton(USER_BUTTON);
PwmOut      pwm_moteur1(PA_8);
DigitalOut  Enable(PB_5);
PwmOut      pwm_moteur2(PB_3);
Serial      pc(USBTX,USBRX);
QEI         codeur(D8, D9, NC, 48, QEI::X4_ENCODING );
AnalogOut   sortie_position(A2);
AnalogIn    entree_consigne(A0);
Ticker      ticker_regul;
        
void moteur(float ratio);

void boucle_regul(void){
    float consigne;
    float position_roue;
    static float erreur;
    static float Ierreur;
    float Kp = 0.05;
    float KiTe = 0.00001;

    Ierreur = Ierreur + erreur;
    consigne = entree_consigne * 360.0;
    position_roue = ( ((codeur.getPulses()*10)%9792) * 36.0/(48*20.4) );
    erreur = consigne - position_roue;
    moteur(Kp * erreur + KiTe *Ierreur );
    sortie_position.write(position_roue/360.0);
    
    }

int main()
{
    
    pwm_moteur1.period_us(50);
    pwm_moteur2.period_us(50);
    pwm_moteur2.write(0);
    Enable = 1;
    ticker_regul.attach(&boucle_regul,0.001);
    
    pc.printf("TP asservissement position\n\r");
    
    while (1) {
     
    }
}

void moteur(float ratio){
    if (ratio >= (float)0.0) {
        pwm_moteur1.write(0);
        pwm_moteur2.write(ratio);
    }
    else{
        pwm_moteur1.write(-ratio);
        pwm_moteur2.write(0);
    }       
}

Vidéo de démonstration :

Exemple 2 : Contrôle de température d’un module Peltier

MInE Prototyper Prototyper avec Nucleo et MBED

Nucléo – Mettre en place un asservissement numérique / 3