samedi 16 janvier 2016

Speed Motor's Variator Using STM32

Speed Motor's Variator Using STM32


Résultat de recherche d'images pour "stm32 motor"


La variation de vitesse de moteur a courant continu dans cet article est basée sur le protocole PWM qu'on peut le définir comme ceci :


PWM

La modulation de largeur d'impulsions (MLI ; en anglais : Pulse Width Modulation, soit PWM), est une technique couramment utilisée pour synthétiser des signaux continus à l'aide de circuits à fonctionnement tout ou rien, ou plus généralement à états discrets.
Le principe général est qu'en appliquant une succession d'états discrets pendant des durées bien choisies, on peut obtenir en moyenne sur une certaine durée n'importe quelle valeur intermédiaire.
Résultat de recherche d'images pour "pwm mli definition"
Ce phénomène est fortement recommandé pour assurer la variation de vitesse de moteur a courant continu, aujourd'hui je vais vous démontrer comment on peut générer un signal PWM déune STM32 et visualiser son présence sur des diodes LEDs.

Voici un exemple de comment on genere un signal PWM using Mikro C for ARM et STM32F4:
//Let's Electronic By Aymen Lachkhem
// www.letselectronic.blogspot.com
// Hello in this tutoriel we are going to use 4 buttons (digital Input), the first two will increase and decrease the current duty for the
// first Led and the second two will make the same thing with the other Led.
unsigned int current_duty, old_duty, current_duty1, old_duty1;
unsigned int pwm_period1, pwm_period2;

void InitMain() {
  GPIO_Digital_Input (&GPIOA_BASE, _GPIO_PINMASK_3 | _GPIO_PINMASK_4 | _GPIO_PINMASK_5 | _GPIO_PINMASK_6); // configure PORTA pins as input
}

void main() {
  InitMain();
  current_duty  = 100;                        // initial value for current_duty
  current_duty1 = 100;                        // initial value for current_duty1

  pwm_period1 = PWM_TIM1_Init(5000);
  pwm_period2 = PWM_TIM4_Init(5000);

  PWM_TIM1_Set_Duty(current_duty,  _PWM_NON_INVERTED, _PWM_CHANNEL1);  // Set current duty for PWM_TIM1
  PWM_TIM4_Set_Duty(current_duty1, _PWM_NON_INVERTED, _PWM_CHANNEL2);  // Set current duty for PWM_TIM4

  PWM_TIM1_Start(_PWM_CHANNEL1, &_GPIO_MODULE_TIM1_CH1_PE9);

  PWM_TIM4_Start(_PWM_CHANNEL2, &_GPIO_MODULE_TIM4_CH2_PD13);

  while (1) {                                // endless loop
    if (GPIOA_IDR.B3) {                // button on RA3 pressed
      Delay_ms(1);
      current_duty = current_duty + 5;       // increment current_duty
      if (current_duty > pwm_period1) {      // if we increase current_duty greater then possible pwm_period1 value
        current_duty = 0;                    // reset current_duty value to zero
      }
      PWM_TIM1_Set_Duty(current_duty,  _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
     }

    if (GPIOA_IDR.B4) {                // button on RA4 pressed
      Delay_ms(1);
      current_duty = current_duty - 5;       // decrement current_duty
      if (current_duty > pwm_period1) {      // if we decrease current_duty greater then possible pwm_period1 value (overflow)
        current_duty = pwm_period1;          // set current_duty to max possible value
      }
      PWM_TIM1_Set_Duty(current_duty,  _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
     }

    if (GPIOA_IDR.B5) {                // button on RA5 pressed
      Delay_ms(1);
      current_duty1 = current_duty1 + 5;     // increment current_duty
      if (current_duty1 > pwm_period2) {     // if we increase current_duty1 greater then possible pwm_period2 value
        current_duty1 = 0;                   // reset current_duty1 value to zero
      }
      PWM_TIM4_Set_Duty(current_duty1, _PWM_NON_INVERTED, _PWM_CHANNEL2);       // set newly acquired duty ratio
     }

    if (GPIOA_IDR.B6) {                // button on RA6 pressed
      Delay_ms(1);
      current_duty1 = current_duty1 - 5;     // decrement current_duty
      if (current_duty1 > pwm_period2) {     // if we decrease current_duty1 greater then possible pwm_period1 value (overflow)
        current_duty1 = pwm_period2;         // set current_duty to max possible value
      }
      PWM_TIM4_Set_Duty(current_duty1, _PWM_NON_INVERTED, _PWM_CHANNEL2);
     }

    Delay_ms(1);                             // slow down change pace a little
  }
}
    Voici une démonstration vidéo de fonctionnement :




L’objectif de ce tutoriel est de mettre en oeuvre le contrôle de vitesse de moteur a courant continu de façon autonome 
Pour ceci on aura besoin de 
Un Moteur DC
STM32 F4
Transistor TIP122
Diode
Deux boutons poussoirs 
deux résistances 1 K

Le principe est tout à fait simple on aura deux boutons poussoirs ou la première va incrémenter la vitesse de moteur et la deuxième va faire exactement le contraire.

L’incrémentation continuera jusqu’à alimenter le moteur en régime de rapport cyclique complet puis conditionnement une autre incrémentation va le remettre a 0 tour/s, le même truc se passe avec la décrémentation de rapport déja nul va le rendre on vitesse maximale.


Voici un exemple de comment on varie le vitesse de moteur a courant continu using Mikro C for ARM et STM32F4:

//Let's Electronic By Aymen Lachkhem
// www.letselectronic.blogspot.com
// In This Tutorial We are going to control the speed of dc motor using Stm32 PWM.
unsigned int current_duty, old_duty;
unsigned int pwm_period1, pwm_period2;

void InitMain() {
  GPIO_Digital_Input (&GPIOA_BASE, _GPIO_PINMASK_3 | _GPIO_PINMASK_4 ); // configure PORTA pins as speed control input
}

void main() {
  InitMain();
  current_duty  = 100;                        // initial value for current_duty


  pwm_period1 = PWM_TIM1_Init(5000);


  PWM_TIM1_Set_Duty(current_duty,  _PWM_NON_INVERTED, _PWM_CHANNEL1);  // Set current duty for PWM_TIM1

  PWM_TIM1_Start(_PWM_CHANNEL1, &_GPIO_MODULE_TIM1_CH1_PE9);



  while (1) {                                // endless loop
    if (GPIOA_IDR.B3) {                // button on RA3 pressed
      Delay_ms(1);
      current_duty = current_duty + 1;       // increment speed
      if (current_duty > pwm_period1) {      // if we increase current_duty greater then possible pwm_period1 value
        current_duty = 0;                    // reset current_duty value to zero
      }
      PWM_TIM1_Set_Duty(current_duty,  _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
     }

    if (GPIOA_IDR.B4) {                // button on RA4 pressed
      Delay_ms(1);
      current_duty = current_duty - 3;       // decrement speed
      if (current_duty > pwm_period1) {      // if we decrease current_duty greater then possible pwm_period1 value (overflow)
        current_duty = pwm_period1;          // set current_duty to max possible value
      }
      PWM_TIM1_Set_Duty(current_duty,  _PWM_NON_INVERTED, _PWM_CHANNEL1); // set newly acquired duty ratio
     }

    Delay_ms(1);                             // slow down change pace a little
  }
}
    Voici une démonstration vidéo de fonctionnement :




   




Aucun commentaire:

Enregistrer un commentaire