remettre la fonction millis a zéro

Bonjour a tous ,
je suis débutant et je souhaiterai remettre la fonction millis a zero dans mon programme.

// Moteur pas à pas
int AnalogPIN = A0;
int val = 0;
int BPHaut = 8;
int BPBas = 12;
#include <Stepper.h>
int nombreDePas = 48*64;
unsigned long dateCourante = millis();
unsigned long intervalle = 5000;
unsigned long remise_a_zero= dateCourante - intervalle;

Stepper monMoteur(nombreDePas,9,11,10,6); //1° = 1n2; 2° = 1n4; 3° = 1n3; 4° = 1n1

void setup()
{
monMoteur.setSpeed(9);
Serial.begin(9600);

pinMode(12,INPUT);
pinMode(8,INPUT);
BPHaut = 8;
BPBas = 12;
}

void loop()
{
BPHaut = digitalRead(8);
BPBas = digitalRead(12);
val = analogRead(A0);
Serial.println(millis());
//Serial.println(BPHaut);

if(dateCourante==5000){
unsigned long remise_a_zero= dateCourante - intervalle;
}

if (val > 500){
val = analogRead(A0);
monMoteur.step(250);
}
if (val > 500 && intervalle == 5000){
digitalWrite(11,LOW);
digitalWrite(10,LOW);
digitalWrite(9,LOW);
digitalWrite(6,LOW);
}

}

Ma remise a zéro ne fonctionne pas. c'est peut-être dû a la librairie stepper qui utilise déjà millis ?

La fonction millis ne peut pas se remettre à zéro, elle te donne le nombre de millisecondes écoulées depuis le début du programme. Point barre.

Pour mesurer une durée, tu stockes la valeur de millis dans une variable unsigned long et tu fais la différence avec la valeur de millis à la fin.

Salut , voici un exemple d’ utilisation de millis qui permet de faire une action toutes les 30 secondes :

void relaisHeuresCreuses () { // heures creuses de minuit a 6 H et de 12 a 14 Heures
	static unsigned long chrono = 0;

	if (millis() - chrono >= TIMER_V) { // si plus de 30 secondes
		if ((RTC.heure() < 6) || ((RTC.heure() >= 12) && (RTC.heure() < 14))) {
			activeRelais_A(RHC_PIN_RELAY);
			if (DEBUG) Serial.println (F("relaisHeureCreuse => etat actif"));
		}
		else {
			reInitRelais_A(RHC_PIN_RELAY);
			if (DEBUG) Serial.println (F("relaisHeureCreuse => etat passif"));
		}
		chrono = millis();
	}
}

Sinon on peut utiliser quoi d'autre pour faire tourner un moteur pendant 20 s par exemple car si on ne peut pas remettre millis a zéro cela va être problématique car mon programme doit fonctionner plusieurs années.

on fait comme dans le code que je viens de poster , on compare le temps ecoulé ( la fonction millis() donc ) avec un timer auquel on donne la valeur desiré , avec le temps ecoulé plus tard .

lorsque la valeur temps ecoulé de depart ( millis maintenant) - la valeur temps ecoulé apres ( millis de depart ) depasse le timer , alors le temps qu on a decidé est passé , tout simplement .

pour 20 sec , ca pourrait donner un truc du genre :

unsigned long millisDepart = millis();
const unsigned long TIMER = 20000; // 20 sec en millisecondes

if (millis() - millisDepart >= TIMER) { // les 20 secondes sont passées
    // je fais mes machins
}

lekv: Sinon on peut utiliser quoi d'autre pour faire tourner un moteur pendant 20 s par exemple car si on ne peut pas remettre millis a zéro cela va être problématique car mon programme doit fonctionner plusieurs années.

Hello

Et quand tu veux faire cuire des œufs pendant 3 minutes, est-ce que tu commences par remettre ta montre à zéro?

Je dirais plutôt : tu regardes l'heure qu'il est quand tu lances la cuisson, puis tu surveilles l'heure régulièrement, et quand trois minutes sont écoulées tu arrêtes la cuisson.

Ben millis(), c'est ta montre.

lekv:
cela va être problématique car mon programme doit fonctionner plusieurs années.

Il n’y a pas de problème à utiliser millis() pendant plusieurs années, si utilises toujours la formule qui compare la différence de 2 temps à un seuil.

La seule chose qui ne marche pas, c’est de faire attentes (avec millis(), donc ) de plus de 49 jours environ.
En effet, l’utilisation de la bonne formule protège contre 1 débordement (un RAZ ) de millis().
Mais après 49 jours, tu peux avoir un second débordement, et là le résultat est faux (il manque 49,71 jours).
Plus grande valeur stockable dans un unsigned long = 4294967296
Ce sont des millisecondes. Divisé par 1000x3600x24, ça donne 49,71 jours.

lekv: Sinon on peut utiliser quoi d'autre pour faire tourner un moteur pendant 20 s par exemple car si on ne peut pas remettre millis a zéro cela va être problématique car mon programme doit fonctionner plusieurs années.

Le problème est intéressant et abordé souvent sur le net.

Ton programme doit fonctionner plusieurs années, mais la bonne question est : doit-il mesurer des durées plus longues que 49.7 jours ?

Si tu lis l'anglais, une discussion intéressante ici, notamment à partir de la réponse d'Edgar Bonet

Sinon on peut utiliser quoi d’autre pour faire tourner un moteur pendant 20 s par exemple car si on ne peut pas remettre millis a zéro cela va être problématique car mon programme doit fonctionner plusieurs années.

Je dirais plutôt : tu regardes l’heure qu’il est quand tu lances la cuisson, puis tu surveilles l’heure régulièrement, et quand trois minutes sont écoulées tu arrêtes la cuisson.

En observant aussi que quand je fais cuire un œuf, je ne regarde que l’aiguille des minutes et pas celle des heures et celles de minutes.

Je traduis: si c’est pour mesurer des durées de 20s, c’est inutile de stoker la valeur dans un unsigned long, un uint16_t suffit. Cela fait toujours sur une Uno 2 octets de RAM économisées (en plus on gagne 4 cycles d’horloges)

Tu fais comme on t’as dit : utiliser des variables intermédiaires et tu n’aura aucun soucis.

Si tu veux comprendre pourquoi cela fonctionne et pourquoi on se fiche de savoir si le compteur de millis() déborde tu cherche un tuto sur l’arithmétique binaire.

je suis de retour.j'aimerai que mon moteur tourne pendant on va dire 20s lorsque une condition est vrai. la remise a zéro est donc inutile si on prend l'exemple du temps que l'on vérifie lors de la cuisson. bref le temps passe donc millis condition A val >500 condition B = attendre ...seconde

si la condition A est vrai

alors attendre que millis + ...seconde ( c'est précisément qui me pose problème) pour eteindre le moteur

unsigned long millisDepart = millis();
const unsigned long TIMER = 20000; // 20 sec en millisecondes

if (millis() - millisDepart >= TIMER) { // les 20 secondes sont passées
    // je fais mes machins
}

et je ne comprend pas millis() - millisDepart car selon moi on soustrait la même chose. même si le code fonctionne pour effectuer une action après 20s

Voici mon pseudo code

mesurer la luminosité ambiant

si elle est > 500

faire fonctionner le moteur pendant un certain temps

tant que la luminosité est>500

broche moteur à 0

si luminosité <500

faire tourner le moteur dans le sens inverse pendant un certain temps

tant que la luminosité est <500

broche moteur a 0

lekv: ``` unsigned long millisDepart = millis(); const unsigned long TIMER = 20000; // 20 sec en millisecondes

if (millis() - millisDepart >= TIMER) { // les 20 secondes sont passées // je fais mes machins }

A la fin de ton if il manque :

millisDepart = millis();

Ensuite millis c'est une montre un bout de papier et un crayon.

  • La montre tourne
  • tu note l'heure (par ex 15h00) sur ton bout de papier et de temps en temps tu regardes ton bout de papier
  • tu regardes ta montre et tu soustrais le chiffre sur le papier à l'heure affichée sur la montre....
  • tant que le résultat est plus petit que le délai que tu as déterminé (1 minute), tu continues
  • dès que ça dépasse ou que c'est le même chiffre que tu as décidé (15h01 - 15h00 = 1 minute) tu fais ton action et tu récris le nouveau temps affiché sur la montre sur ton papier..... (15h01)
  • et tu recommences.

mesurer la luminosité ambiant
si elle est > 500
faire fonctionner le moteur pendant un certain temps
tant que la luminosité est>500

Un truc du genre si vous voulez faire une attente active

if analogRead(pinLuminosite) > 500) {
  unsigned long t0 = millis();
  activerMoteur();
  while ((analogRead(pinLuminosite) > 500)  && (millis() - t0 < 20000UL)); // attente active max 20s
  arreterMoteur();
}

Sinon ce type de programme se prête bien à la programmation par machine à états, vos événements sont le temps qui s’écoule ou la luminosité qui franchit un seuil (cf mon tuto éventuellement)

lekv: et je ne comprend pas millis() - millisDepart car selon moi on soustrait la même chose.

Mais non ! Quand tu appelles millis(), la valeur est à chaque fois différente, car du temps a passé. Sauf si tu appelles très rapidement en boucle, millis() va renvoyer la même valeur pendant une millisecondes, puis finira par passer à la ms suivante.

Le code de la fonction millis() se trouve dans le répertoire où est installé l'IDE, il est consultable.

Explication [u]sommaire[/u] du fonctionnement de millis(). millis() utilise le compteur du timer 0. Ce compteur change en permanence. Avec une fréquence d'horloge de 16 MHz et les réglages [u]choisis par arduino[/u] ce compteur incrémente de 1 unité toutes les 4 microsecondes. Ce compteur est un compteur 8 bits, ce qui veut dire qu'il ne peut compter que jusqu'à 255 et après on dit qu'il "déborde" c'est à dire qu'il passe de 255 à 0.

Le role de la fonction millis() est de gérer ces débordements pour pouvoir compter des temps extrèmement plus long. Le résultat de la fonction millis() est placé dans une variable long integer non signé ( c'est à dire toujours positif) c'est pour cela que les règles de l'arithmétique binaire s'appliquent. Si pour faire simple on reste dans le domaine d'une variable sous 8 bits (domaine 0 ; 255) : 254 + 1 =255 255 + 1 = 0

1 - 1 = 0 0 - 1 = 255

Les fonctions milli() et micro() fonctionnent de la même façon sauf que micro augmente d'une unité toutes les 4µs et millis() augmente d'une unité toutes les 1 ms.

J’ai refait mon programme mais voilà que le monteur continu de tourner malgré le fait que je luis ai indiquer de tourner 20s.Quelle est l’erreur ?

// Moteur pas à pas
int AnalogPIN = A0;
int val = 0;

#include <Stepper.h>
int nombreDePas = 48*64;
unsigned long depart = millis();
const unsigned long intervalle = 20000;

      
Stepper monMoteur(nombreDePas,9,11,10,6);    //1° = 1n2; 2° = 1n4; 3° = 1n3; 4° = 1n1

void setup()
{
  monMoteur.setSpeed(9);
  Serial.begin(9600);
  
 
}

void loop()
{
 
  val = analogRead(A0);  
  Serial.println(millis());
     //Serial.println(BPHaut);

     
  if(val > 500 )
  { 
  unsigned long depart = millis();
  val = analogRead(A0); 
  monMoteur.step(250);
  while((val > 500) && (millis() - depart >= intervalle ));
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  digitalWrite(6,LOW);
  }
  
 if(val < 500 )
  { 
  unsigned long depart = millis();
  val = analogRead(A0); 
  monMoteur.step(-250);
  while((val < 500) && (millis() - depart >= intervalle ));
  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  digitalWrite(6,LOW);
  }
                                      
  }

Ceci

while((val > 500) && (millis() - depart >= intervalle ));

me semble strictement équivalent à un delay. En effet, le ';' à la fin fait que tant que la condition est remplie, le code ne fait rien. Donc val n'est pas remis à jour. Donc la partie (val > 500) est vraie au début donc vraie tout le temps de l'attente : elle ne sert à rien dans le while. Conclusion : c'est seulement la seconde partie de la condition qui est réévaluée, donc c'est un delay.

Tu pourrais surveiller le capteur pendant l'attente :

while((val > 500) && (millis() - depart >= intervalle )) val = analogRead(A0);

mais ce n'est peut-être pas ce que tu veux.

Au passage, tu as déclaré la variable depart en global : inutile de la redéclarer en local : change (2 fois)

unsigned long depart = millis();

en

depart = millis();

Enfin, pourquoi le moteur ne s'arrête pas ? Es-tu sûr que ceci doit l'arrêter :

  digitalWrite(11,LOW);
  digitalWrite(10,LOW);
  digitalWrite(9,LOW);
  digitalWrite(6,LOW);

Je connais mal la bibliothèque Stepper : elle n'a pas une méthode pour arrêter le moteur ?

je met les broches relier au l298n a zéro car sinon 4 leds reste allumé sur le composant