Exemple: 6_Moteurs

Programme de démonstration faisant tourner 6 moteurs variés à différentes vitesses avec ou pas de accélérations ainsi qu'un "blink with delay".

Liens

Pour faire fonctionner cet exemple, il faut soit télécharger QuickStepExemples.zip contenant tous les fichiers d'exemples, soit télécharger 6_Moteurs.zip contenant cet exemple, soit créer un répertoire du nom de l'exemple et mettre dedans:
- le fichier 6_Moteurs.ino de l'exemple
- le fichier de configuration QuickStepConf.h propre à cet exemple
- les trois fichiers (QuickStep.h, QuickStep.cpp et digitalWriteFast.h) pour avoir la bibliothèque (identiques pour toutes les applications)

QuickStepConf.h (extraits)

// X: Moteur 17HS4401, Hybride 1,7A + A4988 16 µpas + rotation continue
// 10 tours dans un sens, 10 tours dans l'autre à 300tr/mn (= démarrages à 600tr/mn)
#define UN_TOUR_X (200L*16) pas_ou_micro_pas
#define VITESSE_MAXI_X 300.0 RPM
#define STEP_X 2
#define DIR_X 5
#define ENABLE_X 8
#define NOMBRE_DE_PAS_MAXIMUM_X_SUR_16_BITS
#define NB_ORDRES_DANS_LA_PILE_X 3

Un seul ordres dans la pile suffirait pour faire tourner le moteur, mais ici à cause de delay, on doit donner au moins un mouvent à l'avance. On prendra une pile de 3 ordres. 10 tours dans un sens avec 3200 pas/tr ne fait que 32000 pas à faire et cela tiendrait en 16 bits (mais ici économise peu car la pile est petite)

// Y: Moteur 17HS4401, Hybride 1,7A + A4988 8 µpas + accélérations
// Accélération de 15 tours dans un sens pris au hasard, décélération de 15 tours
// Vitesse finale 1000tr/mn#define UN_TOUR_Y (200L*8) pas_ou_micro_pas
#define VITESSE_MAXI_Y 1000.0 RPM
#define STEP_Y 3
#define DIR_Y 6
#define NB_ORDRES_DANS_LA_PILE_Y 127
#define NB_ORDRES_ACCELERATION_Y 63

Pour atteindre les 1000tr/mn, il faut une accélération avec beaucoup de paliers. Avec 63 paliers et une pile du double, on peut avoir 2 mouvements complets et ainsi avoir toujours quelque chose à faire. La broche ENABLE est la même que pour le moteur X, inutile de la redéfinir. Pour 15 tours, il faut absolument définir les comptages sur 32 bits.

// Z: Moteur 28BYJ-48 12V non modifié + A4988 pas entiers + rotation continue
// 1 tour en 3 à 48s
#define UN_TOUR_Z 2048L pas_ou_micro_pas
#define VITESSE_MAXI_Z 0.33 RPS
#define STEP_Z 4
#define DIR_Z 7
#define NOMBRE_DE_PAS_MAXIMUM_Z_SUR_16_BITS
#define NB_ORDRES_DANS_LA_PILE_Z 3

Pile de 3 ordres pour avoir des mouvement d'avance à faire.

// T: Moteur 42BYGH34, Hybride 12V + A4988 pas entiers + Aller retour
// 2 tours dans un sens, 2 tours dans l'autre, 120tr/mn (= démarrages à 240tr/mn)
#define UN_TOUR_T 200L pas_ou_micro_pas
#define VITESSE_MAXI_T 120.0 RPM
#define STEP_T 12
#define DIR_T 13
#define NOMBRE_DE_PAS_MAXIMUM_T_SUR_16_BITS
#define NB_ORDRES_DANS_LA_PILE_T 3
// U:Moteur 28BYJ-48 12V + ULN2003 4 fils demi-pas + accélérations
// Un tour dans un sens pris au hasard, avec démarrage et freinage
// Vitesse maxi 1 tour pour 3s
#define UN_TOUR_U (2048L*2) pas_ou_micro_pas
#define VITESSE_MAXI_U 0.33 RPS
#define PREM_BOBINE_U A3
#define DEUX_BOBINE_U A0
#define TROIS_BOBINE_U A
#define QUATRE_BOBINE_U A2
#define DEMI_PAS_U
#define NOMBRE_DE_PAS_MAXIMUM_U_SUR_16_BITS
#define NB_ORDRES_DANS_LA_PILE_U 31
#define NB_ORDRES_ACCELERATION_U 15

Ici, on ne peut pas donner d'ordre complet à l'avance. Le départ sera donc donné quand la led change d'état.

// V: Moteur 28BYJ-48 12V + ULN2003 2 fils + accélérations
// Un tour dans un sens pris au hasard, avec démarrage et freinage
// Vitesse maxi 1 tour pour 2s (vitesse du moteur 32tr/s soit 1920 tt/mn)
#define UN_TOUR_V 2048L pas_ou_micro_pas
#define VITESSE_MAXI_V 0.5 RPS
#define PREM_BOBINE_V 9
#define DEUX_BOBINE_V 10
#define NOMBRE_DE_PAS_MAXIMUM_V_SUR_16_BITS
#define NB_ORDRES_DANS_LA_PILE_V 31
#define NB_ORDRES_ACCELERATION_V 15

Ici de même, on ne peut pas donner d'ordre complet à l'avance. Le départ sera donc donné quand la led change d'état.

// W: Led clignottante
#define PREM_BOBINE_W A4
#define DEUX_BOBINE_W A5

On utilise la bibliothèque uniquement pour l'initialisation des ports et les noms de broches.

6_Moteurs.ino

#
  $menu = ":QS";
  include "QuickStep.h"

#define sens_hasard (2 * random(2) -1)

void setup()
{
  quickStepInit(); // Obligatoire pour utiliser QuickStep
  Serial.begin(115200); // Pour quickStepInfo
  quickStepInfo();
  /* Affiche:
Utilisation du timer 2
La base de temps retenu est de 37.50 µs
Entre deux impulsions STEP, il y a donc entre 37.5 et 9600 µs
Le moteur X peut tourner entre 500 et 1.95 tr/mn (8.33 et 0.0326 tr/s). Demandée 300 tr/mn (5.00 tr/s)
Le moteur Y peut tourner entre 1000 et 3.91 tr/mn (16.7 et 0.0651 tr/s). Demandée 1000 tr/mn (16.7 tr/s)
Le moteur Z peut tourner entre 781 et 3.05 tr/mn (13.0 et 0.0509 tr/s). Demandée 19.8 tr/mn (0.330 tr/s)
Le moteur T peut tourner entre 8000 et 31.3 tr/mn (133 et 0.521 tr/s). Demandée 120 tr/mn (2.00 tr/s)
Le moteur U peut tourner entre 391 et 1.53 tr/mn (6.51 et 0.0254 tr/s). Demandée 19.8 tr/mn (0.330 tr/s)
Le moteur V peut tourner entre 781 et 3.05 tr/mn (13.0 et 0.0509 tr/s). Demandée 30.0 tr/mn (0.500 tr/s)
   */
}

// Le mouvement complet accélération et décélération du moteur Y est donné en
// 2 fois pour ne pas déborder la pile et pour avoir toujours la moitié du
// mouvement dans la pile. Ainsi, le delay(500) ne gènera pas l'enchaînement.
// On aurait pu prendres une pile plus grande avec une Mega, ou faire moins
// de paliers. Mais pour atteindre 1000tr/mn, il vaut mieux garder les 63
//paliers. 
enum {acceleration, deceleration} prochainePhaseDuMoteurY = acceleration;
int8_t sensDuMoteurY;

void loop()
{ 
  // Led: Blink with delay
  // Période 1s
  digitalWrite(PREM_BOBINE_W, !digitalRead(PREM_BOBINE_W)); // Change d'état la led
  digitalWrite(DEUX_BOBINE_W, digitalRead(PREM_BOBINE_W)); // Met l'autre Led dans le même état
  delay(500); // Pour Que la led batte la seconde
  
  //X:  Moteur 17HS4401, Hybride 1,7A + A4988 16 µpas + rotation continue
  // 10 tours dans un sens, 10 tours dans l'autre à 300tr/mn (= démarrages à 600tr/mn)
  if (quickStepLibreX() > 0) quickStepRotationX((-digitalRead(DIR_X)+0.5) * 10 * UN_TOUR_X, VITESSE_MAXI_X);

  //Y:  Moteur 17HS4401, Hybride 1,7A + A4988 8 µpas + accélérations
  // Accélération de 15 tours dans un sens pris au hasard, décélération de 15 tours, vitesse finale 1000tr/mn
  if (quickStepLibreY() >= 63) 
    if (prochainePhaseDuMoteurY == acceleration)
    {
      quickStepRotationY( (sensDuMoteurY = sens_hasard) * 15*UN_TOUR_Y, VITESSE_MAXI_Y, acceleration_sur 15*UN_TOUR_Y, deceleration_sur 0 pas_ou_micro_pas);
      prochainePhaseDuMoteurY = deceleration;
    }
    else
    {
      quickStepRotationY(sensDuMoteurY * 15*UN_TOUR_Y, VITESSE_MAXI_Y, acceleration_sur 0 pas_ou_micro_pas, deceleration_sur 15*UN_TOUR_Y);
      prochainePhaseDuMoteurY = acceleration;
    }
    
  //Z:  Moteur 28BYJ-48 12V non modifié + A4988 pas entiers + rotation continue
  // 1 tour en 3 à 48s
  if (quickStepLibreZ() > 0) quickStepRotationZ(UN_TOUR_Z / 4, VITESSE_MAXI_Z * random(3, 16) / 16);

  //T:  Moteur 42BYGH34, Hybride 12V + A4988 pas entiers + Aller retour
  // 2 tours dans un sens, 2 tours dans l'autre, 120tr/mn (= démarrages à 240tr/mn)
  if (quickStepResteT() == 0) quickStepRotationT((-digitalRead(DIR_T)*2+1) * 2 * UN_TOUR_T, VITESSE_MAXI_T);

  //U:  Moteur 28BYJ-48 12V + ULN2003 4 fils demi-pas + accélérations
  // Un tour dans un sens pris au hasard, avec démarrage et freinage, vitesse maxi 1 tour pour 3s
  if (quickStepResteU() == 0) quickStepRotationU(sens_hasard * UN_TOUR_U, VITESSE_MAXI_U, acceleration_sur UN_TOUR_U / 2, deceleration_sur UN_TOUR_U / 2);

  //V:  Moteur 28BYJ-48 12V + ULN2003 2 fils + accélérations
  // Un tour dans un sens pris au hasard, avec démarrage et freinage, vitesse maxi 1 tour pour 2s (vitesse du moteur 32tr/s soit 1920 tt/mn)
  if (quickStepResteV() == 0) quickStepRotationV(sens_hasard * 2 * UN_TOUR_V, VITESSE_MAXI_V, acceleration_sur UN_TOUR_V, deceleration_sur UN_TOUR_V);
}