IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Code asservissement position moteur cc avec encodeur


Sujet :

Arduino

Mode arborescent

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2021
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2021
    Messages : 5
    Par défaut Code asservissement position moteur cc avec encodeur
    Bonjour tout le monde!
    J'ai un soucis avec un programme arduino conçu pour asservir un moteur cc avec encodeur en position et ce problème me prends la tête depuis 2 bonne semaines maintenant... C'est assez important, c'est pour mon TIPE (projet de prépa équivalent aux TPE de 1re) et on est assez en retard comme ça avec mon collègue...

    Contexte: le motoréducteur sert à faire déplacer un chariot sur un axe linéaire. Un système de poulie-courroie transforme la rotation du moteur en translation du chariot.
    Cependant, quand j'entre une consigne de 10cm, il ne se déplace que de 3cm environ.
    De plus, le moniteur série n'affiche que des valeurs entières de l'angle mesuré en sortie du réducteur (nommé 'angle_tour dans le programme), alors qu'il devrait y avoir des décimales puisque 'angle_tour' est défini comme un float...

    La poulie a un rayon de Rpoul=0.5cm
    Mon moteur a un rapport de réduction de r=1/20
    Le capteur à effet Hall situé à l'extrémité du moteur a une résolution de PPR= 11 impulsions par tour

    Le code est normalement joint en fichier.

    Si même l'un d'entre vous serait d'accord pour se contacter très rapidement par vidéo conférence ce serait topissime!
    Merci d'avance...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    #include <SimpleTimer.h>
     
     
    // asservissement en position angulaire un moteur à courant continu.
     
    SimpleTimer timer; // Timer pour échantillonnage
     
    //definition des entrées
     
    #define pi 3.14
    #define r 20
    #define Rpoul 0.5
    #define PPR 11   //Nombre de ticks par tour de rotor (20*11 ticks par tour d'arbre de sortie)
    #define tourparcm 1/(2*pi*Rpoul)
     
    const int pinInput1 = 6; // Commande de sens moteur, Input 1
    const int pinInput2 = 7; // Commande de sens moteur, Input 2
    const int pinPower = 9; // Commande de vitesse moteur, Output Enabled1
    const int encoderPinA = 2; // compteur 1
    const int encoderPinB = 3; // compteur 2
     
    //init echantillonage
    unsigned int time = 0;
    const int frequence_echantillonnage = 20;
     
    //init compteur :
    int encoder0Pos = 0; //position de départ=0
    int lastReportedPos = 0;
    boolean A_set = false;
    boolean B_set = false;
     
    //consigne
    const double target_cm = -10;
    double target_tour = tourparcm * target_cm;
    int target_ticks; //plus simple d'asservir en ticks car ce sera toujours un nombre entier
     
    // init calculs asservissement PID
    int erreur = 0; //erreur
    float erreurPrecedente = 0;
    float somme_erreur = 0;
     
    //Definition des constantes du correcteur PID
    const float kp = 1; // Coefficient proportionnel (choisis par essais successifs)
    const float ki = 0; // Coefficient intégrateur
    const float kd = 0; // Coefficient dérivateur
     
    /* Routine d'initialisation */
    void setup()
    {
     target_ticks = target_tour * r * PPR ;    //Consigne en ticks
     Serial.begin(9600); // Initialisation port COM
     Serial.println(F("CLEARDATA"));
     Serial.println(F("LABEL, temps, consigne, erreur, encoder0pos, vitesse_moteur, angle_tour, distance"));
     
     pinMode(pinPower, OUTPUT); // Sorties commande moteur
     pinMode(pinInput1, OUTPUT);
     pinMode(pinInput2, OUTPUT);
     pinMode(encoderPinA, INPUT); //sorties encodeur
     pinMode(encoderPinB, INPUT);
     digitalWrite(encoderPinA, HIGH); // Resistance interne arduino ON
     digitalWrite(encoderPinB, HIGH); // Resistance interne arduino ON
     // Interruption de l'encodeur A en sortie 0 (pin 2)
     attachInterrupt(0, doEncoderA, CHANGE);
     // Interruption de l'encodeur A en sortie 1 (pin 3)
     attachInterrupt(1, doEncoderB, CHANGE);
     analogWrite(pinPower, 0); // Initialisation sortie moteur à 0
     delay(300); // Pause de 0,3 sec pour laisser le temps au moteur de s'arréter si celui-ci est en marche
     
     // Interruption pour calcul du PID et asservissement appelée toutes les 10ms
     timer.setInterval(1000 / frequence_echantillonnage, asservissement);
    }
    /* Fonction principale */
    void loop()
    {
     timer.run(); //on fait tourner l'horloge
    }
     
    //---- Cette fonction est appelée toutes les 20ms pour calcul du correcteur PID
    void asservissement ()
    {
     time += 20; // pratique pour graphes excel après affichage sur le moniteur
     erreur = target_ticks - encoder0Pos;
     somme_erreur += erreur;
     
     // Calcul de la vitesse courante du moteur
     int vitMoteur = kp * erreur + kd * (erreur - erreurPrecedente) + ki * (somme_erreur);
     erreurPrecedente = erreur; // Ecrase l'erreur précedente par la nouvelle erreur
     
     // Normalisation et contrôle du moteur
     if ( vitMoteur > 255 ) vitMoteur = 255; // on est branché sur un pont en H L293D   ici, il s'agit de la saturation
     else if ( vitMoteur < -255 ) vitMoteur = -255;
     Tourner (vitMoteur);
     float angle_tour = encoder0Pos / PPR / r; //Position angulaire de sortie (ici il s'agit de la sortie du réducteur et non pas de la sortie du moteur)
    // pratique pour comparer avec la consigne d'entrée
     float distance = angle_tour / tourparcm;
     Serial.print(("DATA,TIME"));
     Serial.print(F(","));
     Serial.print(target_cm);
     Serial.print(F(","));
     Serial.print(erreur); // affiche sur le moniteur les données voulues
     Serial.print(F(","));
     Serial.print(encoder0Pos);
     Serial.print(F(","));
     Serial.print(vitMoteur);
     Serial.print(F(","));
     Serial.print(angle_tour);
     Serial.print(F(","));
     Serial.print(distance);
     Serial.println();
    }
     
    //---- Interruption appelée à tous les changements d'état de A
    void doEncoderA()
    {
     A_set = (digitalRead(encoderPinA) == HIGH);
     encoder0Pos += (A_set != B_set) ? -1 : 1 ; //modifie le compteur selon les deux états des encodeurs ( correspond au front montant de A, on compare à B pour déduire le sens de rotation et on en déduit si on incrémente +1 ou -1)
    }
     
    //---- Interruption appelée à tous les changements d'état de B
    void doEncoderB()
    {
     B_set = (digitalRead(encoderPinB) == HIGH);
     encoder0Pos += (A_set == B_set) ? -1 : 1 ; //modifie le compteur selon les deux états des encodeurs
    }
     
     
    //---- Fonction appelée pour contrôler le moteur
    void Tourner( int rapportCyclique )
    {
     if ( rapportCyclique > 0 )
     {
     digitalWrite(pinInput1, LOW);
     digitalWrite(pinInput2, HIGH);
     }
     else
     {
     digitalWrite(pinInput1, HIGH);
     digitalWrite(pinInput2, LOW);
     rapportCyclique = -rapportCyclique;
     }
     analogWrite(pinPower, rapportCyclique);
    }
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Code CSS (position?) qui bug avec Firefox ?
    Par RinaBK dans le forum Mise en page CSS
    Réponses: 23
    Dernier message: 29/01/2021, 19h02
  2. Réponses: 4
    Dernier message: 13/10/2005, 14h44
  3. Réponses: 7
    Dernier message: 12/09/2005, 11h05
  4. [web] position du logo avec TK
    Par stepha001 dans le forum Interfaces Graphiques
    Réponses: 6
    Dernier message: 20/04/2005, 13h58
  5. Récupérer le code HTML d'une page avec Delphi 7
    Par PsyKroPack dans le forum Web & réseau
    Réponses: 5
    Dernier message: 06/02/2003, 21h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo