Compter les tours d’un axe avec un fin de course

Un petit montage avec lequel on va pouvoir contrôler le nombre de rotations d’un axe ; on va même pouvoir contrôler le nombre de quart de tours !

Le montage est adapté à des axes tournant à des vitesses faibles et reliés à des moteurs à faible inertie. Dans ces conditions, il offre une précision tout à fait satisfaisante.

Presque un moteur pas à pas 🙂 !

Pour ceux qui ont besoin d’un compte-tours, en voici un ici à base de fourche optique.

Voilà un modèle (construction très inspirée par un modèle de Willy) qui utilise les fonctions ci-dessous pour contrôler la montée et la descente de la benne.



/*
   Compte-tours avec fdc
    
       
 */
int FDC = 2; // fdc relié à la pin 2 
 
int E1 = 5; //M1 Controle de vitesse PWM
 
int M1 = 4; //M1 Controle du sens de rotation
 
int APPUI = 0; // sur ce fdc appui = etat bas
 
void marche_avant(char a) //Marche avant
{
  analogWrite (E1,a); // PWM (reglage vitesse)
  digitalWrite(M1,HIGH); // sens de rotation
} 
 
void marche_arriere (char a) //Marche arrière
{
  analogWrite (E1,a); // PWM (reglage vitesse)
  digitalWrite(M1,LOW); // sens de rotation
}

void stop_moteur () 
{
  analogWrite (E1,0); // PWM (reglage vitesse)
  delay(100);
}
 
 
/////////////////////////////////////////////////////////////////////
void marche_nb_pas( int vitesse, int nb_pas, char sens)
/////////////////////////////////////////////////////////////////////

{
// une poulie porte des plots
// qd le plot touche le fdc
// on compte les changements d'etat
// de la pin reliée
// pour un plot appuyé,
// deux changements d'état


boolean etat_fdc = false;

boolean etat_fdc_precedent = false ;

int chgt_fdc = 0 ;

int nb_top = 0;


// lancer le moteur

 if (sens == 'A') {
      marche_avant (vitesse);
     }
     
 if (sens == 'R') {
      marche_arriere (vitesse);
     }
     


while ( nb_top < nb_pas  ) {
  
      
 etat_fdc = 0;
  
 if (digitalRead(FDC) == APPUI) {     
    
      delay(5);     
        
      etat_fdc = 1;
            
 }             
 
  
   // est-ce qu'on a changé d'état ?
  
   if ( etat_fdc != etat_fdc_precedent ) {
     
       chgt_fdc++;
   }
   
  
   
   // 1 passage de plot entraine
   // 2 changements d'état
     
    nb_top = chgt_fdc / 2;
    
    //Serial.print ("*************** nb_top : ");
    
   // Serial.println(nb_top);
    
    etat_fdc_precedent= etat_fdc;     
     
  }     
 

stop_moteur();
}
 
 
 
 
// Executee une seule fois
 
void setup() {
   
   // initialiser la communication serie
    
   Serial.begin(9600);
    
   pinMode(E1, OUTPUT); // E1 est utilisee en sortie
    
   pinMode(M1, OUTPUT); // M1 est utilisee en sortie
   
   pinMode(FDC,INPUT); // fin de course relié pin 2
   
   // ici on n'active pas la resistance pull-up interne 
   //  on utilise un crash sensor DFRobot
   // qui est  FDC avec resistance de rappel intégrée
   // et resistance de protection intégrée
   // modèles utilisés :
   // SEN0138-L et SEN0138-R
  
}
 
// executee en boucle
 
void loop() {
  
    
   Serial.println("On avance de 4 pas");
   
   marche_nb_pas(200,4,'A');
   
   delay(3000);
    
   
  Serial.println("On recule d'un pas");
   
   marche_nb_pas(200,1,'R');
   
   delay(3000);
   
  
  Serial.println("On recule de 3 pas");
   
   marche_nb_pas(200,3,'R');    
    
   delay(3000);
}

 

Grue à bec de Canard – partie 4

Fichier hébergé par Archive-Host.com

Fichier hébergé par Archive-Host.com

Fichier hébergé par Archive-Host.com

Pour interagir avec l’Arduino depuis le PC, Yves a écrit deux codes processing


// Slider 1
 
// un slider pour commander la vitesse d'un moteur 
 // importer les librairies nécessaires
import processing.serial.*; // présente par défaut
import controlP5.*; // il faut l'installer

ControlP5 controlP5;
Serial serial;
  
int prefixe_moteur = 121 ; 
// ce prefixe indique que la commande qui va suivre concerne le moteur
 
void setup() {
  // On dessine la fenêtre de l'interface graphique
  size(400,350);
   
  // Le programme affiche dans la fenêtre de debuggage
  // de processing, en bas d'écran la liste des ports
  println("Voici la liste des ports :");
  println(Serial.list());
   
  // ici on a choisi le port 0
  // il faut peut-être essayer une autre
  // valeur de la liste en cas de pb
   
  int numero_port_serie = 0;
   
  print("Le numero de port est : ");
  println(numero_port_serie);
   
  String port = Serial.list()[numero_port_serie];
   
  print("Le port est : " );
  println(port);
 
  serial = new Serial(this, port, 9600); 
// attention a mettre la même vitesse coté Dfrduino

  controlP5 = new ControlP5(this); 
 
  // Créer un  slider horizontal
 
  //("Nom du Slider", min,max, pos de depart, xpos,ypos, largeur,hauteur);
  controlP5.addSlider("MOTEUR", -50,50, 0, 100,150, 200,20);
   
  // Configure les propriétés du Slider
  Slider s2 = (Slider)controlP5.controller("MOTEUR");
  s2.setSliderMode(Slider.FLEXIBLE);
  s2.setNumberOfTickMarks(11);
  s2.showTickMarks(true);
  s2.snapToTickMarks(false);
}
// Dessine les objets choisis
void draw() {
  background(100); // 100 : fond gris
} 

// Dans cette méthode// on récupère la valeur 
// renvoyée par le slider moteur2// et on l'envoie à l'Arduino
 
void MOTEUR(float valeur_slider) {
   
  int sens = 1; // marche avant moteur
   
  // Récupérer la valeur envoyée par le slider entre -50 et 50
   
  if (valeur_slider < 0) {
      sens= 0 ; // marche arriere
      valeur_slider = - valeur_slider;
  }    
   
  int vitesse = round(valeur_slider);
   
  // envoyer cette valeur à l'Arduino 
  
  serial.write (prefixe_moteur);
   
  serial.write (sens);
   
  serial.write(vitesse); 
   
 }

// Slider 1moteurs     
// un slider pour commander la vitesse des moteurs 
 // importer les librairies nécessaires
import processing.serial.*; // présente par défaut
import controlP5.*; // il faut l'installer

ControlP5 controlP5;
Toggle t1;
Toggle t2;
Toggle t3;
Toggle t4;
Serial serial;
 
int prefixe_moteurs = 111 ; 
// ce prefixe indique que la commande qui va suivre concerne les moteurs
  
void setup() {
  // On dessine la fenêtre de l'interface graphique
  size(550,350);
  
  // Le programme affiche dans la fenêtre de debuggage
  // de processing, en bas d'écran la liste des ports
  println("Voici la liste des ports :");
  println(Serial.list());
   
  // ici on a choisi le port 1
  // il faut peut-être essayer une autre
  // valeur de la liste en cas de pb
   
  int numero_port_serie = 1;   
  print("Le numero de port est : ");
  println(numero_port_serie);   
  String port = Serial.list()[numero_port_serie];   
  print("Le port est : " );
  println(port);
 
  serial = new Serial(this, port, 9600);
  controlP5 = new ControlP5(this); 
 
 // Créer un premier toggle  
  t1 = controlP5.addToggle("toggleLED1",false,10,10,100,100); 
  // Configure les propriétés du Toggle  
  // méthodes propres à l'objet Toggle
  t1.setMode(ControlP5.DEFAULT); // fixe le mode de fonctionnement du Toggle : ControlP5.DEFAULT ou ControlP5.SWITCH
  // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
  // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
  // un toggle n'utilise que image Default et Active
  t1.setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageActive.png"),loadImage("imageDefault.png"));
 
 // Créer un deuxième toggle  
  t2 = controlP5.addToggle("toggleLED2",false,150,10,100,100);  
  // Configure les propriétés du Toggle 
  // méthodes propres à l'objet Toggle
  t2.setMode(ControlP5.DEFAULT); // fixe le mode de fonctionnement du Toggle : ControlP5.DEFAULT ou ControlP5.SWITCH

  // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
  // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
  // un toggle n'utilise que image Default et Active
  t2.setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageActive.png"),loadImage("imageDefault.png"));
 
 // Créer un troisième toggle
 t3 = controlP5.addToggle("toggleLED3",false,290,10,100,100);  
  // Configure les propriétés du Toggle  
  // méthodes propres à l'objet Toggle
  t3.setMode(ControlP5.DEFAULT); // fixe le mode de fonctionnement du Toggle : ControlP5.DEFAULT ou ControlP5.SWITCH
  // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
  // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
  // un toggle n'utilise que image Default et Active
  t3.setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageActive.png"),loadImage("imageDefault.png"));
 
 // Créer un quatrième toggle
 t4 = controlP5.addToggle("toggleLED4",false,430,10,100,100);  
  // Configure les propriétés du Toggle  
  // méthodes propres à l'objet Toggle
  t4.setMode(ControlP5.DEFAULT); // fixe le mode de fonctionnement du Toggle : ControlP5.DEFAULT ou ControlP5.SWITCH
  // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
  // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
  // un toggle n'utilise que image Default et Active
  t4.setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageActive.png"),loadImage("imageDefault.png"));
 
  // Créer un premier slider horizontal
  //("Nom du Slider", min,max, pos de depart, xpos,ypos, largeur,hauteur);
  controlP5.addSlider("MOTEURS", -50,50, 0, 100,200, 200,20);
   
  // Configure les propriétés du Slider
  Slider s1 = (Slider)controlP5.controller("MOTEURS");
  s1.setSliderMode(Slider.FLEXIBLE);
  s1.setNumberOfTickMarks(11);
  s1.showTickMarks(true);
  s1.snapToTickMarks(false);
 
 } 
  
// Dessine les objets choisis
void draw() {
  background(155); // 100 : fond gris
  fill(0);
  PFont maTypo=loadFont("ArialMT-14.vlw");
  textFont(maTypo,14);
   text ("Pelle",40,140);
   text ("Rotation",180,140);
   text ("Charge",320,140);
   text ("Flèche",460,140);
}
// Dans cette méthode
// on récupère la valeur 
// renvoyée par le slider moteurs     
// et on l'envoie à l'Arduino
 
void MOTEURS(float valeur_slider) {   
  int sens = 1; // marche avant moteur  
  // Récupérer la valeur envoyée par le slider entre -50 et 50  
  if (valeur_slider < 0) {
      sens= 0 ; // marche arriere
      valeur_slider = - valeur_slider;
  }      
  int vitesse = round(valeur_slider);// envoyer cette valeur à l'Arduino  
  serial.write (prefixe_moteurs);   
  serial.write (sens); 
  serial.write(vitesse);   
} 
void toggleLED1(int theValue) { // fonction évènement Toggle de meme nom - reçoit la valeur
        println("Evènement Toggle LED1 avec valeur = "+t1.getState());

        if (t1.getState()==true)serial.write(101); 
        // envoie caractère H sur port Série si bouton toggle état 1
        if (t1.getState()==false)serial.write(100); 
        // envoie caractère L sur port Série si bouton toggle état 0
}
void toggleLED2(int theValue) { // fonction évènement Toggle de meme nom - reçoit la valeur
        println("Evènement Toggle LED2 avec valeur = "+t2.getState());

        if (t2.getState()==true)serial.write(201); 
        // envoie caractère H sur port Série si bouton toggle état 1
        if (t2.getState()==false)serial.write(200); 
        // envoie caractère L sur port Série si bouton toggle état 0
}
void toggleLED3(int theValue) { // fonction évènement Toggle de meme nom - reçoit la valeur
        println("Evènement Toggle LED3 avec valeur = "+t3.getState());

        if (t3.getState()==true)serial.write(231); 
        // envoie caractère H sur port Série si bouton toggle état 1
        if (t3.getState()==false)serial.write(230); 
        // envoie caractère L sur port Série si bouton toggle état 0
}
void toggleLED4(int theValue) { // fonction évènement Toggle de meme nom - reçoit la valeur
        println("Evènement Toggle LED4 avec valeur = "+t4.getState());

        if (t4.getState()==true)serial.write(241); 
        // envoie caractère H sur port Série si bouton toggle état 1
        if (t4.getState()==false)serial.write(240); 
        // envoie caractère L sur port Série si bouton toggle état 0
}

Enfin sur chaque carte DFrduino, les codes sont ci-dessous :


/*
 * Slider 1 moteur
 * 4 relais 
 * Dfrduino
*/  
// Broches 2,7,8,10 : connectée relais
// --- Déclaration des constantes des broches E/S numériques ---

int PIN_ONOFF[4] = {2,7,8,10}; // Constante pour les broche 2,7,8,10;
  
int Pin_sens = 4; // le sens du moteur est commandé par la Pin 4 
int Pin_pwm = 5 ; // la vitesse du moteur est commandée par la Pin 5 
int pwm = 255;  // la largeur d'impulsion pwm (0-255) 

byte donnee_serie = 0;
 
void setup() {
   // Ouvrir la liaison série
   Serial.begin(9600);  
  // ------- Broches en sorties numériques -------  
  for(int i=0; i<4; i++)
  {
     pinMode (PIN_ONOFF[i],OUTPUT); // Broche LED configurée en sortie
  }  
} 
void loop() {
   
  int sens=0;
  int vitesse= 0;
 // int moteur=0;
   
   // Est-ce qu'il y a qq chose à lire sur l'interface série ?
    
   if (Serial.available()) {
     donnee_serie = Serial.read();
     
     if (donnee_serie==101) { // si Octet reçu est le H (101 = Marche / Etat Haut)
         digitalWrite(PIN_ONOFF[0], HIGH); // allume la LED
     }
     if (donnee_serie==100) { // si octet reçu est le L (100 = Arret / Etat Bas)
         digitalWrite(PIN_ONOFF[0], LOW); // éteint la LED
     }     
    if (donnee_serie==201) { // si Octet reçu est le H (101 = Marche / Etat Haut)
         digitalWrite(PIN_ONOFF[1], HIGH); // allume la LED
     }
     if (donnee_serie==200) { // si octet reçu est le L (100 = Arret / Etat Bas)
         digitalWrite(PIN_ONOFF[1], LOW); // éteint la LED
     } 

     if (donnee_serie==231) { // si Octet reçu est le H (101 = Marche / Etat Haut)

         digitalWrite(PIN_ONOFF[2], HIGH); // allume la LED
     }
     if (donnee_serie==230) { // si octet reçu est le L (100 = Arret / Etat Bas)
         digitalWrite(PIN_ONOFF[2], LOW); // éteint la LED
     }
        if (donnee_serie==241) { // si Octet reçu est le H (101 = Marche / Etat Haut)
         digitalWrite(PIN_ONOFF[3], HIGH); // allume la LED
     }
     if (donnee_serie==240) { // si octet reçu est le L (100 = Arret / Etat Bas)
         digitalWrite(PIN_ONOFF[3], LOW); // éteint la LED
     } 
	if (donnee_serie == 111) {       
          sens=lire_suivant(); // sens
         vitesse=lire_suivant(); // vitesse
         controle(sens,vitesse);                 
     }         
   } 
}           
 
int lire_suivant() {
while (1) { 
 
 if (Serial.available() ) {
      return (Serial.read());
 }
} // while
}
// la procédure de contrôle des moteurs
 
void controle (int sens, int v)         
// m : 1 ou 2 pour moteur 1 ou moteur 2, 
// sens : 1 ou 0 (avant ou arrière)
// v : vitesse de 0 à 50, 
{
        int pwm;
        pwm = map(v, 0,50, 0,255); 
// ramener vitesse à l'intervalle 0 255
        digitalWrite(Pin_sens,sens);  // fixer sens
        analogWrite (Pin_pwm,pwm);    // fixer vitesse
                              
 
}


/*
 * Slider1-2 moteurs
 * deux moteurs
 * Dfrduino
*/  
int tab_Pin_sens = 4 ; // le sens du moteur est commandé par la Pin 4 
int tab_Pin_pwm  = 5 ; // la vitesse du moteur est commandée par la Pin 5 

int tab_Pin_sens2 = 7 ; // le sens du moteur est commandé par la Pin 7
int tab_Pin_pwm2  = 6 ; // la vitesse du moteur est commandée par la Pin 6 

int pwm = 255;  // la largeur d'impulsion pwm (0-255) 
byte donnee_serie = 0;
 
void setup() {
   // Ouvrir la liaison série
   Serial.begin(9600);
} 
void loop() {   
  int sens=0;
  int vitesse= 0;  
   // Est-ce qu'il y a qq chose à lire sur l'interface série ?   
   if (Serial.available()) {
     donnee_serie = Serial.read();
     if (donnee_serie == 121) {       
         sens=lire_suivant(); // sens
         vitesse=lire_suivant(); // vitesse
         controle(sens,vitesse);                  
     }   // 121                         
     } // 1er serial available
} // loop   

int lire_suivant() {
while (1) {  
 if (Serial.available() ) {
      return (Serial.read());
 }
} // while
}

// la procédure de contrôle des moteurs 
void controle (int sens, int v)         
// sens : 1 ou 0 (avant ou arrière)
// v : vitesse de 0 à 50, 
{
        int pwm;
        pwm = map(v, 0,50, 0,255); 
// ramener vitesse à l'intervalle 0 255
         digitalWrite(tab_Pin_sens,sens);  // fixer sens moteur 1
         digitalWrite(tab_Pin_sens2,sens); // fixer sens moteur 2

         analogWrite (tab_Pin_pwm,pwm);    // fixer vitesse moteur 1
         analogWrite (tab_Pin_pwm2,pwm);   // fixer vitesse moteur 2
}

Grue à bec de canard – partie 1

Yves s’est inspiré d’un modèle de grue rencontré en voyage pour monter un modèle meccano.

grue à bec de canard

meccano arduino grue

Le modèle est très complet avec 6 moteurs commandant les différents mouvements. Il utilise deux DFRduino Roméo, un Shield Xbee pour pouvoir être commandé sans fil, un shield 4 relais. Une interface processing détaillée plus loin permet de commander les 4 mouvements à la souris, à partir d’un PC.

Les 4 moteurs de mouvements sont alimentés par deux batteries au plomb de 6V en série qui font office de contre-poids pour la flèche (boîte en parallélépipède en bout de flèche) et les deux moteurs couplés de roulement le sont par une batterie de 12V placée en arrière du châssis au niveau des moteurs.

Les cartes électroniques sont alimentées directement en 12V par les batteries reliées aux différents moteurs