J'aimerais lire mon encodeur lorsque l'axe qui le supporte tourne dans un sens ou dans l'autre et ainsi incrémeter ou décrémenter un compteur.
Pour cela j'utilise une déclaration attachinterrupt(pin,fonction,CHANGE).
Pour cela j'ai un capteur 2 voies et un moteur à courant continu.
Je fais tourner le moteur dans un sens puis dans l'autre grâce à une boucle que j'effectue 5 fois par exemple. Et pour ce faire, j'utilise les classiques : high et low sur les broches du moteur, ça fonctionne bien et ça s'arrête après la 5ème fois.
Malheureusement, le port série n'affiche que le numéro de la boucle et rien d'autre alors que j'ai bien créé mes attachinterrupt() et mes fonctions qui appellent une fonction d'affichage lorsqu'il y a un changement sur les bornes du capteur.
Pourriez-vous m'indiquer où est mon erreur s'il vous plait ?
#include <Encoder.h>
#define ENCODER_USE_INTERRUPTS
#include <digitalWriteFast.h>
// sensorInPin = 2 fil bleu du capteur sur l'Arduino UNO sur ligne d'interruption
// sensorRedPin = 3 fil rouge du capteur sur l'Arduino UNO sur ligne d'interruption
Encoder myenc(2,3);
const int sensA=6; //borne sens horaire du moteur sur pin 6 du shield moteur
const int sensB=7; //borne sens anti-horaire du moteur sur pin 7 du shield moteur
const int L298N_enA=4; //contrôle de la vitesse du moteur sur pin 4 du shield moteur
int pwmMoteur=5; //borne du capteur
unsigned char i = 0;
volatile long newPosition = 0;
void setup()
{
Serial.begin(115200); //connection série initialisée à 115200 bauds/s
pinMode(pwmMoteur,OUTPUT) ;
pinMode(sensA,OUTPUT) ;
pinMode(sensB,OUTPUT) ;
pinMode(pwmMoteur, OUTPUT);
attachInterrupt(sensA, gestioninterruption2, CHANGE);
attachInterrupt(sensB, gestioninterruption3, CHANGE);
}
void loop()
{
while(i<5) {
Serial.println("");
Serial.print(i+1);
//rotation sens horaire
digitalWrite(sensA,HIGH) ;
digitalWrite(sensB,LOW) ;
analogWrite(pwmMoteur,255) ;
delay(500) ;
//pour l'arret
digitalWrite(sensA,HIGH) ;
digitalWrite(sensB,HIGH) ;
delay(500) ;
//rotation sens anti-horaire
digitalWrite(sensA,LOW) ;
digitalWrite(sensB,HIGH) ;
delay(500) ;
//pour l'arret
digitalWrite(sensA,HIGH) ;
digitalWrite(sensB,HIGH) ;
delay(500) ;
i++;
}
}
void gestioninterruption2()
{
if (digitalReadFast2(2)== digitalReadFast2(3)) {
newPosition--;
affiche();
}
else {
newPosition++;
affiche();
}
}
void gestioninterruption3()
{
if (digitalReadFast2(3)== digitalReadFast2(2)) {
affiche();
newPosition++;
}
else {
newPosition--;
affiche();
}
}
void affiche()
{
newPosition = myenc.read();
Serial.print("Encoder is at: "); // print the position
Serial.println(newPosition);
}
J'ajoute que la diode LD3 de l'arduino clignote lorsque je tourne à la main l'axe du moteur tout doucement, j'ai bien une interruption qui semble se faire...
D'autre part serial.print utilise les interruptions pour transférer les données.
Pendant le déroulement d'une ISR, les autres interruptions sont bloquées
Autrement dit, tu ne peu pas appeler serial.print à l'intérieur d'une ISR
J'ai revu mon code encore plus simplement pour partir sur de meilleures bases avec le code qui suit.
Mon interrogation maintenant : est-il possible de faire tourner le moteur pendant x seconde tout en utilisant la fonction attachinterrupt(), car j'ai l'impression que le moteur va continure à tourner du fait de la fonction.
Je ne vois pas pourquoi le moteur continuerait à tourner du fait de l'interruption. Il va s'arrêter quand tu lui demande de s’arrêter.
Par contre ta gestion d'it est trop simpliste, elle ne prend pas en compte le sens.
Aussi je ne vois pas l'intérêt de ça: if (_EncoderTicks > 32766) ...
Il faudrait connaitre la fréquence des interruptions (qui dépend de la vitesse et de la résolution du codeur) pour répondre précisément, mais il y a toutes les chances pour que ce soit assez rapide.