Bonjour à tous,
Je suis nouveau sur ce forum et je le trouve super intéressant. Du coup, j’ai souhaité partager le problème que je rencontre actuellement sur un asservissement de position de moteur à courant continu. Je vais essayer d’être le plus précis possible dans mes explications.
Description de mon application : j’effectue un asservissement numérique avec un Atmega328 à l’aide d’Arduino. Ce microcontrôleur vient commander un moteur CC à travers un pont en H. En particulier, la commande est générée par la PWM du microcontrôleur, et est ensuite dirigée vers des portes logiques qui délivrent eux-même le signal PWM et son complément au pont en H. Le moteur est équipé d’une roue codeuse à effet Hall pour capter la rotation de son axe rotor. Ce capteur fourni des fronts, provoqué par un changement d’angle, que je viens compter avec le µC (l’angle parcouru entre 2 tick est de 30°). Ref. moteur : https://www.pololu.com/product/3215
Les couples résistants élevés induits par la charge mécanique m’empêche d’utiliser un servomoteur. Le moteur possède donc un réducteur 1:20.4 pour palier à ce problème. L’axe de sorti parcourt dans l’application, au maximum 3 tours.
Pour les besoins de mon application, le axe moteur doit atteindre la consigne sans erreur statique (c’est primordial). J’ai donc souhaité implanter un correcteur PI.
Dans un premier temps, j’ai commencé par un asservissement avec correction proportionnelle seulement dont voici le code :
void Asservissement(float ConsignePositionRotor) // fonction d'asservissement effectuée toutes les 79ms
{
// Chaine directe
ErreurCourante = ConsignePositionRotor - PositionCouranteRotor ; // Calcul de l'erreur
RapportCyclique = Kp * ErreurCourante + 127 ; // Correcteur PI
if ( RapportCyclique > 255 ){// Saturation dans un sens de rotation
RapportCyclique = 255;
}
if ( RapportCyclique < 0 ){// Saturation dans l'autre de rotation
RapportCyclique = 0;
}
OCR2A = RapportCyclique ; // Registre de la valeur de rapport cyclique de la PWM de l'Atmega328
// Chaine de retour
if (ErreurCourante > 0){
PositionCouranteRotor = PositionCouranteRotor + TCNT1 ;
TCNT1 = 0 ;
}
if (ErreurCourante < 0){
PositionCouranteRotor = PositionCouranteRotor - TCNT1 ;
TCNT1 = 0 ;
}
}
Cette fonction est effectuée toutes les 26.3ms. TCNT1 est le registre du compteur 1 de l’atmega qui compte les 'ticks’ de ma roue codeuse. Toutes les variables sont réinitialisées à chaque fin d’asservissement. Enfin, la constante 127 est ajouté à la variable RapportCyclique pour utiliser les deux sens de rotations(de 0 à 127, on tourne dans un sens et de 127 à 255, on tourne dans l’autre).
J’ai ensuite testé plusieurs consignes d’angles pour 3 valeurs gain Kp (0.25, 0.5 et 0.75) afin de tester cette asservissement tout neuf.
Pour Kp = 0.25 : L’amortissement du système est faible, ce qui est a priori normal. Mais l’erreur statique est quant à elle constante quelque soit la consigne. D’après mes souvenirs des cours d’automatiques, l’erreur statique doit être proportionnelle à la valeur de la consigne. => Donc là… pas bon.
Pour Kp = 0.5 : Il y a un faible dépassement et quelques oscillations, mais l’erreur statique remontée par le µC est quasiment nulle, alors que le rotor a parcouru en réalité, un angle bien plus important que la consigne demandée… => Donc là, pas bon non plus.
Pour Kp = 0.75 : Même constat que pour Kp = 0.5 hormis une légère amplification des oscillations (erreur statique remontée par le µC toujours nulle alors que l’angle parcouru en réalité, est beaucoup, beaucoup plus important que la consigne demandée). => Pas bon non plus…
Voilà mon soucis… J’ai l’impression qu’il y a un truc qui m’échappe… peut-être que j’emploie une mauvaise méthode ?
En vous remerciant par avance pour toutes vos réponses. Bonne soirée !
PS : j’ai des photos de mes courbes mais je n’arrive pas à les intégrer dans le message…