Capteur anémomètre / prise de mesure toutes les 5 secondes

Bonsoir,

J'ai un capteur anémomètre intégrant un contact reed et une carte arduino UNO (https://www.lextronic.fr/P36218-capteur-annomtre.html).

Je souhaite effectuer des mesures toutes les 5 secondes. Le programme ci-dessous m'affiche bien les valeurs toutes les 5 secondes mais les valeurs sont très faibles comparées à celles mesurées avec mon anémomètre manuel digital. De plus si j'enlève les lignes de codes qui permettent de temporiser les mesures, les valeurs sont bonnes. Donc le problème est localisé mais comme je suis débutant dans le langage Arduino, j'aurai besoin d'un coup de main. Je tiens à préciser que pour réaliser la partie du programme qui donne des valeurs justes, j'ai été beaucoup aidé par Kamill, un membre de ce forum que je tiens à remercier.

Merci par avance

#define pinANEMO 2
#define pi 3.1415
#define RayonDesBras 0.07 //rayon en mètre de l'anémomètre

long date_debut;
long date_mesure(0); 



void setup()
{
pinMode(pinANEMO, INPUT);
Serial.begin(9600);
long date_debut=millis();
}

unsigned long millis_old(0);
float deltaTime(0);
float vitesseVent(0);
float NombreTourSec(0);
float NombreTourMin(0);
float FEtalonage(1);



void loop()
{
date_mesure=millis();  
if (date_mesure==date_debut+5000) //si la durée de la mesure est égale à 5 secondes
{
calcul_vent() ; 
   //calcul de la vitesse du vent
    NombreTourSec = (1/deltaTime); // convertion periode -> vitesse de rotation en tours/seconde
    NombreTourMin = NombreTourSec*60; // vitesse de rotation en tours/minute

vitesseVent = pi*RayonDesBras*NombreTourMin*FEtalonage*3.6/30; //vitesse du vent en km/h


//affichage de la vitesse
  Serial.print("Vitesse du vent = ");
    Serial.print(vitesseVent);
    Serial.print(" km/h\r\n");

date_debut=millis(); //réinitialisation de la date de début
 }
}


void calcul_vent  ()
{
static byte etatPrecedent=LOW;
byte etat = digitalRead(pinANEMO); //lecture du capteur

 if (etat && etat!=etatPrecedent)
 {
deltaTime = ((millis() - millis_old) / 1000.0);// div en 1000 pour avoir le résultat en seconde
millis_old = millis(); // remise à 0 du compteur pour capturer la différence de temps au prochain tour
}
 etatPrecedent=etat;
}

hello

toutes les 5 secondes, tu vas lire l'entrée D2

et là, tu as la chance [u]ou pas[/u] de tomber sur un état du reed différent de celui mémorisé

donc pour moi tu comptes [u]peut être[/u] un tour d’anémomètre toutes les 5 secondes.

comme tu calcules le temps pour en déduire une frequence ( ou nombre de tours) tu peux ensuite calculer une vitesse du vent.

mais tu ne fais un relevé qu'une fois toutes les 5 secondes (sans être sur de compter un tour) alors que l'anémometre peut tourner très vite

donc c'est du hasard

je me trompe ?

L'astuce est de faire des lectures constantes mais d'envoyé seulement les données toutes les 5 secondes.

he oui, si notre ami passe par les interruptions, ( incrémentant un compteur)

toutes les 5 secondes: un relevé et remise à zéro du compteur puis calcul et affichage …et ça roule…heu non, ça souffle… :slight_smile:

Bonjour,

Merci pour vos réponses. Entre le capteur et la carte, j'ai placé un petit montage avec un circuit CMOS 4011 en utilisant 2 portes NAND pour éviter le phénomène de "rebond". De plus, il y a sur le capteur une résistance de 10kOhm pour le pullup. Ainsi, les valeurs sont stables mais je souhaite simplement que la prise de mesure soit moins rapide à l'affichage. L'aide que j'attends de votre part est de savoir comment modifier ou compléter mon programme, quelles instructions doivent être saisies pour parvenir à ceci. Comme je l'ai écrit précédemment, je débute dans ce type de langage et je galère pour savoir quelles bonnes instructions utiliser.

Comme dit précédemment, il faut utiliser les interruptions.

Chaque basculement du relai Reed va générer une interruption ; cette interruption va mettre en œuvre un petit bout de code dont la fonction sera simplement d'incrémenter un compteur.

Maintenant, dans votre programme, toutes les 5 secondes, vous relevez votre compteur et vous diviser sa valeur par 5, ce qui vous donnera le nombre d'impulsions par seconde.

Après ce calcul, vous remettez le compteur à zéro ... et c'est reparti pour un tour.

Je ne vous donne pas le code ; je vous laisse d'abord regarder le principe de fonctionnement des interruptions sous Arduino. Vous tapez "Arduino interruptions" dans votre moteur de recherche préféré et vous consultez.

Cordialement.

Pierre

Rhestti: Entre le capteur et la carte, j'ai placé un petit montage avec un circuit CMOS 4011 en utilisant 2 portes NAND pour éviter le phénomène de "rebond".

Bonjour, j'utilise ce capteur sur ma ruche et comme toi j'ai fais un anti-rebond avec 2 NAND triggées le capteur et raccordé sur D2 et provoque une interruption (voir AttachInterrupt) l'interruption 0 ne fait qu'incrémenter un compteur toutes les secondes je relève ce compteur, le sauvegarde dans 2 variables et le remet a zéro une des variable me sert pour déterminer la valeur des rafales (je garde donc le max) l'autre me sert a faire la valeur du vent moyen sur la période choisie (pour moi toutes les minutes) comme je ne publie que toutes les 15 mn je fais encore une moyenne de la moyenne/mn

pour le calcul de la vitesse je ne perd pas de temps a refaire les calculs (pi, D, ....) en virgule flottante, le capteurs donne 1 imp/s pour un vent de 2.4 km/h et comme je suis un peu fainéant je reste en int en multipliant par 10 puis division par 4 (2 décalage a droite) ce qui donne 2.5

Super boulot !

ChPr, J’ai regardé le principe de fonctionnement des interruptions sous Arduino. j’ai modifié tout le code mais il m’affiche des valeurs trop élevées et parfois une valeur négative ??? Si vous avez une idée d’où vient mon erreur je suis preneur.

#include <PinChangeInt.h>

#define pinILS 2
#define pi 3.1415
#define RayonDesBras 0.07
byte comptageILS = 0;
byte comptageILSold = 0;
const unsigned long dureeAntiRebond = 1;
unsigned long time = 0;
unsigned long timeold;
int nombreTourSec =0;
int nombreTourMin =0;
float vitesseVent(0);
float FEtalonage(1);



void interruptILS() //comptage de l'ILS
{
  static unsigned long dateDernierChangement = 0;
   unsigned long date = millis();
 
  if ((date - dateDernierChangement) > dureeAntiRebond) {
    comptageILS++;
    dateDernierChangement = date;
  }
}




void setup()
{
 Serial.begin(9600);
 pinMode(pinILS, INPUT);
 PCintPort::attachInterrupt(pinILS, interruptILS, FALLING); 
 timeold = millis();
 comptageILSold=0;
}



void loop()
{    

  if ((millis() - timeold)> 1000) { // durée d'1 seconde 
    timeold = millis();
    nombreTourSec = (comptageILS - comptageILSold); //comptage du nombre de tours par seconde
    nombreTourMin = nombreTourSec*60;
    vitesseVent = pi*RayonDesBras*nombreTourMin*FEtalonage*3.6/30; // formule pour le calcul de la vitesse du vent
    comptageILSold = comptageILS; // réinitialisation du comptage
    
    
    Serial.print("Vitesse du vent = "); // affichage des valeurs
    Serial.print(vitesseVent);
    Serial.print(" km/h\r\n");
    }
}

J’ai un peu expurgé votre code de données inutiles :

#define pinILS 2
#define pi 3.1415
#define RayonDesBras 0.07

unsigned long timeold;
int nombreTourSec = 0;
int nombreTourMin = 0;
float vitesseVent(0);
float FEtalonage(1);

volatile unsigned int comptageILS = 0; // une variable utilisée dans une interruption doit être déclarée "volatile"



void interruptILS() //comptage de l'ILS
{
  comptageILS++;
}

void setup()
{
  Serial.begin(9600);
  pinMode(pinILS, INPUT);
  attachInterrupt(pinILS, interruptILS, FALLING);
  timeold = millis();
}



void loop()
{
  if ((millis() - timeold) > 1000) { // durée d'1 seconde
    nombreTourSec = comptageILS; //comptage du nombre de tours par seconde
    nombreTourMin = nombreTourSec * 60;
    vitesseVent = pi * RayonDesBras * nombreTourMin * FEtalonage * 3.6 / 30; // formule pour le calcul de la vitesse du vent
    comptageILS = 0; // réinitialisation du comptage


    Serial.print("Vitesse du vent = "); // affichage des valeurs
    Serial.print(vitesseVent);
    Serial.print(" km/h\r\n");
    timeold = millis();
  }
}

Cordialement.

Pierre

Merci beaucoup pour l'allègement. Je ne peux pas le tester avant demain mais je vous tiens au courant. Je croise les doigts pour qu'il fonctionne car je galère un peu (beaucoup).

ChPr, le code fonctionne. Enfin ... Au départ, suite à vos allègements, le moniteur affichait une valeur nulle. J'ai repris le code initial, refais certains de vos allègements et surtout j'ai écrit l'instruction "volatile" que vous m'avez indiqué pour la variable liée à l'interruption. Maintenant, c'est nickel. Merci beaucoup pour l'aide et pour m'avoir suggéré de voir les principes de fonctionnement des interruptions.

Bonjour,

Finalement serait-il possible d'avoir une copie de la version finale qui fonctionne ?

Merci et bravo.

Si votre anémomètre fonctionne toujours, je suis intéressé par le code ainsi que par le schéma du circuit et des composants.

Merci