Le problème c'est que ce n'est pas hyper précis, mais surtout c'est que au bout d'une trentaines de secondes, ça ne fonctionne plus.
De l'autre côté du net, on a du mal à savoir ce qui ne marche plus, il faut souvent dire précisément ce qui ne marche plus. Par exemple au bout de 30 secondes le régulateur de la carte fume, ou au liei d'avoir un affichage de 100 pour 100Hz, j'ai un affichage de 200 ou au début, cela m'affiche 100 toutes les secondes et au bout de 30s, ça affiche des 1...
Bon, le piège est classique. millis() donne le temps en millisecondes et tu essaie de mettre cela dans un int qui est capable de mémoriser un nombre entre -32768 et +32767. Donc dans les 32 premières secondes tout va bien. 0 la 33ème seconde, millis() vaut 33000 et tu fais
temps = millis();
temps va déborder et il contiendra 33000-65536 soit -32536. A la boucle suivante il y a le test
if ((millis() - temps) >= 1000)
millis() n'a pas eu le temps de changer et on aura
if ((33000 - (-32536)) >= 1000)
soit:
if ((33000 + 32536) >= 1000)
test qui est encore vrai, on va ainsi rentrer dans la boucle à chaque fois. L'erreur arrive donc à la 33ème seconde. Je suppose que c'est ce que tu n'a pas décrit.
Pour éviter cela, comme millis() est un unsigned long, il faut aussi prendre temps en unsigned long. Il n'y ara plus le plantage à 33s.
Maintenant il y a es choses bizarres. Pendant une seconde on n'entre pas dans le if et il reste:
void loop()
{
attachInterrupt(0, RPM, RISING);
}
Je ne sais pas trop ce qui se passe si on appelle attachInterrupt plusieurs fois par ms. Il vaudrait mieux mettre attachInterrupt dans le if? Ainsi il serait exécuté qu'une fois:
void loop()
{
if ((millis() - temps) >= 1000)
{
detachInterrupt (0);
nbpuls = pulscount;
Serial.println(nbpuls);
temps = millis();
pulscount = 0;
attachInterrupt(0, RPM, RISING);
}
//tone(13, 50); // signal carré sortie sur pin 13 31Hz mini 65535Hz maxi
}
Mais si c'est pour faire cela, autant mettre en place l'interruption dans le setup, et dans loop suspendre les interruptions par noInterrupts() et les remettres à la fin par interrupts()
nbpuls ne sert que pour l'affichage, pourquoi l'utiliser plutôt que de mettre Serial.println(pulscount);
Les gens sont paresseux, si tu utilises la vitesse de 115200 bauds, c'est plus facile à tester pour les autres. Pour toi, cela ne change rien qu'une seule fois, il faut mettre ta console à cette vitesse une fois pour toutes.
Mais tu risques en passant à 115200bauds de trouver plus de monde qui pourra tester.
Dans la boucle il y a une instruction longue (attachInterrupt) Supposons qu'elle dure 0,3s (c'est beaucoup beaucoup moins que ça, mais c'est plus facile à comprendre)
On démarre t=0
t=0, pas de test
attachInterrupt dure 0,3s, il est t=300ms
t=300, pas de test
attachInterrupt dure 0,3s, il est t=600ms
t=600, pas de test
attachInterrupt dure 0,3s, il est t=900ms
t=900, pas de test
attachInterrupt dure 0,3s, il est t=1200ms
t=1200, test on affiche ce qui s'est passé pendant 1200ms
attachInterrupt dure 0,3s, il est t=1500ms
t=1500, pas de test
attachInterrupt dure 0,3s, il est t=1800ms
t=1800, pas de test
attachInterrupt dure 0,3s, il est t=2100ms
t=2100, test on affiche ce qui s'est passé pendant 1100ms
attachInterrupt dure 0,3s, il est t=1500ms
...
Si la boucle de mesure est longue, on va la terminer avec une erreur de l'ordre de sa durée. Pour pur qu'il y ait tone en plus de attachInterrupt...
Tone n'a rien à faire dans loop(); si on en a besoin, c'est pour avoir un signal carré, autant la mettre dans seup()
pulscount est un entier signé. Autant mettre un entier non signé.
Quand on déclare les variables, elles sont initialisées à 0. Ce n'est pas la peine de les réinitiliser dans le setup. Si on veut insister sur le fiat qu'o les veut à 0, on peut le faire dans la déclaration:
volatile unsigned int pulscount=0;