Bonjour a tous.
En ce moment je suis sur une arène de robot pour les enfants, je test chaque partie séparément avant de tout regrouper. j'ai un problème avec millis() même si j'utilise BlockNot.
Mon problème est que je demande une attente de 3000ms, mais l'arduino n'attend pas. comme si mon temps été trop rapide.
if ((depart_rouge == 1) && (depart_bleu == 1)) {
led_bouton_rouge.blinkSingle(600);
led_bouton_bleu.blinkSingle(600);
timer = millis();
if ((timer - millis()) > 3000UL) {
niveau = 1;
}
}
Voila. dés que depart-rouge et depart-bleu sont égal a 1, niveau = 1 directement est pas au bout de 3 secondes. et que je met les UL ou non cela ne change rien.
j'ai le même problème en utilisant des bibliothéques de timer.
Quelqu'un pourrait m'aider svp? je ne voit pas ou est mon problème.
(est ce qu'un ancien code aurait pu modifier la vitesse des timers...??)
Presque vrai, mais ce qui est observé c'est que niveau passe à 1 tout de suite, alors que cette remarque conduirait à ce que la condition ne soit jamais vraie et que niveau n'atteigne jamais 1.
note: je dis presque vrai car entre les deux instructions, millis() s'est peut être incrémenté de 1 ou de 2.
Souvent millis n'aura pas le temps de s'incrémenter et la condition sera fausse. Mais parfois si millis() s'est incrémenté entre temps, on va avoir timer - millis() qui va valoir -1 ou -2, et comme les deux nombres sont certainement des unsigned, on va trouver 4294967295 ou 4294967294 qui est plus grand que 3000UL. La condition est vraie.
Remplace if ((timer - millis()) > 3000UL) {
par if ((millis() - timer) > 3000UL) {
Bonjour, je vous remercie déjà de vos réponse rapide.
je précise je suis encore débutant, j'ai fait quelques projets mais j'apprend encore chaque jour.
donc j'ai fait comme vous m'avez dit:
j'ai enlever mon timer = millis() qui était juste avant et je l'ai laisser dans le setup.
j'ai inversé pour millis() - timer
je vous met mon bout de code entier, car je sent que c'est une erreur bête que je fais mais je n'arrive à voir... (peut être la fatigue ou vérifier ma vue.. )
voici le code, c'est la partie pour le départ, quand un bouton est appuyer chaque depart s'incrémente de 1, une fois les deux départs égal a 1, l'arène se lance pour commencer le jeux.
#include <singleLEDLibrary.h>
#define bouton_rouge A11
#define bouton_bleu A10
sllib led_bouton_rouge(12);
sllib led_bouton_bleu(11);
byte depart_rouge = 0;
byte depart_bleu = 0;
byte niveau = 0;
unsigned long timer;
void setup() {
Serial.begin(9600);
pinMode(bouton_rouge, INPUT);
pinMode(bouton_bleu, INPUT);
timer = millis();
}
void loop() {
led_bouton_rouge.update();
led_bouton_bleu.update();
Serial.println(timer);
if (digitalRead(bouton_rouge)== LOW) {
depart_rouge = 1;}
if (digitalRead(bouton_bleu)== LOW) {
depart_bleu = 1;}
if (depart_rouge == 0) {
led_bouton_rouge.flickerSingle();}
if (depart_bleu == 0) {
led_bouton_bleu.flickerSingle();}
if (depart_rouge == 1) {
led_bouton_rouge.breathSingle(1000);}
if (depart_bleu == 1) {
led_bouton_bleu.breathSingle(1000);}
if ((depart_rouge == 1) && (depart_bleu == 1)) {
led_bouton_rouge.blinkSingle(600);
led_bouton_bleu.blinkSingle(600);
if ((millis() - timer) > 3000UL) {
niveau = 1;
}
}
if (niveau == 1) {
led_bouton_rouge.setOnSingle();
led_bouton_bleu.setOnSingle();
}
}
j'ai ajouter le Serial pour voir ce que afficher mon timer, mais il reste a 0, donc je fait millis() - 0 ..
Auriez vous une explication? que je comprenne mon erreur SVP?
Je vous remercie pour vos réponses.
oui j'ai un pullup externe sur chaque bouton.
depart_rouge et depart_bleu reste a 1, ils reviendront a 0 a la fin du jeux .
j'ai essayer en enlevant la bibliothéque au cas ou millis() était géné par celle ci, mais rien ne change.
en fait j'ai remarquer que la condition :
if ( (millis() - timer) > 3000) {
}
n'attend pas que les deux départ soit égal a 1, elle se fait au démarrage et je ne comprend pas pourquoi.
question peut être trés bête :
est il possible qu'un ancien code modifie la valeur de millis() ? et qu'en injectant un nouveau code la valeur reste modifié? (en sachant que j'ai le même résultat sur les deux méga, donc je doute que sa vienne de là..)
j'ai également essayer se code est le même résultat: si j'attend plus de 5 seconde niveau = 1 dés l'appuie du bouton, si j'appuie des le démarrage, niveau attend 5 seconde avant d'être égal a 1.
j'aimerais comprendre mon erreur..
Non. millis() et mis à zéro au reset de votre carte Arduino
si vous voulez tester l'appui des 2 boutons à moins de 5 secondes d'écart, vous pourriez faire cela
(tapé ici, non testé. mettre le moniteur série à 115200 bauds, pas la peine d'aller lentement)
const byte pinBoutonBleu = 11;
const byte pinBoutonRouge = 12;
unsigned long premierAppui;
bool departBleu = false;
bool departRouge = false;
void setup() {
Serial.begin(115200);
pinMode(pinBoutonBleu, INPUT);
pinMode(pinBoutonRouge, INPUT);
}
void loop() {
if (!departBleu && digitalRead(pinBoutonBleu) == LOW) {
if (!departRouge) premierAppui = millis();
departBleu = true;
}
if (!departRouge && digitalRead(pinBoutonRouge) == LOW) {
if (!departBleu) premierAppui = millis();
departRouge = true;
}
if ((departRouge || departBleu) && (millis() - premierAppui >= 5000)) {
Serial.println(F("un bouton avait été appuyé mais l'autre non et 5s sont passées"));
departBleu = false;
departRouge = false;
premierAppui = 0; // pas obligatoire, mais pour que ce soit comme au début
}
if (departBleu && departRouge) {
Serial.println(F("Les deux boutons ont été appuyés à moins de 5s d'écart. GO !"));
while (true) yield(); // on s'arrête là pour ce code de démo
}
}
Je vous remercie beaucoup.
Là le temps est bon donc sa vient bien de mon code que je doit trouver l'erreur, j'avais peur pour ma carte..
-donc je vais essayer de modifier ce que vous m'avez pour que niveau ==1 5 seconde après l'appuie des deux boutons (chaque joueurs appuie sur son bouton quand il est prêt, une fois fait au bout de 5 seconde le jeux se lance).
Deux petites questions en plus pour mieux comprendre et évoluer:
- Est ce que vous arriverez à m'expliquer votre ligne :
while (true) yield();
cela fait quoi exactement ?
(si je range ce bout de code dans un "void depart()", cette ligne va arréter seulement se void ou tout le code ?
- Ne pas mettre les {} après le deuxième if, cela change quelque chose ou non?
Je tiens à vous remercier énormément !!!!!!
vous m'avez enfin débloquer sur ce morceaux.
j'ai pu modifier quelque truc et adapter et cela fonctionne parfaitement.
il ne me reste plus qu'à trouver comment faire pour mes servo moteur et millis() encore une fois et je pourrais enfin mettre le jeux en marche normalement .
Je vous remercie énormément .
Si l'envi et le courage vous viens pour une aide pour mes servo moteur, vous ferez des heureux
En tout cas je vous remercie sincèrement de votre aide.
le code se bloque à cet endroit. c'est une boucle infinie. yield() est une fonction de l'environnement arduino qui évite que la carte ne reboot toute seule (certaines cartes ont un watchdog est si le code est bloqué dans une boucle infinie et donc ne sort pas de la loop (ou ne passe pas dans quelques autres fonctions comme delay) assez vite alors la carte redémarre)
j'ai mis ça pour que le code se "termine" une fois les 2 boutons appuyés mais bien sûr dans votre cas il ne faut pas !