Objectifs

  1. Savoir l’utilité d’un actionnaire linéaire
  2. Savoir asservir la distance
  3. Savoir comment utiliser un capteur à ultrason
  4. Savoir les caractéristiques d’un actionnaire linéaire
  5. Savoir le fonctionnement d’un actionnaire linéaire
  6. Savoir commander un actionnaire linéaire
  7. Etc.

Applications

  1. Déplacement linéaire d’une charge, pièce
  2. Systèmes à vérin électrique
  3. Systèmes de translation : Portière, fenêtre, tables mobiles, etc.
  4. Procédés avec mouvement de translation précis
  5. Automatismes industriels
  6. Et, d’autres applications !

Principe de fonctionnement

Dans cette partie, on va voir comment asservir la distance de déplacement de l’arbre d’un actionneur linéaire (ou vérin électrique). L’idée consiste à définir une consigne par l’utilisateur, par exemple 20 mm. En suite, l’arabe va se déplacer d’une façon automatique jusqu’à l’obtention de la consigne, puis s’arrêter. Le système reste en revanche en asservissement permanent. Autrement dit, lorsque l’arabe s’éloigne de la consigne durant le fonctionnement, la commande va le ramener au voisinage de la consigne sans intervention humaine, c’est le principe de l’asservissement automatique !

  • Consigne : En pratique, la consigne peut être réglée par l’utilisateur soit par un potentiomètre, soit par deux boutons poussoir Up/Donw, une télécommande, etc. Un afficheur numérique est très utile afin de visualiser la cosigne réglée ainsi la sortie atteinte. On le voit souvent dans les systèmes asservis. Ici, la consigne sera définie dans le programme pour des raisons de simplifications. On verra peut-être dans un autre projet un système avec une consigne externe.
  • Capteur à ultrason : Il assure le retour de la distance de l’actionneur ou du vérin électrique. Il permet de passer d’une commande en boucle ouverte en une commande en boucle fermée.
  • Module PWM: Il permet de faire varier la vitesse de l’actionneur ainsi le changement de la polarité (sens de rotation). Le module est constitué d’un pont H complet avec une logique de commande. La partie commande nécessite 4 pins comme indiqué dans la figure. Les pins ( 6,7) dédiés à l’activation des bras droite/gauche du pont. Les pins (8, 9) sont des sorties PWM droite/gauche.  Par exemple, pour activer le sens 1, on positionne les pins (6, 7) à ‘1’ logique, ensuite, on envoie un signal PWM dans la sortie (8). La sortie  (9) en revanche reste à 0.
  • Actionneur linéaire : Il est alimenté avec la sortie du pont H complet
  • Arduino : Génération de la commande en fonction de la distance de l’arbre de l’actionneur

Commande d'un actionneur linéaire - Partie 3 Commande automatique

Le réglage du zéro

La procédure du réglage du zéro consiste à positionner l’actionner dans la position initiale durant la mise sous tension de la carte. La position initiale est définie par la fin de course basse. Lorsque le système se trouve dans la position initiale, le capteur de distance mesure une distante dite distance au repos (d0). Elle sera mémorisée et utilisée dans la boucle principale (voir le tuto pour plus de détails).  L’objectif du réglage du zéro est de réduire les dérives de la distance dans le temps (déplacement de la position du capteur ou celui de l’obstacle en face du capteur, etc.) et avoir une bonne précision sur l’obtention de la consigne. On peut supprimer la phase d’initialisation. En revanche, il faut définir une constante (d0) qu’elle sera introduite dans le programme. Une autre stratégie à deux capteurs à ultrason est envisageable pour se passer de la phase du réglage de zéros.

  // Remise à zéro de l'actionneur (Position initiale)  
const unsigned long TCourse=10; // Temps de la course max en secondes
unsigned long T=millis();
while((millis()-T)<TCourse*1000)
{
UpDown(PinOut, 1, 255); // Vitesse max
}
UpDown(PinOut, 0, 0); delay(2000);

Inversez la polarité du moteur si l’arbre translate dans le sens opposé.

Caractéristiques du pont H complet BTS7960

N’hésitez pas de consulter la partie 1 & 2 pour en savoir plus sur le fonctionnement du circuit BTS7960.

    Capteur à ultrason

    On va utiliser un capteur à ultrason pour la mesure de la distance de déplacement.

    module ultrason pour Arduino

    Les caractéristiques techniques du capteur – HC-SR04

    • Alimentation : 5 V
    • Consommation : 15 mA.
    • Portée : 2 cm à 5 m.
    • Résolution : 0.3 cm.
    • Angle de mesure : < 15°

    Chronogramme de fonctionnement

    Projet électronique FPGA 4 1 sur 3 Capteur de distance ultrasonique à base du FPGA et Arduino - capteur ultr

    Le capteur contient deux signaux TRIG et ECHO, et une broche d’alimentation à 5V et une masse.

    Le signal TRIG (une entrée) est une impulsion de 10 us qui permet de déclencher le circuit à l’intérieur du capteur pour activer l’émetteur ultrason (signal interne) et attendre l’arrivée de l’onde. Le capteur génère une sortie ECHO sous forme d’une impulsion électrique avec une largeur proportionnelle à la distance Aller/Retour.

    Nos avons abordé (voir ci-dessous) plusieurs projets dans le passé à base du capteur à ultrason avec Arduino. On va récupérer, amélioré et adapté le code à notre projet.

    Commentaires sur le code

    Pinout

    #define L_EN            6         // Left Enable   
    #define R_EN 7 // Right Enable
    #define L_PWM 8 // Left PWM
    #define R_PWM 9 // Right PWM
    #define RapCyc 30.0 // Duty Cycle (%)

    #define Consigne_mm 30.0 // Consigne en (mm)
    #define Epsilon_mm 3.0 // Consigne en (mm)

    #define Echo_in_pin 2 // Entrée: Retour de l'onde
    #define Trig_out_pin 3 // Sortie: Déclenchement de l'onde
    #define Speed_sound 340.0e-3 // Vitesse du son (mm/us)
    #define NMoy 150 // Filtrage de la distance

    Initialisation

    Définition de la fonction UpDown()

    La fonction UpDown() permet de générer les signaux de commande du module PWM en fonction du type de la commande. Elle prend en entrée le nom du tableau de 4 éléments content la numérotation des pins. La numérotation doit respecter l’ordre suivant : (L_EN, R_EN, L_PWM, R_PWM) (voir le code). Ensuite, le Type de la commande :

    • Type=1: Sens 1
    • Type=2: Sens 2
    • Type=0 ou autres valeurs : Arrêt

    La fonction prend également la valeur du rapport cyclique comprise entre 0 et 255. Par conséquent, grâce à la fonction, on peut faire varier le sens ainsi la vitesse du déplacement !  Ci-dessous la définition de la fonction.

    void UpDown(int* Pins, int Type,  unsigned int rapCyc)
    {
    switch (Type)
    {
    // Sens 1
    case 1:
    digitalWrite(Pins[0], HIGH);
    digitalWrite(Pins[1], HIGH);
    analogWrite(Pins[2], rapCyc);
    analogWrite(Pins[3], 0);
    break;

    // Sens 2
    case 2:
    digitalWrite(Pins[0], HIGH);
    digitalWrite(Pins[1], HIGH);
    analogWrite(Pins[2], 0);
    analogWrite(Pins[3], rapCyc);
    break;

    // Arrêt
    default:
    digitalWrite(Pins[0], LOW);
    digitalWrite(Pins[1], LOW);
    analogWrite(Pins[2], 0);
    analogWrite(Pins[3], 0);
    }
    }

    Définition de la fonction getMean()

    Mesure de la distance moyenne.

    float getMean(float *tabMoy, int Nm, float vin0)
    {
    // Variables locales
    static int J=0;
    float somme_1=0.0;
    float VMFiltre=0.0;

    // Filtrage: Calcul de la Moyenne Glissante
    for (int i=0; i<Nm; i++) somme_1+=tabMoy[i];
    VMFiltre=(somme_1/(float)Nm);

    // Mise à jour du tableau des VM
    tabMoy[J]=(vin0+VMFiltre)/2.0;
    J++; J%=Nm;

    // Retour de la VM
    return VMFiltre;
    }

    Définition de la fonction getDistmm()

    Lecture du capteur à ultrason. La fonction retourne la distance courante en (mm) entre le capteur et l’obstacle en face du capteur.

    double getDistmm(int trigpin, int echopin, double speedson) 
    {
    // Déclanchement mesure avec l'envoie d'une impulsion de 10µs
    digitalWrite(trigpin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigpin, LOW);

    // Lecture du temps aller/retour de l'onde
    double HC_val = pulseIn(echopin, HIGH, 30000);

    // Calcul de distance d(mm), V=d/t==> v*t
    // Le coefficient 2 pour la distance aller/retour
    double Dist_mm = (HC_val/2.0) * speedson;


    // Renvoi de la distance en (mm)
    if (Dist_mm <= 10.0) return 10.0; // Zone aveugle du capteur
    else return Dist_mm;
    }

    Application de la commande

    La commande utilisée est analogue à une commande incrémentale. La génération de la commande est effectuée d’une façon permanente en fonction de la distance en cours de l’arbre. On agit sur l’actionneur en fonction de la distance de retour de la façon suivante :

    • Augmentation du déplacement (Sens 1) : Distance de retour < Consigne – Epsilon
    • Diminution de déplacement (Sens 2) : Distance de retour >  Consigne – Epsilon
    • Arrêt : Distance au voisinage de la consigne à Epsilon près (désactivation du module PWM, pas de consommation à vide de l’actionneur).
      // Sens 1 - Down
    if (dist_mm> Consigne_mm+Epsilon_mm) UpDown(PinOut, 1, RP);

    // Sens 2 - Up
    else if (dist_mm< Consigne_mm-Epsilon_mm) UpDown(PinOut, 2, RP);

    // Arrêt
    else UpDown(PinOut, 0, RP);

     

    Vous pouvez tester d’autre stratégie de la commande en utilisant le même schéma électrique ! Il suffit de changer le code. Voir la série Asservissement avec Arduino pour plus de détails.

    Programme complet

    #define L_EN            6         // Left Enable   
    #define R_EN 7 // Right Enable
    #define L_PWM 8 // Left PWM
    #define R_PWM 9 // Right PWM
    #define RapCyc 80.0 // Duty Cycle (%)

    #define Consigne_mm 50.0 // Consigne en (mm)
    #define Epsilon_mm 3 // Consigne en (mm)

    #define Echo_in_pin 2 // Entrée: Retour de l'onde
    #define Trig_out_pin 3 // Sortie: Déclenchement de l'onde
    #define Speed_sound 340.0e-3 // Vitesse du son (mm/us)
    #define NMoy 50 // Filtrage de la distance


    // PWM
    unsigned short RP= 0;
    int PinOut[4];

    // Variables pour HC-SR04
    float dist_mm=0.0, d0=0.0, d1=0.0;
    float distMoy[NMoy];

    void setup()
    {
    // Pinout Module PWM
    pinMode(L_EN, OUTPUT);
    pinMode(R_EN, OUTPUT);
    pinMode(L_PWM, OUTPUT);
    pinMode(R_PWM, OUTPUT);

    // Init Module PWM
    digitalWrite(L_EN, LOW);
    digitalWrite(R_EN, LOW);
    analogWrite(L_PWM, 0);
    analogWrite(R_PWM, 0);

    // Init tableau des pins
    PinOut[0]=L_EN;
    PinOut[1]=R_EN ;
    PinOut[2]=L_PWM;
    PinOut[3]=R_PWM;

    // Init rapport cyclique
    RP=(unsigned short)(RapCyc*255.0/100.0);

    // Remise à zéro de l'actionneur (Position initiale)
    const unsigned long TCourse=10; // Temps de la course max en secondes
    unsigned long T=millis();
    while((millis()-T)<TCourse*1000)
    {
    UpDown(PinOut, 1, 255); // Vitesse max
    }
    UpDown(PinOut, 0, 0); delay(2000);

    // Initialisation HC-SR04
    pinMode(Trig_out_pin, OUTPUT);
    pinMode(Echo_in_pin, INPUT);
    digitalWrite(Trig_out_pin, LOW);

    // Init buffer des distances
    for(int i=0;i<NMoy; i++)
    {
    distMoy[i]=getDistmm(Trig_out_pin, Echo_in_pin, Speed_sound);
    delay(10);
    }


    // Ditance au repos (Course minimale)
    dist_mm=getDistmm(Trig_out_pin, Echo_in_pin, Speed_sound);
    d0= getMean(distMoy, NMoy, dist_mm);


    // Affichage (Test)
    Serial.begin(115200);
    }


    void loop()
    {
    // Lecture de la distance en (mm)
    d1=getDistmm(Trig_out_pin, Echo_in_pin, Speed_sound);
    dist_mm= d0-getMean(distMoy, NMoy, d1);

    // Visualisation de la distance (Test)
    Serial.print(d0); Serial.print(", ");
    Serial.print(d1); Serial.print(", ");
    Serial.println(dist_mm);
    //return;

    // Sens 1 - Down
    if (dist_mm> Consigne_mm+Epsilon_mm) UpDown(PinOut, 1, RP);

    // Sens 2 - Up
    else if (dist_mm< Consigne_mm-Epsilon_mm) UpDown(PinOut, 2, RP);

    // Arrêt
    else UpDown(PinOut, 0, RP);

    // Délai - HC-SR04
    delay(10);
    }



    void UpDown(int* Pins, int Type, unsigned int rapCyc)
    {
    switch (Type)
    {
    // Sens 1
    case 1:
    digitalWrite(Pins[0], HIGH);
    digitalWrite(Pins[1], HIGH);
    analogWrite(Pins[2], rapCyc);
    analogWrite(Pins[3], 0);
    break;

    // Sens 2
    case 2:
    digitalWrite(Pins[0], HIGH);
    digitalWrite(Pins[1], HIGH);
    analogWrite(Pins[2], 0);
    analogWrite(Pins[3], rapCyc);
    break;

    // Arrêt
    default:
    digitalWrite(Pins[0], LOW);
    digitalWrite(Pins[1], LOW);
    analogWrite(Pins[2], 0);
    analogWrite(Pins[3], 0);
    }
    }

    double getDistmm(int trigpin, int echopin, double speedson)
    {
    // Déclanchement mesure avec l'envoie d'une impulsion de 10µs
    digitalWrite(trigpin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigpin, LOW);

    // Lecture du temps aller/retour de l'onde
    double HC_val = pulseIn(echopin, HIGH, 30000);

    // Calcul de distance d(mm), V=d/t==> v*t
    // Le coefficient 2 pour la distance aller/retour
    double Dist_mm = (HC_val/2.0) * speedson;


    // Renvoi de la distance en (mm)
    if (Dist_mm <= 10.0) return 10.0; // Zone aveugle du capteur
    else return Dist_mm;
    }


    float getMean(float *tabMoy, int Nm, float vin0)
    {
    // Variables locales
    static int J=0;
    float somme_1=0.0;
    float VMFiltre=0.0;

    // Filtrage: Calcul de la Moyenne Glissante
    for (int i=0; i<Nm; i++) somme_1+=tabMoy[i];
    VMFiltre=(somme_1/(float)Nm);

    // Mise à jour du tableau des VM
    tabMoy[J]=(vin0+VMFiltre)/2.0;
    J++; J%=Nm;

    // Retour de la VM
    return VMFiltre;
    }

    N’oublie pas de laisser un commentaire, ça nous encourage pour continuer à partager de nouveaux projets 🙂

    Click to rate this post!
    [Total: 3 Average: 4.7]

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Retour en haut

    You have successfully subscribed to the newsletter

    There was an error while trying to send your request. Please try again.

    FPGA | Arduino | Matlab | Cours will use the information you provide on this form to be in touch with you and to provide updates and marketing.