Go Down

Topic: probleme de temps sur servo avec milli() (Read 2885 times) previous topic - next topic

ARTNOW

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 !

Code: [Select]
// 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
      }
   }
}

bricoleau

#1
Oct 16, 2015, 12:05 am Last Edit: Oct 16, 2015, 12:06 am by bricoleau
Code: [Select]
unsigned long t2=1000UL*40;
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

ARTNOW

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

fifi82

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à.

fdufnews

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.

bricoleau

#5
Oct 16, 2015, 10:43 am Last Edit: Oct 16, 2015, 10:43 am by bricoleau
Un autre truc maintes fois expliqué sur ce forum :
Code: [Select]
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
Code: [Select]
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().

Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

fifi82

#6
Oct 16, 2015, 11:35 am Last Edit: Oct 16, 2015, 11:38 am by fifi82
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

ARTNOW

Un autre truc maintes fois expliqué sur ce forum :
Code: [Select]
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
Code: [Select]
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
     }
  }
}

fifi82

#8
Oct 18, 2015, 02:43 pm Last Edit: Oct 18, 2015, 03:06 pm by fifi82
dans le code que tu viens de poster tu fais :
Code: [Select]
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()"
Code: [Select]
   
#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
    }   
 }
 
}

ARTNOW

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 .
 ;)

ARTNOW

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


ARTNOW

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
    }   
 }
 
}


dfgh

#13
Oct 19, 2015, 06:24 pm Last Edit: Oct 19, 2015, 07:49 pm by dfgh
 :) 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...)
Code: [Select]
// 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
  }

ARTNOW

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 . ;)

Go Up