Go Down

Topic: Interruption MotorShield Arduino (Read 565 times) previous topic - next topic

Floklo

Bonjour tout le monde,

Je suis en ce moment sur un petit projet, sur lequel je manipule un Arduino et son MotorShield, un microSwitch et un moteur DC 12V.
Lorsque le moteur fait un tour, un système mécanique appuie sur le bouton du microswitch, de sorte que je puisse compter ensuite le nombre de tour que fait le moteur.

Rien de compliqué. Mon problème vient de l'attribution des pins et de mon code ensuite. (c'est la première fois que je me sers d'un arduino. Il m'est imposé)

La pin 3 est pour la PWN relié au enable du L298 du motorshield.
la pin 12 est relié au In1 et In2 du L298 pour la direction (Pour le port A que j'utilise).

J'utilise la pin 6 en Output à +5V pour mettre au port COM du microswitch, et je relie la pin 2 au port VO3 du microswitch, de sorte qu'à chaque fois que le bouton est poussé, un état haut arrive sur ce port VO3, et donc sur la pin 2 du Arduino.
En effet sur la pin 2 se trouve le registre pour faire une interruption simple à programmer, en utilisant la fonction attachInterrupt().

A chaque fois que je charge le programme dans le Arduino, le moteur fait 1 tour et s'arrête. J'ai passé une journée dessus je ne vois pas si le problème vient de mon code (je ne pense pas) ou si il vient de la pin 2, qui doit avoir une autre fonction. Quand on regarde le schéma electrique du motorShield on remarque que la pin 2 (sur le schéma la partie POWER) est relié à l'entrée nommé IOREF. Je ne sais pas à quoi cela correspond.

Voila, je met un schéma de mon montage et mon code, merci pour votre future aide
Cordialement

Moteur: https://www.digikey.fr/product-detai...085-ND/6469521
Motor Shield: https://store.arduino.cc/arduino-motor-shield-rev3 (il y a le schéma électrique du motorshield)

Code: [Select]

//broche signal sens de rotation
const int in1 =12;

//broche +5V
const int in3 = 6;

//compteur
volatile int comp = 0;

const byte pinInterrupt = 2;

void stop_motor()
{
 analogWrite(enable, 0);
}

void incrementation()
{
  comp = comp + 1;
}

void setup()
{
  pinMode(enable, OUTPUT); //PWM
  pinMode(in1, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(pinInterrupt, INPUT);
   
  analogWrite(enable,200);
  digitalWrite(in1, HIGH);
  digitalWrite(6, HIGH);
  attachInterrupt(digitalPinToInterrupt(pinInterrupt), incrementation, LOW);
}

void loop()
{
  if(comp == 20)
  {
    stop_motor(); 
  }
}

3Sigma

Bonjour,

Ajoute un Serial.println(comp) dans ta loop pour voir l'état du compteur. Il est possible que ton microswitch génère un signal pourri avec plein de rebonds et que ça te mette comp à 20 dès le premier tour.

Floklo

Ok, merci.
Je viens de le faire, ça m'affiche des valeurs incohérentes :o

Je sais pas si le rebond du microswitch peut créer ce genre de chose...
ou mon code...

Je sèche complètement. 


hameau

Salut,

Le lien pour le moteur n'est pas valide, il tourne à quelle vitesse ce moteur ?, je pense que le moteur ne fait qu'un tour car la variable comp passe rapidement à 20 durant la phase d'appui sur le micro switch.

J'afficherai la valeur comp dans la boucle loop, genre :

Serial.println(comp);
Pour voir évolution de la variable durant le fonctionnement du moteur.



3Sigma

Ecris ça aussi:

pinMode(pinInterrupt, INPUT_PULLUP);

au lieu de:

pinMode(pinInterrupt, INPUT);

hameau

#5
Aug 22, 2017, 10:17 am Last Edit: Aug 22, 2017, 10:22 am by hameau
Pourquoi dans interruption incrémenter comp sur un front descendant et pas sur un front montant ? 

Code: [Select]
ttachInterrupt(digitalPinToInterrupt(pinInterrupt), incrementation, LOW);

Le LOW n 'est pas adapté , voir detail ci-dessous :
  • LOW : l'interruption est déclenchée quand la broche concernée est LOW. Comme il s'agit d'un état et non d'un événement, l'interruption sera déclenchée tant que la broche est LOW. Par conséquent, dès que l'ISR aura terminé son exécution, elle la recommencera. Pendant ce temps,
    loop() ne sera pas exécuté.
  • CHANGE : l'interruption est déclenchée quand la broche concernée change d'état, c'est à dire passe de LOW à HIGH ou bien de HIGH à LOW. Il s'agit d'un événement.
  • RISING : l'interruption est déclenchée quand la broche concernée passe de LOW à HIGH. Il s'agit également d'un événement.
  • FALLING : l'interruption est déclenchée quand la broche concernée passe de HIGH à LOW. Il s'agit encore d'un événement.

Floklo

Le moteur fait du 100tr/min à 12V, mais je met la PWM à 200 (sur 255), donc il tourne à peu prés à 80tr/min.

Mais ce qui est encore plus étrange, c'est qu'en mettant le Serial.println(), le moteur ne c'est plus arrêté du tout (au lieu des 1 tour habituel).
Je vais mettre un filtre en sortie du microswitch. connaissez vous une méthode de code pour arrêter le programme pendant quelques micro seconde après l'interruption ? apparement on ne peut pas utiliser delay() ni milli().

Et merci beaucoup pour votre aide !!

lien moteur : https://www.digikey.fr/product-detail/fr/copal-electronics-inc/MG16B-120-AB-00/563-2085-ND/6469521


hameau

Comme indiqué ci-dessus change le LOW en RISING dans interrption,

Floklo

Ok merci tout le monde, le problème est bien le microswitch...
J'ai effectué les changements que vous m'avez indiqués, mon compteur compte mieux (cf photo), mais mon moteur s'arrête au bout de 3 tours ^^, donc il faut mettre un filtre passe bas je pense en sortie du microswitch.

Merci beaucoup de votre aide !!

Je met le code, pour quelqu'un qui aurait le même problème :
Code: [Select]

//PWM pour la vitesse
const int enable = 3;

//broche signal sens de rotation
const int in1 =12;

//broche +5V
const int in3 = 6;

//compteur
volatile int comp = 0;

const byte pinInterrupt = 2;

void stop_motor()
{
 analogWrite(enable, 0);
}

void incrementation()
{
  comp = comp + 1;
  Serial.println(comp);
}

void setup()
{
  pinMode(enable, OUTPUT); //PWM
  pinMode(in1, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(pinInterrupt, INPUT_PULLUP);
  
  analogWrite(enable,200);
  digitalWrite(in1, HIGH);
  digitalWrite(6, HIGH);
  attachInterrupt(digitalPinToInterrupt(pinInterrupt), incrementation, FALLING);
  Serial.begin(9600);
}

void loop()
{
  
  if(comp >= 20)
  {
    stop_motor();  
  }
}

 

hameau

Va voir ici pour gestion anti rebond : http://eskimon.fr/96-arduino-204-un-simple-bouton


Floklo


Floklo

Re-bonjour

je reviens vers vous, car j'ai branché un condensateur 1 uF en parallèle de mon interrupteur.
Tout marche très bien lorsque j'appuie à la main sur l'interrupteur (i.e. le moteur ne tourne pas), le compteur compte un par un à chaque fois que j'appuie. Très bien !

Mais lorsque je fais la même manip en faisant tourner le moteur (i.e. à chaque tour le système mécanique appui sur l'interrupteur) le compteur compte 5 par 5 (en moyenne, ça varie).

Je soupçonne donc que l'alimentation du moteur via le motorshield crée plein d'interférence dans la carte Arduino ? Pensez vous que ce soit ça ?

Si oui cela veut dire qu'il faut je fasse un système à par de la partie logique pour alimenter et contrôler le moteur ? Bien compliqué pour un système aussi simple que le miens...

Cordialement

hameau

Tu alimentes comment le moteur shield en 12 V ? , car normalement du dois avoir une Alimentation pour la carte Arduino 5V si USB ou externe via connecteur noir dans les 7 V, et une alimentation pour le moteur 12 V dans ton cas.

Par contre il faut relier les GND ensemble, donc GND ARduino relier au GND alimentation Externe 12V.

Voila

Floklo

J'alimente la carte Arduino (en dessous) avec le port USB, et le shield avec une alim 12V via les ports voué à ça.

Et les GND du Arduino et de l'alim sont en commun.

Go Up