Ce tutoriel expose une méthodologie complète pour la régulation de la vitesse d’un actionneur linéaire rapide, s’appuyant sur une stratégie de commande incrémentale. Un aspect clé de ce tutoriel est la présentation d’une technique pratique pour mesurer avec précision la vitesse de rotation de l’actionneur. Cette technique repose sur l’analyse d’un signal alternatif issu du système, et plus spécifiquement sur l’élimination de sa composante continue. L’avantage majeur de cette approche réside dans sa capacité à fournir une mesure de vitesse fiable et exempte de décalage, sans qu’il soit nécessaire de déterminer et d’ajuster un seuil de détection, simplifiant ainsi la mise en œuvre et augmentant la robustesse du système.
VIDEO
Programme Arduino
#define PWM_PIN 3 #define NUM_MEAN 16 #define ADC_SEUIL 1450.0 #define PWM_MIN 60.0 #define PWM_MAX 250.0 const unsigned long NUM_MEAN_DC=4096; #define PWM_DEFAULT 100.0 //Valeur Initiale #define VITESSE_TR_MIN 250.0 //Consigne #define DELAY_uS 100 //Délai d'incrémentation(µS) #define STEP_PWM 1.0 //Pas d'incrémentation unsigned long T0, T; unsigned long count_iter=0; double T_s; double F_s=0.0; static byte pwm_i=PWM_MIN; double pwm_f=PWM_MIN; double adc_mv=0.0, adc_mv_diff=0.0; double somme=0.0; bool res_status=false; bool res_status_old=false; double vitesse=0.0; unsigned long T_0_pwm; double mean_dc=0.0, somme_dc=0.0; unsigned long count_dc=0; void setup() { //Interface série (tests) Serial.begin(115200); //PWM pinMode(PWM_PIN, OUTPUT); analogWrite(PWM_PIN, PWM_DEFAULT); //Init T0=micros(); T_0_pwm=micros(); } void loop() { //1. Filtrage for(int i=0;i<NUM_MEAN;i ) somme =(double)analogRead(A0); adc_mv=somme/(double)NUM_MEAN; adc_mv=1000.0*adc_mv*5.0/1023.0; somme=0.0; //2. Seuillage res_status= adc_mv_diff>0.0; //res_status= adc_mv>ADC_SEUIL; //Serial.println(String(ADC_SEUIL*res_status) " ," String(adc_mv)); return; //3. Mesure de la vitesse bool fall_egde=(res_status==0) & (res_status_old==1); if(!fall_egde) count_iter ; else{ if(count_iter!=0){ T=micros(); T_s=1.0E-6*((double)T-(double)T0)*(double)count_iter; if(T_s!=0.0){ //F_s=1.0/(2.0*T_s); //Demi-période F_s=1.0/T_s; //Période complète vitesse=60.0*F_s; //Serial.println("Vitesse(Tr/Min)=" String(vitesse)); } } count_iter=0; } //4. Composante DC if(count_dc >=NUM_MEAN_DC){ mean_dc=somme_dc/((double)NUM_MEAN_DC); count_dc=0; somme_dc=0.0; }else{ count_dc ; somme_dc =adc_mv; } adc_mv_diff=adc_mv-mean_dc; //Serial.println(String(adc_mv) " ," String(mean_dc) " ," String(adc_mv_diff)); //Serial.println(adc_mv_diff); //Serial.println(String(adc_mv_diff) " ," String(250.0*res_status) " ," String(250.0*fall_egde)); //Serial.println(String(adc_mv_diff) " ," String(250.0*fall_egde)); //5. Régulation if(fall_egde!=0){ if(micros()>T_0_pwm DELAY_uS){ T_0_pwm=micros(); if(vitesse<VITESSE_TR_MIN){ pwm_f =STEP_PWM; if(pwm_f>PWM_MAX)pwm_f=PWM_MAX; }else{ pwm_f-=STEP_PWM; if(pwm_f<PWM_MIN)pwm_f=PWM_MIN; } analogWrite(PWM_PIN, (byte)pwm_f); if(vitesse <500.0) Serial.println(String(pwm_f) "," String(vitesse) "," String(VITESSE_TR_MIN)); } } //Init T0 T0=micros(); res_status_old=res_status; }
Régulation de la vitesse