[débutant] timer ou millis ?

Bonjour à tous,

Je suis débutant. Je vous explique mon programme, je fais les acquisitions d'un capteur (accéléromètre), si pendant 5sc il y a 'x' pics qui sont au dessus d'un seuil fixé alors je fais tourner un servo moteur dans un sens sinon dans l'autre. Tout cela en boucle infinie (dans la loop).

J'ai regardé du coté de la fonction millis mais on ne peut pas la remettre à 0 (sinon ça irait bien dans mon programme). J'ai regardé pour les timer mais je ne comprends pas trop...

Mon problème se situe dans l'instruction "faire pendant 5sc à chaque boucle".

Merci !

J’ai regardé du coté de la fonction millis mais on ne peut pas la remettre à 0 (sinon ça irait bien dans mon programme). J’ai regardé pour les timer mais je ne comprends pas trop…

bonjour,
non tu ne remets pas à zéro mais tu remets une variable à la millis()
si X>seuil==>top depart = millis()
si X>seuil ET millis() - top depart<5000==>on incrémente
etc…
si X>seuil ET millis() - top depart > 5000 ==> top depart = millis()

Quand il est 13h15 et que tu dois partir 20 minutes plus tard, tu fais comment ?

Tu remets ta montre à minuit et tu attends 0:20 pour partir ? Non ? Alors pourquoi vouloir remettre millis() à zéro ?

Là, je vois les neurones qui se connectent.... :smiling_imp:

molluste: J'ai regardé du coté de la fonction millis mais on ne peut pas la remettre à 0 (sinon ça irait bien dans mon programme).

bonsoir Ce n'est ps abolument exact , une RAZ peut etre faite :grin: mais le plus simple est surement là d’initialiser une variable temps_ancien et de faire/tester la difference entre millis/micros() et temps_ancien pour verifier si ton delai est écoulé.

regarde l'exemple BlinkWithoutDelay de l'IDE :confused:

Rectification (avec l’aide du message entre temps), mais j’ai compris le fonctionnement mais je sais pas si ça marche…

#include<Servo.h>
Servo servo;
int sensorPin = 1;
int resolution;
int seuil;
int sensibilite;
int c1; //variable du compteur 1
int c2; //variable du compteur 2
int temps_ancien;
    void setup()
    {  servo.attach(9);
       servo.write(85); 
       temps_ancien=0;
    }
    
    void loop()
    {
    c1=0;
    c2=0;
    
    while (millis()-temps_ancien<5000){ 
          int reading = analogRead(sensorPin);
          float voltage = reading *5.0;
          voltage /= 1024.0;
          float G=voltage*resolution;
          if (G>seuil)
              c1=c1+1;}
              
          temps_ancien=millis()             
    
    
    if (c1>sensibilite)
      servo.write(0);
    else
      servo.write(85);
      
     }

Rectification (avec l'aide du message entre temps), mais j'ai compris le fonctionnement mais je sais pas si ça marche...

je dirais que ce n'est pas à nous de tester pour toi, mais à toi de le faire, non?

Oui très juste mais j'aurai accès à ma carte arduino que ce week end. C'est juste pour avoir vos avis, je ne vous demande pas de me faire mon programme mais juste de m'aiguiller et c'est ce que vous avez très bien. Je vous en remercie d'ailleurs !

déjà, ceci ne passera pas

int temps_ancien;

int ==> -32768 à 32767 mais, ceci oui

unsigned long temps_ancien;

Ah oui au temps pour moi... Je suis allé trop vite en lisant l'exemple de Artouste.

Bonjour,

J’ai donc pu tester mon programme. Il marche que à moitié et au bout d’une demie journée à chercher pourquoi je me remet donc à vous…
Alors je rappelle brièvement mon programme:
J’ai un accéléromètre qui est relié à une arduino qui pilote un servo moteur pour actionner une commande d’un amortisseur de vélo.
Le programme compte le nombre de fois que l’on a dépassé un seuil, si on l’a dépassé plus de 10 fois alors on actionne le servo moteur dans un sens sinon dans l’autre.
J’ai fixé (pour tester) mon seuil à 0G. Quand je place l’accéléromètre à la verticale (1G) le servo tourne dans un sens (jusque la ça va). Quand je place l’accéléromètre pour qu’il affiche -1G le servo change de position mais revient à celle d’avant continuellement, il fait que de changer de position au lieu de rester dans saposition…
Au final ça marche que dans un sens mais je ne vois pas pourquoi ça bug dans l’autre…
Je vous remercie d’avance !

#include<Servo.h>
Servo servo;
int sensorPin =A0;
int seuil=0; //seuil de basculement en G
int sensibilite=10;
int c1; //variable du compteur 
unsigned long temps_ancien;
    void setup()
    {  servo.attach(9); //pin du servo moteur
       temps_ancien=0; } //On initialise le temps
    void loop(){
    c1=0; //On initialise un compteur
    while (millis()-temps_ancien<2000){   //On mesure pendant 2sc
          int reading = analogRead(sensorPin);
          float voltage = reading *5.0;
          voltage /= 1024.0;
          float G=voltage*16.6-27;  //On obtient les valeurs des Gs
          if (G>seuil)  
              c1=c1+1;}  // On compte le nbre de G>seuil  
            
    if (c1>sensibilite){  
      servo.write(0);}  //Si le seuil est beaucoup dépassé on bascule en position libre
    else {
      servo.write(85);}  //Sinon il revient à sa position bloquée
    temps_ancien=millis();    //On affecte temps_anciens à la valeur actuel du temps 
       }

Up!

Je ne vois pas grand chose de flagrant dans le code

Juste un doute sur la capacité de ta variable c1, de type int donc limitée à 32767, à comparer à la durée d'un analogRead() pour savoir combien on peut en avoir au maximum pendant deux secondes = nombre d'exécutions de ton while. Il me semble qu'un analogRead() dure 100µs, ce qui veut dire que ton while s'exécute 10.000 fois par secondes donc ça devrait passer. Peut-être passer c1 en unsigned long pour voir.

Là où la logique me semble louche, c'est de comparer le nombre de hits à un seuil sans savoir combien de lectures ont été effectuées. Un test en pourcentage de hits me semblerait plus logique, mais je ne connais pas le capteur.

Sinon de manière générale : donne toi les moyens du diagnostic, en posant des mouchards.

Ajoute des Serial.print pour comprendre ce qui se passe Et si pas possible de brancher un ordi dans le contexte du test, ajoute un afficheur ou des leds témoins, à commencer par la led13 qui est "gratuite".

Merci de ta réponse, L accéléromètre est L'adlx 326. Il renvoie une tension. 0,05v par G il me semble.

Alors déjà mon programme marche j'ai testé en mettant une source de tension à la place de mon capteur sur la broche de L arduino. En mettant une tension supérieur au seuil ça bascule et de même dans l'autre sens. J'ai déjà pensé que le fait de mettre le seuil à 0 allait occasionner du bruit car le 0 est la valeure où il y a le plus de bruit, j'ai donc mis le seuil à 0,5G. Pareil ca bouge toujours au lieu de rester en position sur le -1G mais OK sur le 1G. Ensuite j'ai varié la sensibilité dans le programme. Il a fallut que je monte à 3000 pour que ça fonctionne !! Ce qui veut dire qu'il y a beaucoup de parasites !! Je me demande donc si c'est pas le servo moteur qui parasite le tout... Il va falloir que j'essaye de mettre un condensateur pour essayer de filtrer un peu.

Mais ce qui est bizarre c'est que l'accelerometre fournit 500 valeurs par seconde. (Dans le while je suis passé à 2sc). Donc en 2sc ca compare au mieu 2000 valeurs, alors que moi j'ai rentré 3000 pour la sensibilité.

Commence par compter le nombre de boucles exécutées dans le while.

Peu importe que ton capteur fournisse 500 valeurs par seconde. L'arduino ne l'attend pas. Il tourne à la vitesse d'un analogRead+quelques opérations arithmétiques. Donc probablement une dizaine de milliers de lectures par seconde.

Alors la boucle while fait 18693 opérations + ou - 3. Je vais peut être mettre une tempo dans la boucle du coup non ?

edit: avec un delay(1) dans la boucle j'ai des valeurs autour de 2500. Je l'ai donc laissé. J'ai aussi fait afficher en série la valeur 0 ou 1 en fonction de la position du servo moteur. Sans brancher le servo, tout va niuel j'ai que des 0 ou que des 1 mais des que je le branche je vois apparaitre dans la liaison séries des 0 et des 1 qui alternent... Le problème vient donc du servo. Il doit surement générer des parasites alors...