probleme de temps sur servo avec milli()

bonjour , j'ai un soucis avec ce programme si je programme plus de 30 s rien ne se passe sur la sortie 9 de mon servo , par contre avec 20 s cela fonctionne , help me !

// CROQUETIME CATS
// projet distribution croquette pour chat avec servo
// il faut faire une sequence toute les 4 heures par exemple

#include <Servo.h>
 
Servo myservo; 
             
unsigned long t1=0;       // mémoriser le temps                         
unsigned long t2=1000*40; // donne la valeur de la tempo pour éviter les calculs pendent l'exécution du programme
                          // marche avec 30s et pas avec 40 s ???????
                         
int pos = 0;    // variable pour la position du servo

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  t1=millis()+t2;        // la distribution se fera dans 4h apres la mise sous tension
  myservo.write(pos); // positionne le servo à zéro
}
 
void loop()
{
  unsigned long time=millis();    // lecture du temps qui passe
 
  if ( time >= t1 ) { t1=time+t2;  // à la fin de la tempo on exécute le programme suivant:
 
    for(pos = 0; pos <= 180; pos += 4) // va de 0 degrees a 180 degrees
      {                                  // avec des pas de 1 degre
        myservo.write(pos);              // dit au servo d aller en position en fonction de la variable 'pos'
        delay(15);                       // pause  15ms 
      }
    for(pos = 180; pos>=0; pos-=4)     // va de  180 degres a  0 degrees
      {                                  // avec des pas de 4 degrees donc retour rapide
        myservo.write(pos);              // dit au servo d aller en position en fonction de la variable 'pos'
        delay(15);                       // pause  15ms
      }
   }
}
unsigned long t2=1000UL*40;

merci BRICOLEAU , ca marche , je comprends pas comment ta modif fonctionne mais c'est ok merci beaucoup

je pense que '1000' tout seul est un "int" et que "1000UL" est un "unsigned long" donc pour faire le calcul et retourner un unsigned long il faut ajouter UL après.
J'ai appris quelque chose sur ce coup là.

Le problème t'avais déjà été signalé dans le fil que tu avais précédemment créé.
Il faut impérativement typer les constantes pour avoir des résultats pertinents:

  • suffixe L ou UL pour les long et unsigned long
  • placer une décimale (.0 par exemple) pour les nombres à virgule flottantes
    sinon par défaut les constantes sont considérées comme entières.

Maintenant que tu as une RTC tu pourrais aussi utiliser le registre des secondes de la RTC pour gérer tes temporisations.

Un autre truc maintes fois expliqué sur ce forum :

unsigned long time=millis();    // lecture du temps qui passe
if ( time >= t1 ) { t1=time+t2;  // à la fin de la tempo on exécute le programme suivant:

Et le programme risque de se bloquer ou de dysfonctionner au bout d'une cinquantaine de jours.

C'est le temps qu'il faut à la fonction millis() pour atteindre 2^32 et repasser à zéro.
Le code correct est

unsigned long time=millis();    // lecture du temps qui passe
if (time - t1 >= t2) { t1=time;  // à la fin de la tempo on exécute le programme suivant:

Et si tu veux que ton programme lance la première exécution à x millisecondes après le démarrage, tu ajoutes t1 = t1 - t2 + x; dans ton setup().

oui "time" repasse à 0 tout les 49j 17h 2mn 47s et 295ms soit toute les 4 294 967 295 ms valeur maxi d'un unsigned long

bricoleau:
Un autre truc maintes fois expliqué sur ce forum :

unsigned long time=millis();    // lecture du temps qui passe

if ( time >= t1 ) { t1=time+t2;  // à la fin de la tempo on exécute le programme suivant:



Et le programme risque de se bloquer ou de dysfonctionner au bout d'une cinquantaine de jours.

C'est le temps qu'il faut à la fonction millis() pour atteindre 2^32 et repasser à zéro.
Le code correct est


unsigned long time=millis();    // lecture du temps qui passe
if (time - t1 >= t2) { t1=time;  // à la fin de la tempo on exécute le programme suivant:




Et si tu veux que ton programme lance la première exécution à x millisecondes après le démarrage, tu ajoutes t1 = t1 - t2 + x; dans ton setup().

Merci pour vos réponses , pouvez vous me dire comment à laide d'un bouton poussoir je pourrais lancer un cycle en marche forcé , et me dire pourquoi quand je programme 9h de délais cela ne fonctionne pas , 11 h00 après pas de croquettes dans la gamelle et 3 chats furax !!!!!..

autre question , j’ai un rtc , je sais le programmer pour le mettre à l’heure et lire les données avec la fenêtre série mais je ne sait pas programmer une action à 12h00 par exemple .

// CROQUETIME CATS
// projet distribution croquette pour chat avec servo
// il faut faire une sequence toute les 4 heures par exemple

#include <Servo.h>

Servo myservo;

unsigned long t1=0; // mémoriser le temps
unsigned long t2=1000UL*32400; // cycle dans 9h00

int pos = 0; // variable pour la position du servo
int max = 190;
int min = 0;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
t1=millis()+t2; // la distribution se fera dans 4h apres la mise sous tension
myservo.write(pos); // positionne le servo à zéro

}

void loop()
{
unsigned long time=millis(); // lecture du temps qui passe
if (time - t1 >= t2) { t1=time; // à la fin de la tempo on exécute le programme suivant
for(int i = 0; i <= 5; i++) // le chiffre 5 pour 5 cycles

{ // avec des pas de 1 degre
myservo.write(180); // dit au servo d aller en position en fonction de la variable 'pos'
delay(15); // pause 30ms

}
myservo.write(0);
{ // avec des pas de 4 degrees donc retour rapide

delay(15); // pause 30ms
}
}
}

dans le code que tu viens de poster tu fais :

for(int i = 0; i <= 5; i++)  // le chiffre 5 pour 5 cycles
   
     {                                  // avec des pas de 1 degre
       myservo.write(180);

se qui correspond à dire au servo d'aller 5 fois à 180°, une seule fois suffi.

essaye ça avec la lib RTC, pour faire plus simple j'ai mis le code du mouvement du servo dans une fonction nommée "distibution()"

#include <Wire.h>
#include <RTClib.h>                    
#include <Servo.h> 
RTC_DS1307 RTC;
Servo myservo;

boolean ar=0; //antirebond pour la distribution
int bp=2;

void setup()
{
 Wire.begin();
 RTC.begin();
 pinMode(bp, INPUT);  // broche 2 en entrée pour le bouton poussoir
 
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 myservo.write(0); // positionne le servo à zéro   
}

void loop()
{
boolean b=digitalRead(bp);  // lecture de l'état du bouton poussoir

DateTime now = RTC.now();   // lecture de l'heure
  
if ( now.hour()==12 || now.hour()==20 || b ) distribution(); else ar=0;  // donne une dose à 12h et à 20h et si appui sur le bp

}


void distribution(){
  
 if (!ar) { ar=1; // active l'antirebond
 
  for(int i = 0; i <= 5; i++)  // le chiffre 5 pour 5 cycles  
    {                                  
      myservo.write(180);              // dit au servo d aller en position en fonction de la variable 'pos'
      delay(500);                      // pause  500ms pour laisser le temps au servo de s'ouvrir       
      myservo.write(0);    
      delay(500);                      // pause  500ms pour laisser le temps au sevo de se fermer
    }    
 }
 
}

merci fifi82 , le soucis c'est que mon module rtc est un DS3231, donc pas possible d'utiliser ton programme tel quel , et, es-ce possible pour faire des essais de régler les minutes également du style 12h15 pour tester ?.

j’ai remarquer que mon servomoteur avait tendance à chauffer un peu , l’idéal serait de couper l'alim du servo par un relais avec des contact NO que j'activerai avant de lancer le cycle du servo ?
qu'en pensez vous ?

merci de votre aide.

Grâce à vous je comprend beaucoup mieux le monde de l'arduino .

c'est passionnant .
:wink:

Bonjour , pour le servo qui chauffe c'est réglé c était juste un réglage de fin de course .
quelqu’un à une idée de programme pour utiliser un rtc DS 3231 avec des départ de cycle par exemple à 12h15 et 20h30 et un bp marche forcé ? .

merci

Bonjour , qui peut m’aider à debeuguer ce programme svp :
// CROQUETIME CATS
// projet distribution croquette pour chat avec servo
// il faut faire une sequence toute les 4 heures par exemple

#include <Servo.h>
Servo myservo;
boolean ar=0; //antirebond pour la distribution
int bp=2;

unsigned long t1=0; // mémoriser le temps
unsigned long t2=1000UL*60; // donne la valeur de la tempo pour éviter les calculs pendent l'exécution du programme
// 60s pour les tests

int pos = 0; // variable pour la position du servo

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
t1=millis()+t2; // la distribution se fera dans 4h apres la mise sous tension
myservo.write(pos); // positionne le servo à zéro
pinMode(bp, INPUT); // broche 2 en entrée pour le bouton poussoir
}
void loop()
{
boolean b=digitalRead(bp); // lecture de l'état du bouton poussoir
if ( b ) distribution(); else ar=0; // si appui sur le bp on lance la distribution
unsigned long time=millis(); // lecture du temps qui passe
if (time - t1 >= t2) { t1=time; // à la fin de la tempo
if (t1=time);{ goto distribution (); // on lance la distribution
}
}
}
}
void distribution(){

if (!ar) { ar=1; // active l'antirebond

for(int i = 0; i <= 1; i++) // le chiffre 1 pour 2 cycles
{
myservo.write(180); // dit au servo d aller en position en fonction de la variable 'pos'
delay(500); // pause 500ms pour laisser le temps au servo de s'ouvrir
myservo.write(0);
delay(500); // pause 500ms pour laisser le temps au sevo de se fermer
}
}

}

:slight_smile: testes ça
nota dans le prg que tu donnes ci dessus il y a if (t1=time) cela ne fonctionne pas car il faut if (t1==time)
(plus les ; qui n'aident pas...)

// CROQUETIME CATS
// projet distribution croquette pour chat avec servo
// il faut faire une sequence toute les 4 heures par exemple

#include <Servo.h>
Servo myservo;
int bp = 2;

unsigned long t1 = 0;           // mémorisera le temps au départ
unsigned long t2 = 1000UL * 60; // donne la valeur de la tempo pour éviter les calculs pendent l'exécution du programme
                                // 60s pour les tests   //4h=14400000
                            
int pos = 0;                    // variable pour la position du servo

void setup()
{
  myservo.attach(9);    // attaches the servo on pin 9 to the servo object
  t1 = millis() ;       // la distribution se fera dans 4h apres la mise sous tension
  myservo.write(pos);   // positionne le servo à zéro
  pinMode(bp, INPUT);   // broche 2 en entrée pour le bouton poussoir
}
void loop()
{
//distribution manuelle
  boolean b = digitalRead(bp); // lecture de l'état du bouton poussoir
  if ( b )                     //b=true implique que le BP apporte du 5V sur l'entrée
  {                            //si appui sur le bp on lance la distribution
    delay(500);                //il y a eu appui sur BP, on laisse les rebonds passer
    distribution();            //on s'interdit de relire l'entrée BP 500ms 
  }                            //puis on va distribuer
                               //attention:rebonds en poussant et en relachant
                               //donc appui doit etre bref ( 400ms)
//distribution programmée
  unsigned long time = millis();   // lecture du temps qui passe
  if ((time - t1) >= t2)
  {
    distribution ();               // on lance la distribution
    t1 = time;                     // à la fin de la tempo
  }
}

void distribution()
{
  for (int i = 0; i <= 1; i++) // le chiffre 1 pour 2 cycles
  {
    myservo.write(180);              // dit au servo d aller en position en fonction de la variable 'pos'
    delay(500);                      // pause  500ms pour laisser le temps au servo de s'ouvrir
    myservo.write(0);
    delay(500);                      // pause  500ms pour laisser le temps au sevo de se fermer
  }
}

merci beaucoup dfgh cela fonctionne parfaitement , c'est exactement ce que je voulais , mes 3 chats et mes 3 enfants te remercient , fini la galère de gérer la nourriture des chats , surtout quand on part en weekend ou en vacances . :wink: