Bonjour,
J'ai un souci avec une commande IF qui ne fonctionne pas comme elle devrait.
Objectif : Arrêter la rotation d'un servomoteur quand le détecteur IR est coupé (réf : B081TYP382). Je récupère la position du servomoteur par un servo.Read, je teste l'état du détecteur mais quand je fais le test sur ces deux variables, la réaction du IF n'est pas correcte:
Code : #include <Servo.h>
Servo myservo; // create servo object to control a servo
volatile int state = 1; // positiion 0 ou 1 du detecteur laser
volatile unsigned long button_time = 0; //
volatile unsigned long last_button_time = 0; //
int debounce = 50; #define SENSOR_PIN_2 2 // pin du detecteur laser
const int val = 50; // Position du moteur sortie 2
int vread;
void loop() {
for (int i = 0; i <= val; i ++) {
vread = myservo.read();
if(!state && vread >= val) {
break;
}
else if(state) {
myservo.write(etat);
delay(30);
}
}
}
Si je teste "!state && vread >= val" la boucle ne passe jamais par ce qui suis, si je test uniquement sur "!state" ça fonctionne.
Je récupère bien la valeur du read (je fais des prints de controle) mais ce double test ne fonctionne jamais.
Le "state" fonctionne parfaitement (print de controle) et j'arrête parfaitement la rotation sur le simple test de "state".
Je m'arrache les cheveux la-dessus depuis plusieurs heures (voire jours) sans comprendre ce qui se passe.
Quelqu'un aurait-il une idée ?
Je précise que je souhaite passer par un IR pour arrêter la rotation et non sur la rotation du servomoteur pour plus de sécurité. J'ai plusieurs positions d'arrêt possibles selon des paramètres variables. Pour le moment je veux juste tester une valeur avec State, mais comme ça ne marche pas, je n'avance pas plus loin.
Merci pour votre aide.
Merci de prendre en compte les recommandations listées dans "Les bonnes pratiques du Forum Francophone” et postez un code complet avec les balises de code (et corrigez celui du premier post).
quand vous utilisez des variables partagées avec l'ISR, il faut mettre cela en section critique
Voici mon code, mais j'ai trouvé mon erreur. Je teste "etat >= val && !state" puis je fais "else if (state)". Donc la rotation s'arrête alors que je souhaite qu'elle continue jusqu'à atteindre la valeur "val". Si je fais juste le "else", sans retester "state" ça marche.
Je suis navré de vous avoir dérangés et vous remercie pour votre aide, utile car elle m'a forcé à relire pour la enième fois mon programme et de trouver mon erreur.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
const int bout1 = 8;
int val = 50;
int vitesse = 1;
int etat = 0;
volatile int state = 1;
volatile unsigned long button_time = 0;
volatile unsigned long last_button_time = 0;
int debounce = 50; /
#define SENSOR_PIN_2 2 // pin du detecteur laser
void setup() {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(SENSOR_PIN_2), blink, CHANGE); // attache l’interruption externe n°0 à la fonction blink
pinMode(SENSOR_PIN_2, INPUT);
pinMode(bout1, INPUT_PULLUP);
myservo.write(0);
myservo.attach(3); // attache l'objet servo à la pin 3 Rotation
}
void loop() {
/**** récupération de la valeur du bouton saisie et affectation des variables associées */
// if (digitalRead(bout1) == 1)
{
{
for (etat = valx; etat <= 60; etat += vitesse) {
Serial.print(" State = ");
Serial.print(state);
Serial.print(" val = ");
Serial.println(val);
if (etat >= val && !state) {
Serial.print(" etatB = ");
Serial.println(etat);
break;
}
else if (state) {
myservo.write(etat);
Serial.print(" etatC = ");
Serial.println(etat);
delay(30);
}
}
}
}
}
void blink() // la fonction appelée par l’interruption externe n°0
{
button_time = millis();
if (button_time - last_button_time > debounce)
{
state = !state; // inverse l’état de la variable
Serial.print(" - State = ");
Serial.println(state);
last_button_time = button_time;
}
}
ne faites pas un print dans l'interruption, même si ça fonctionne il ne faut pas ralentir l'ISR
sinon comme déjà mentionné il faut dans la loop soit travailler en section critique (interruptions désactivées) pour tout le traitement qui touche les variables partagées avec l'ISR, soit faire une petite section critique dans laquelle vous dupliquez les valeurs des variables partagées et la loop travaille sur les copies