Compte a rebours simple

Je suis débutant sur arduino
J'ai un projet de machine piloté par
Arduino et carte Shield CNC (avec 3 stepper) et un LCD 20x4

je cherche a simplement afficher un compte a rebours sur une ligne comme ceci:
"Temps restant 30:00" et un décompte de seconde en seconde.

sans bouton, sans led, juste faire que le programme continu après le 00:00

Quelqu'un peu m'aider svp

:warning:

Post mis dans la mauvaise section, on parle anglais dans les forums généraux. ➜ déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans “Les bonnes pratiques du Forum Francophone”

Si tu es débutant, je te conseille d'abord de te former à l'Arduino et au langage C. Des liens sont disponibles dans les messages épinglés du forum. Celui-ci est très bien.

Ta demande peut être résolue de manière très simple mais qui ne conviendra peut-être pas à un besoin final. C'est à voir...

La solution la plus simple fera un code dit 'bloquant' : on va arrêter le microcontrôleur chaque seconde pendant une seconde, puis lui demander de diminuer le temps. Ca ressemblera à ça (affichage sur la console de l'IDE Arduino) :

int temps = 30*60; // 30 minutes
void setup() {
Serial.begin(115200); // régler la console sur ce chiffre aussi
}
void loop() {
int minutes = temps/60;
int secondes = temps%60;
Serial.print(minutes);
Serial.print(':');
Serial.println(secondes);
delay(1000); // Apnée pendant une seconde...
temps--;
if (temps == 0) while(1); // Boucle infinie si on atteint 0
}

A tester...

Merci beaucoup pour ton aide, j'ai réussi l'affichage en intégrant la bibliothèque.
J'ai n'ai par contre pas d'attente de fin de compte a rebours pour que le programme continu, la minuterie s'affiche bien et la suite d'affichage se superpose.
Comment faire pour que le logiciel attende la fin du compteur ?
Merci

Voici le code que j'utilise...

#include <LiquidCrystal_I2C.h>
int temps = 30*60; // 30 minutes
LiquidCrystal_I2C lcd(0x27, 20, 4); 
void setup() 
{
lcd.init(); // initialisation de l'afficheur 
}
void loop() 
{
// affichage du LCD
lcd.backlight();
lcd.setCursor(0,3); 
int minutes = temps/60;
int secondes = temps%60;
lcd.print("Delai: ");
lcd.print(minutes);
lcd.print(':');
lcd.println(secondes);
delay(1000); // Apnée pendant une seconde...
temps--;
if (temps == 0) while(1); // Boucle infinie si on atteint 0

lcd.clear();
delay(10);
lcd.setCursor(0, 0); 
lcd.print("Demarrage programme"); 
lcd.setCursor(0, 1); 
lcd.print("Prelavage essence"); 
lcd.setCursor(0, 2); 
lcd.print("Numero 1/3");
}

Mettre

// affichage du LCD
while (temps > 0) // 0n boucle tant que le décompte n'est pas terminé
{
  lcd.backlight();
  lcd.setCursor(0,3); 
  int minutes = temps/60;
  int secondes = temps%60;
  lcd.print("Delai: ");
  lcd.print(minutes);
  lcd.print(':');
  lcd.println(secondes);
  delay(1000); // Apnée pendant une seconde...
  temps--;
}

dans le setup, vu que cela ne sera fait qu'une seule fois. Et boucler tant que le temps n'est pas fini
Bien entendu retirer cette partie de loop

Il faut peut-être effacer l'écran au début du bloc while pour éviter des superpositions de chiffres. Et ajouter des '0' lorsque les chiffres sont inférieurs à 10.
Je pense que la ligne lcd.backlight(); devrait être avant le while.

Bon j’ai vraiment essayé mais je suis nul en syntaxe et je n’y arrive pas.
Pour faire simple
J’ai un carte arduino uno et un carte shield cnc avec 3 stepper.
Je veux afficher un message avec une minuterie et en meme temps faire tourner le stepper x.
A la fin du compte a rebours.
Arrêt du stepper x
Un autre message avec un autre compte a rebours et rotation du stepper y
Arrêt du stepper y
Et enfin
Un autre message avec un compte a rebours et rotation du stepper z
Arrêt du stepper z
Désolé d’insister mais c’est pourtant simple je pense mais je galère.
Si tu peux me remettre de l’ordre dans mon code se serai génial… merci

Je suis horloger et j’essaye de faire une machine pour laver les mécanismes, d’ou ma demande

Voici mon code


#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int temps = 30*60; // 30 minutes

const int StepX = 2;
const int DirX = 5;
const int StepY = 3;
const int DirY = 6;
const int StepZ = 4;
const int DirZ = 7;

LiquidCrystal_I2C lcd(0x27, 20, 4); 
void setup() 
{

  lcd.init(); // initialisation de l'afficheur 
  pinMode(StepX,OUTPUT);
  pinMode(DirX,OUTPUT);
  pinMode(StepY,OUTPUT);
  pinMode(DirY,OUTPUT);
  pinMode(StepZ,OUTPUT);
  pinMode( DirZ,OUTPUT);
}

void loop() 

{
while (temps > 0) // 0n boucle tant que le décompte n'est pas terminé
{
  lcd.backlight();
  lcd.setCursor(0,3); 
  int minutes = temps/60;
  int secondes = temps%60;
  lcd.print("Delai: ");
  lcd.print(minutes);
  lcd.print(':');
  lcd.println(secondes);
  delay(1000); // Apnée pendant une seconde...
  temps--;
}
 digitalWrite(DirX, HIGH); // set direction, HIGH for clockwise, LOW for anticlockwise
 digitalWrite(DirY, HIGH);
 digitalWrite(DirZ, HIGH);

// affichage du LCD
lcd.backlight();

// Envoi du message
lcd.setCursor(0, 0); 
lcd.print("  ----------------  "); 
lcd.setCursor(0,1); 
lcd.print("Depart du programme"); 
lcd.setCursor(0, 2); 
lcd.print("      de lavage     "); 
lcd.setCursor(0, 3); 
lcd.print("  ----------------  ");
// fin affichage LCD 

delay(1000); // delay for 1 second
 //-------------------- MOTEUR X------------------------------
// Envoi du message 
lcd.clear();
delay(10);
lcd.setCursor(0, 0); 
lcd.print("Demarrage programme"); 
lcd.setCursor(0,1); 
lcd.print(" "); 
lcd.setCursor(0, 2); 
lcd.print("Prelavage essence"); 
lcd.setCursor(0, 3); 
lcd.print("Bocal Numero 1/3");
// fin affichage LCD 
delay(2000); // delay for 2 second
// Lancement du moteur X
 for(int x = 0; x<2000; x++) { // loop for 200 steps
  digitalWrite(StepX,HIGH);
  delayMicroseconds(500);
  digitalWrite(StepX,LOW); 
  delayMicroseconds(500);
 }
  // Fin Lancement moteur
 delay(2000); // delay for 2 second
 
//---------------------- MOTEUR Y-----------------------------
  // Envoi du message 
lcd.clear();
delay(10);
lcd.setCursor(0, 0); 
lcd.print("Programme"); 
lcd.setCursor(0,1); 
lcd.print(" "); 
lcd.setCursor(0, 2); 
lcd.print("Lavage essence"); 
lcd.setCursor(0, 3); 
lcd.print("Bocal Numero 2/3");
// fin affichage LCD 

 delay(2000); // delay for 2 second
 // Lancement du moteur Y
for(int x = 0; x<800; x++) { // loop for 200 steps
  digitalWrite(StepY,HIGH);
  delayMicroseconds(500);
  digitalWrite(StepY,LOW); 
  delayMicroseconds(500);
  }
 // Fin Lancement moteur

delay(2000); // delay for 2 second
//------------------------MOTEUR Z-------------------------------

// Envoi du message 
lcd.clear();
delay(10);
lcd.setCursor(0, 0); 
lcd.print("Programme"); 
lcd.setCursor(0,1); 
lcd.print(" "); 
lcd.setCursor(0, 2); 
lcd.print("Fin lavage essence"); 
lcd.setCursor(0, 3); 
lcd.print("Bocal Numero 3/3");
// fin affichage LCD 
delay(2000); // delay for 2 second
// Lancement du moteur Z
for(int x = 0; x<4000; x++) { // loop for 400 steps
  digitalWrite(StepZ,HIGH);
  delayMicroseconds(500);
  digitalWrite(StepZ,LOW); 
  delayMicroseconds(500);
 }
 // Fin Lancement moteur
delay(2000); // delay for 1 second

// Envoi du message 
lcd.clear();
delay(10);
lcd.setCursor(0, 0); 
lcd.print("Fin du programme"); 
lcd.setCursor(0,1); 
lcd.print(""); 
lcd.setCursor(0, 2); 
lcd.print(""); 
lcd.setCursor(0, 3); 
lcd.print("");
// fin affichage LCD 
exit(0);
}

Il faut bien préciser une chose : est-ce que tout ceci est exécuté à la file (séquentiel) ou en parallèle ? C'est pas hyper clair dans ta description...
Dans le premier cas, un code bloquant comme celui sur lequel on travaille est bien adapté, pas dans le second cas.

Moi, je comprends que le moteur x travaille, puis s'arrête et le moteur y se lance, puis s'arrête, et ensuite le moteur z se lance et s'arrête. Si tu veux que les moteurs se lancent en même temps et s'arrêtent chacun à bout d'une durée qui lui est propre, le code sera complètement différent.

Oui effectivement j’ai peu être pas été claire dans mes explications donc voila:

1- Message affiché sur lcd + rotation du moteur x + minuterie affichée sur lcd
Stop
2-Message affiché sur lcd + rotation du moteur y+ minuterie affiché sur lcd
Stop
3-Message affiché sur lcd + rotation du moteur z + minuterie affiché sur lcd
Fin

C’est bien étape par etape que les chose s’affiche et toune comme pour un lave linge

Dans ce cas, le plus simple serait de faire une fonction qui affiche le compte à rebours :

void compteARebours (int dureeMinutes) {
int temps = 60 * dureeMinutes;
while (temps > 0) // 0n boucle tant que le décompte n'est pas terminé
{
  lcd.backlight();
  lcd.setCursor(0,3); 
  int minutes = temps/60;
  int secondes = temps%60;
  lcd.print("            ")
  lcd.setCursor(0,3); 
  lcd.print("Delai: ");
  if (minutes < 10) lcd.print('0');
  lcd.print(minutes);
  lcd.print(':');
  if (secondes < 10) lcd.print('0');
  lcd.println(secondes);
  delay(1000); // Apnée pendant une seconde...
  temps--;
}
}

Et dans la loop
(ou dans le setup si ceci ne doit être fait qu'une seule fois) tu ne t'occupes que de lancer les moteurs l'un après l'autre, puis d'appeler la fonction en lui donnant la durée en minutes.

Quand un moteur tourne et que l'on fait en même temps un décompte du temps, il y a deux actions à faire en même temps. Je vois trois solutions:

  1. On écrit ls deux tâches en code non bloquant. Pour les pas à pas, il faut un programme non bloquant, au minimum AccelStepper (stepper ne convient pas). Pour compteARebours(), il faut supprimer delay() et utiliser millis(), en faisant les changements toutes les secondes sinon compteARebours() se finit sans rien faire. La partie qui fait tourner un moteur ressemblerait à
...
  while (temps<tempsDuMoteurQuiTourne)
  {
    compteARebours();
    stepperMoteurQuiTourne.run();
  }
...
  1. On mélange les deux tâches. Si un moteur doit faire X pas pendant N secondes soit n pas par secondes, la partie qui fait tourner le moteur ressemblerait à:
...
  while (temps<tempsDuMoteurQuiTourne)
  {
    compteAReboursDiminueDuneSeconde();
    stepperMoteurQuiTourneFaitLes_n_Pas();
  }
...
  1. On fait tourner le moteur indépendamment:

Mais dans ce cas, il faut que la bibliothèque qui fasse tourner le moteur accepte de tourner pendant un code bloquant. La bibliothèque QuickStep le permet: on lance le moteur et il fait ses pas même pendant le delay.

La troisième solution me parait la plus simple, étant donné que le code bloquant pour compteARebours(); est déjà fait et que je peux t'aider pour utiliser QuickStep (normal, j'en suis l'auteur).

Merci beaucoup pour votre aide j’ai bien avancé dans mon projet grâce a vos messages.
Je déplace mon panier en x, y et z maintenant.
Il me reste plus qu’a actionner un relais sur ma carte shield pour faire tourner mon panier dans mes bocaux en gérant la vitesse de rotation et j’airai fini.
Si je trouve je vous enverrai le code complet au cas où quelqu’un se lancerai dans le même projet…
Encore merci :pray::pray:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.