Le code marche! Il suffisait de calculer la variable tour dans le loop et non dans attachinterrupt. Je ne sais pas pourquoi ça ne fonctionnait pas mais là ça va. Merci à tous
Version imprimable
Le code marche! Il suffisait de calculer la variable tour dans le loop et non dans attachinterrupt. Je ne sais pas pourquoi ça ne fonctionnait pas mais là ça va. Merci à tous
Je suis perplexe, on peut voir ton code ?
Bonsoir
Moi je ne comprends pas la modification, car tour n'est jamais calculé:
- Il est initialisé à 0 dans le setup()
- Il est remit à 0 après chaque envoi de résultat sur le moniteur série dans le loop() pour le 1er programme, et dans l’interruption pour le 2ème programme.
- Et il est incrémenté à chaque interruption, et cela doit être dans l'interruption.
Donc comme Auteur, j'aimerais bien voir le code qui marche, merci d'avance :)
Bonne soirée
Delias
J'ai une prof qui s'est aperçue que le comptage de la variable tour se faisait normalement lorsqu'il est compté dans le loop. J'ai donc modifié le programme pour qu'à chaque front descendant le calcul se fasse dans le loop. Ensuite, avec la fonction fournie par delias je me suis aperçue que la variable se comptait en doublon à chaque passage du trou. J'en ai déduit que cela devait être du à la grosseur du trou (6mm de diamètre). Voilà donc mon code qui m'a tout l'air de marcher
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 //capteur port OUT relié au pin2 de l'arduino const int pinCapteur=2;//on utilise le pin 2 (avec arduino uno pin 2 ou 3 pour les interruptions) // pour le pin2 l'interruption se fait sur le pin0 // Initialisation des variables volatile unsigned int Mesure; //variable qui compte le nombre de mesures volatile float trmin; // variable qui affichera la vitesse du disque en tour/min volatile unsigned long temps; //sert à déterminer le temps que met le disque pour réaliser exactement un tour volatile int tour; //compte le nombre de tours du disque const int n=100; //nombre de tours du disque avant de faire le calcul de vitesse unsigned long dT; volatile bool mesuredispo; //permet l'affichage lorsqu'une nouvelle mesure est disponible volatile bool ok; //permet de savoir si le disque a fait exactement un tour void setup() { Serial.begin(9600); //connection au port série pinMode(pinCapteur, INPUT); //connection du capteur au pin2 de l'arduino //Initialisation des variables tour=0; trmin=0; Mesure=0; temps=millis(); mesuredispo=false; //on appelle la fonction NouveauTourInterrupt dès qu'il y a un changement d'état abscence(HIGH) vers présence(LOW) du trou du disque, c'est à dire dès que le disque fait exactement un tour //attachInterrupt(interruption,fonction,mode) attachInterrupt(0,nouveauTourInterrupt,FALLING); } void loop() { //si il y a eu un tour du disque if (ok){ ok=0; tour++; //à cause de la surface du trou à chaque passage du trou la valeur tour augmente de 2 } //si il y a eu n tour du disque if (tour >= n){ // trmin= (n* 60000)/ (2*temps écoulé pour faire n tours du disque en minute 1min=60 000ms //on divise par 2 pour corriger l'écart //entre millis et temps il y a eu exactement 1 tour dT=millis()-temps; trmin= ((unsigned long)60000*n)/(2*dT); Mesure++; mesuredispo=true; } if (mesuredispo){ Serial.print("Mesure:"); Serial.print(Mesure); Serial.print(" vitesse en tour/min: "); Serial.println(trmin); //Serial.print("nb de tours: "); //Serial.println(tour); //Serial.print("temps entre deux mesures en ms: "); //Serial.println(dT); //Réinitialisation du temps et du nombre de tours temps=millis(); tour=0; mesuredispo=false; } } //Dès qu'il y a 1 nouveau tour on appelle la fonction void nouveauTourInterrupt() { ok=1; }
Bonjour
Tu crées un anti-rebond, l’interruption est probablement appelée 2x avant que le code dans le if (ok) n'aie été appelé.
Si tu avais mesuré le temps entre chaque interruption, tu aurais probablement des durées de 0 ou 1 ms, séparées par des durées plus longues correspondant à 1 tour (20ms à 3000tpm).
Pour cela il faudrait avoir un code dans cette idée (écrit en direct et non testé:!:), 20 et 60 gageraient à être des constantes:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 ... volatile unsigned long temps[20]; ... void loop() { if (tour>60) { for (int i = 1; i<20; i++){ Serial.println(temps[i] - temps[i-1]); } tour = 0; } } void nouveauTourInterrupt() { tour++; if (tour<20) { temps[tour] = millis(); } } }
Hummm.... C'est pas normal tout ça, ça sent la solution qui masque un bug sans pour autant l'avoir résolu ! C'est le pire cas de figure en développement car si ce bug se réveille on ne sait pas où chercher (puisqu'on croit l'avoir résolu)
Est ce qu'on peut voir la tête du signal, à l'oscilloscope, qui sort du capteur lorsque le disque tourne ?
-Faire une copie d'écran lorsque le capteur est simplement alimenté et non connecté à l'entrée d'interruption du Arduino
- Faire une copie d'écran lorsque tout est connecté (alimentation + signal au Arduino)
Je me demande si le signal est "Franc" et si il n'y a une espèce de jitter ?