capter une vitesse et commander un moteur CC

Bonjour,
J'ai actuellement un programme permettant de faire tourner un moteur dans les 2 sens. Je dois capter la vitesse d'un vélo pour que mon moteur fonctionne. Mon moteur doit tourner dans un sens quand la vitesse dépasse 10km/h.
J'ai un compteur de vitesse avec un aimant et je me demandais si je pouvais capter le signal du compteur et l'utiliser pour dire quand mon moteur doit tourner.

J'ai sinon trouver un programme qui mesure la vitesse d'un moteur avec un capteur magnétique et je ne sais pas comment l'adapter pour ma roue de vélo (le rayon de la roue est de 35cm).
voici le lien vers le programme : http://atelierjcm.com/arduino/mesurer-la-vitesse-dun-moteur-avec-un-arduino-et-un-capteur-magnetique/
Merci de bien vouloir m'aider.

Si tu arrives à compter le nombre de tour de roue à la seconde ou minute c'est facile de connaitre la vitesse (théorique) en multipliant par le périmètre de la roue enfin je vais pas t'apprendre la regle de 3.

Si je calcule le nombre de changement d'état (état bas = aimant capté, état haut = aimant non capté) sur 15 secondes, logiquement il y a un état bas par tour quand l'aimant passe devant le capteur donc cela me donne le nombre de tours en 15 secondes. Je peux ensuite multiplier ce nombre par quatre pour l'avoir en tour/min non ?

Oui, si tu connais le nombre de tour en 15 secondes, tu multiplies par 4 pour connaître en 1 minute, ensuite multiplies par (Pi D) pour ta roue et tu connais ta vitesse en minute X 60 pour avoir en heure le tout mis en Km et tu connais ta vitesse en KM/H

Et pour avoir la vitesse en noeud :

  • tu divise par 400 grades,
  • tu multiplies par 360 degrés,
  • tu divises par 100 minutes de grades
  • tu multiplies par 60 minutes de degrés.

Voici le code que j'ai fais, je voudrais savoir si c'est cohérent. Je n'ai pas encore pu le tester car je n'ai pas encore le capteur.
J'utilise un motor shield aussi.

int DIR_A = 12;
int PWM_A = 3;
int BRAKE_A = 9;
int sensorPin= 1; // Pin reliée au capteur magnétique
int etat = 0; // etat Pin 
int ancien_etat = 0; // ancien etat Pin
long chrono = 0; // valeur courante du chrono
long chrono_depart = 0; // valeur de départ du chrono
long duree_test = 5000; // test sur 5 secondes
int nb_chgt = 0; // nombre de changement d'état, 1 par tour

void setup () {
  pinMode (DIR_A, OUTPUT);
  pinMode(BRAKE_A, OUTPUT); 
  pinMode(sensorPin,INPUT);  
  chrono_depart = millis();

}
void loop () {
 etat=digitalRead(sensorPin);
 if (millis()- chrono_depart < duree_test) { 
 if (etat != ancien_etat) { 
 nb_chgt = nb_chgt + 1 ;
 ancien_etat = etat; }
} else { 
if(nb_chgt*12 > 80)  // *12 pour avoir des tours/min

digitalWrite(BRAKE_A, LOW);
digitalWrite(DIR_A, HIGH);
analogWrite(PWM_A, 255);

   delay( 420 );
   
digitalWrite(BRAKE_A, HIGH);

}


 chrono_depart=millis();
 nb_chgt = 0;
 etat=digitalRead(sensorPin);
 
 if (millis()- chrono_depart < duree_test) { 
 if (etat != ancien_etat) { 
 nb_chgt = nb_chgt + 1 ;
 ancien_etat = etat; }
} else { 
if(nb_chgt*12 < 80)

digitalWrite(BRAKE_A, LOW);
digitalWrite(DIR_A, LOW);
analogWrite(PWM_A, 255);

    delay( 420 );
    
digitalWrite(BRAKE_A, HIGH);}
}

C'est pas faux mais ça fait quoi :
analogWrite(PWM_A, 255);
On peut peut-être trouver un ordre qui fait la même chose mais en plus simple ?

Attendre 15 secondes pour effectuer une mesure me semble bien long, avec des délais de réaction « poussifs ».
Pourquoi ne pas mesurer la durée pour un tour, en déduire la vitesse linéaire à partir du périmètre de la roue n’est pas très compliqué ?
V = L / T donc V = P / T.
La vitesse est alors en mètres par seconde, convertir en km/heure n’est pas sorcier.
Seule subtilité dans le programme : Mesurer avec une bonne précision la période T pour un tour.
Sans me prendre la tête, j’attends que l’aimant est passé, j’ouvre une boucle avec un compteur qui incrémente toutes les 1mS par exemple et j’arrête le comptage au retour de l’aimant. Nous avons alors la période en mS ce qui est certainement exagérément précis.

Bonjour,

68tjs:
C'est pas faux mais ça fait quoi :
analogWrite(PWM_A, 255);
On peut peut-être trouver un ordre qui fait la même chose mais en plus simple ?

Of course :wink:
Mais avec cette version on pourra faire oui/non/peut être, en plein dans la fuzzy logic. XD

Juste pour le plaisir un court extrait du fichier wiring_analog..c des librairies arduino :

void analogWrite(uint8_t pin, int val)
{
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
else
{
switch(digitalPinToTimer(pin))

/* Suite =
gestion de la PWM */

Bonjour,
J'ai actuellement un problème avec mon programme il ne fonctionne pas correctement.
J'ai donc fais deux programmes séparant les deux fonctions et ils fonctionnent parfaitement tout seul.

Celui-ci vérifie si la vitesse est supérieur à 10km/h et fait tourner le moteur dans un sens.
code 1 :

int DIR_A = 12;
int PWM_A = 3;
int BRAKE_A = 9;
int sensorPin= 2; // Pin reliée au capateur magnétique
int etat = 0; // etat Pin 
int ancien_etat = 0; // ancien etat Pin
long chrono = 0; // valeur courante du chrono
long chrono_depart = 0; // valeur de départ du chrono
long duree_test = 5000; // test sur 5 secondes
int nb_chgt = 0; // nb de changement etat Pin

void setup () {
  Serial.begin (19200);
  pinMode(sensorPin,INPUT);
  Serial.println ("En cours de mesure ...");
  chrono_depart = millis();
  pinMode (DIR_A, OUTPUT);
  pinMode(BRAKE_A, OUTPUT);
}

void loop() {
  etat = digitalRead(sensorPin);   
  if (millis()- chrono_depart < duree_test) { 
  if (etat != ancien_etat) { 
    
      nb_chgt = nb_chgt + 1 ;
      ancien_etat = etat;      
     }  
  } else {
  Serial.print  ("nombre de changement d'état : ");
  Serial.print (nb_chgt); 
  Serial.println (" changements");
   delay(5000); 
  if( nb_chgt*12>80){
  digitalWrite(BRAKE_A, LOW);
digitalWrite(DIR_A, HIGH);
analogWrite(PWM_A, 255);

   delay( 300 );
   
digitalWrite(BRAKE_A, HIGH);} 
  delay(10000);
  Serial.println ("En cours de mesure ...");  
  chrono_depart=millis();
  nb_chgt = 0;
}
}

Celui-ci vérifie si la vitesse est inférieur à 10km/h et fait tourner le moteur dans l'autre sens. Mais je veux que cette partie du code ne s'effectue qu'une fois que le moteur à tourné dans un sens car la vitesse était supérieur à 10km/h. Et mon moteur ne doit pas se remettre en route si la vitesse est encore supérieur à 10km/h au prochain test.
En gros quand le moteur a tourné dans un sens, après mon code ne doit que vérifier si la vitesse est inférieur à 10km/h. Une fois que la vitesse est inférieur à 10km/h il doit de nouveau verifier si la vitesse est supérieur à 10km/h.
Mais je n'y arrive pas donc je vous demande votre aide. Si mes explications ne sont pas claires ou s'il manque des infos dites le moi.
code 2 :

int DIR_A = 12;
int PWM_A = 3;
int BRAKE_A = 9;
int sensorPin= 2; // Pin reliée au capateur magnétique
int etat = 0; // etat Pin 
int ancien_etat = 0; // ancien etat Pin
long chrono = 0; // valeur courante du chrono
long chrono_depart = 0; // valeur de départ du chrono
long duree_test = 5000; // test sur 5 secondes
int nb_chgt = 0; // nb de changement etat Pin

void setup () {
  Serial.begin (19200);
  pinMode(sensorPin,INPUT);
  Serial.println ("En cours de mesure ...");
  chrono_depart = millis();
  pinMode (DIR_A, OUTPUT);
  pinMode(BRAKE_A, OUTPUT);
}

void loop() {
  etat = digitalRead(sensorPin);   
  if (millis()- chrono_depart < duree_test) { 
  if (etat != ancien_etat) { 
    
      nb_chgt = nb_chgt + 1 ;
      ancien_etat = etat;      
     }  
  } else {
  Serial.print  ("nombre de changement d'état : ");
  Serial.print (nb_chgt); 
  Serial.println (" changements");
   delay(5000); 
  if( nb_chgt*12<80){
  digitalWrite(BRAKE_A, LOW);
digitalWrite(DIR_A, LOW);
analogWrite(PWM_A, 255);

   delay( 300 );
   
digitalWrite(BRAKE_A, HIGH);} 
  delay(10000);
  Serial.println ("En cours de mesure ...");  
  chrono_depart=millis();
  nb_chgt = 0;
}
}

hadopix:
En gros quand le moteur a tourné dans un sens, après mon code ne doit que vérifier si la vitesse est inférieur à 10km/h. Une fois que la vitesse est inférieur à 10km/h il doit de nouveau verifier si la vitesse est supérieur à 10km/h.

Et avec des if(...) Else(...) et des "OU" (||) et des "AND" (&&) tu t'en sors pas?

Où est-ce que je pourrais rajouter des "OU" ou des "ET" ? Je n'en ai jamais utilité étant que je suis débutant ^^
Est ce que sa pourrait marcher avec une boucle "tant que" ? tant que la vitesse > 80 , alors faire le code 2 ? et faire la même chose avec tant vitesse < 80, alors faire le code 1 ?

bonjour,
des choses comme ca, c'est source d'erreur

if( nb_chgt*12<80){

ca serait mieux

if( (nb_chgt*12) < 80){

idem pour

if (millis()- chrono_depart < duree_test) {

En gros quand le moteur a tourné dans un sens, après mon code ne doit que vérifier si la vitesse est inférieur à 10km/h. Une fois que la vitesse est inférieur à 10km/h il doit de nouveau verifier si la vitesse est supérieur à 10km/h.
Mais je n'y arrive pas donc je vous demande votre aide. Si mes explications ne sont pas claires ou s'il manque des infos dites le moi.

vu que la vitesse est < à 10km/h pour vérifier si elle est > 10k/h
c'est un non sens, non?
ou alors pas clair

En fait, mon moteur sert à remonter et à descendre un système de roulette sur un vélo couché. Elles ne servent que pour le démarrage et quand on ralentit car c'est pour stabiliser un vélo couché au départ et à l'arrivée ou quand on freine.
Quand mon vélo démarre, les roulettes sont au sol, mon programme doit alors vérifier quand est ce que la vitesse est supérieur à 10km/h. Si la vitesse > 10km/h, le moteur tourne et la roulette se lève.
Ensuite il doit vérifier si la vitesse repasse sous 10km/h et si c'est le cas.
Si la vitesse < 10km/h, le moteur tourne dans l'autre sens et les roulettes redescendent.
Peut-être que c'est plus clair comme ça.
Mais quand j'ai testé le premier programme que j'avais fait, il tournais après chaque test dans un sens ou l'autre selon la vitesse ou alors il ne faisait rien.

hadopix:
En fait, mon moteur sert à remonter et à descendre un système de roulette sur un vélo couché.

On ne va pas tarder à voir arriver Jean-François :grin:

C'est juste que si mon moteur tourne deux fois de suite dans le même sens et ben le système appréciera pas ^^ et vélo ou vélo couché ou autre peut importe ^^

J'ai tenté de faire mon programme avec des boucles do...while mais je ne suis pas sur. Dites-moi ce que vous en pensez et si c'est juste.

int DIR_A = 12;
int PWM_A = 3;
int BRAKE_A = 9;
int sensorPin= 2; // Pin reliée au capateur magnétique
int etat = 0; // etat Pin 
int ancien_etat = 0; // ancien etat Pin
long chrono = 0; // valeur courante du chrono
long chrono_depart = 0; // valeur de départ du chrono
long duree_test = 5000; // test sur 5 secondes
int nb_chgt = 0; // nb de changement etat Pin



void setup ()

{
  Serial.begin (19200);
  pinMode(sensorPin,INPUT);
  Serial.println ("En cours de mesure ...");
  chrono_depart = millis();
  pinMode (DIR_A, OUTPUT);
  pinMode(BRAKE_A, OUTPUT);
}



void loop(){
do {                                                  // faire ce test tant que la vitesse < 10 km/h
  etat = digitalRead(sensorPin);
  
  if (millis()- chrono_depart < duree_test) { 
    
  if (etat != ancien_etat) { 
    
      nb_chgt = nb_chgt + 1 ;
      ancien_etat = etat;      
     }  
  } else {
    
  Serial.print  ("nombre de changement d'état : ");
  Serial.print (nb_chgt); 
  Serial.println (" changements");
  
   delay(5000);
   
if( nb_chgt*12>80){
  
 digitalWrite(BRAKE_A, LOW);
 digitalWrite(DIR_A, HIGH);
 analogWrite(PWM_A, 255);

   delay( 300 );
   
digitalWrite(BRAKE_A, HIGH);}

} }while((nb_chgt*12) <80);



do {                                                    // faire ce test tant que la vitesse > 10 km/h
  etat = digitalRead(sensorPin);  
  
  if (millis()- chrono_depart < duree_test) { 
    
  if (etat != ancien_etat) { 
    
      nb_chgt = nb_chgt + 1 ;
      ancien_etat = etat;      
     }  
  } else {
    
  Serial.print  ("nombre de changement d'état : ");
  Serial.print (nb_chgt); 
  Serial.println (" changements");
  
   delay(5000);
   
if( (nb_chgt*12) <80){
  
  digitalWrite(BRAKE_A, LOW);
  digitalWrite(DIR_A, LOW);
  analogWrite(PWM_A, 255);

   delay( 300 );
   
digitalWrite(BRAKE_A, HIGH);}

}
}while((nb_chgt*12) > 80);

}