Go Down

Topic: Mise en fonction d'un Anémomètre (Read 5581 times) previous topic - next topic

Tom_Auser

Feb 17, 2012, 09:02 am Last Edit: Feb 17, 2012, 09:04 am by Tom_Auser Reason: 1
Bonjours à tous !  :)

Je possède un anémomètre Somfy et j'aimerais pouvoir récupérer la vitesse du vent en m/s sur mon port serial.
J'ai pensé déduire celle-ci du nombre de changement d'état que prendrait la pin reliée à mon anémomètre.
En effet, j'ai remarqué que celle-ci change 8x d'état lors d'un tour d'hélice.

Voilà mon début de code   ;) :

Code: [Select]
const int Anemo = 8;

unsigned long duration;
unsigned long impulsion;

int Anemo_Push_Counter = 0;
int Anemo_State = 0;
int Last_Anemo_State = 0;

void setup()
{
   Serial.begin(9600); // Communication serial à 9600 bauds
   pinMode(8,INPUT);   // Broche 8 en entrée
}


void loop()

{
 
 // lit l'état actuel de la pin8
 Anemo_State = digitalRead(Anemo);

 // compare l'état actuel de l'anemo à l'état précédent mémorisé
 if (Anemo_State != Last_Anemo_State)
 
 {
     Anemo_Push_Counter++;
 }
   
 
 Serial.println (Anemo_Push_Counter);
 
 delay (100);
 
}


Malheureusement, quand je vais voir dans mon serial, ma variable Anemo_Push_Counter ne s'incrémente pas quand il y a un changement d'état mais quand elle est à 1  :smiley-eek: et ne s'incrémente pas quand elle est à 0  :smiley-sweat:

Un peu d'aide serait la bienvenue ! Merci d'avance  XD

zeni

C'est parce que tu ne mets pas à jour ta variable Last_Anemo_State.
Elle reste toujours à sa valeur initiale. Dans ta condition if, ajoute une mise à jour de cette variable à la valeur en cours (Anemo_State).

schizophrene

Et si tu n'y arrives pas avec l'indication de zeni, je ne comprendrais pas. Puisque c'est connu : "It's so easy, it's Somfy!"

:)

Tom_Auser

#3
Feb 17, 2012, 10:31 am Last Edit: Feb 17, 2012, 10:34 am by Tom_Auser Reason: 1
Merci zeni ! Je peux à présent compter les impulsions  :)

Pour la suite je pensais regarder chaque seconde le compteur en sachant que quand le compteur est à 8 c'est que l'hélice a fait un tour.
Je prendrai ensuite la valeur indiquée (exemple 1012) et je la diviserai par 8 pour obtenir le nombre de tour de l'hélice en 1 seconde (dans mon exemple 126.5).

Je mettrai ensuite cette valeur dans la formule que j'ai trouvé sur wikipedia : http://fr.wikipedia.org/wiki/An%C3%A9mom%C3%A8tre  ;)

C'est à dire : V = 2*PI*F(N)*R*N donc la vitesse du vent en m/s = 2 x PI x la fonction d'étalonnage x le rayon des bras x nbr de tours / s

Donc, V sera envoyé dans mon serial et ce que je cherche à calculer sera assigné à N.

Ce qui me donnerai un code comme ça :
Code: [Select]
const int Anemo = 8;

unsigned long impulsion;
unsigned long nbr_tour;

int Anemo_Push_Counter = 0;
int Anemo_State = 0;
int Last_Anemo_State = 0;

void setup()
{
   Serial.begin(9600); // Communication serial à 9600 bauds
   pinMode(8,INPUT);   // Broche 8 en entrée
}


void loop()

{
 Anemo_Push_Counter = 0;
 
 // lit l'état actuel de la pin8
 Anemo_State = digitalRead(Anemo);

 // compare l'état actuel de l'anemo à l'état précédent mémorisé
 if (Anemo_State != Last_Anemo_State)
 
 {
     Anemo_Push_Counter++;
     Last_Anemo_State = Anemo_State;
 }
 
 delay (1000);
 
 Serial.println (2*3.1415*0.031*5*nbr_tour);
}


Mais Anemo_Push_Counter est, dans mon cas, égal à 0 donc mon résultat aussi  :P
En fait, il me faudrait un moyen de réinitialiser Push_Counter correctement.

Je débute sous arduino alors n'hésitez pas si quelque chose n'est pas clair  XD

Merci beaucoup !

zeni

#4
Feb 17, 2012, 10:49 am Last Edit: Feb 17, 2012, 10:52 am by zeni Reason: 1
Il ne faut pas réinitialiser ton compteur à chaque loop sinon il est toujours à 0 ou 1 avant le calcul de la vitesse du vent. De plus le delay est inutile puisque tu ne fais que mettre en pause le programme (et donc aucune variable n'est mise à jour).
Il te faut un second compteur basé sur le temps écoulé.
Ainsi, à chaque fois qu'il s'est écoulé une certaine durée (mettons appelée D, qui dépend de la vitesse de variation de la vitesse du vent), la vitesse du vent est calculée (à partir du compteur de tours et de D) et envoyée sur le port série. Dans la foulée, le compteur de tours (Anemo_Push_Counter) et de temps sont mis à 0 et à millis() respectivement. Millis() te donne le temps actuel (depuis le moment où le programme a commencé).
Dans le loop, tu as donc une condition du genre (à mettre à la place de delay et de ce qu'il y a ensuite):
if (millis()==compteur_temps+D) {
Calcul vitesse vent;
Envoie vitesse vent sur série;
Anemo_Push_Counter=0;
compteur_temps=millis();
}

Dans setup():
Anemo_Push_Counter=0;
compteur_temps=millis();

Il est préférable de déclarer compteur_temps comme un unsigned long au cas où la durée entre chaque calcul de la vitesse du vent est relativement longue.

Tom_Auser

Je ne comprends pas ce que tu considères comme la variable D.

Quote
à chaque fois qu'il s'est écoulé une certaine durée (mettons appelée D, qui dépend de la vitesse de variation de la vitesse du vent), la vitesse du vent est calculée (à partir du compteur de tours et de D)


Donc millis() c'est le temps depuis le lancement du programme, mais compteur_temps et D j'ai du mal à saisir la façon dont je dois les utiliser.


Merci de ton aide !

Artouste


Je ne comprends pas ce que tu considères comme la variable D.

Quote
à chaque fois qu'il s'est écoulé une certaine durée (mettons appelée D, qui dépend de la vitesse de variation de la vitesse du vent), la vitesse du vent est calculée (à partir du compteur de tours et de D)


Donc millis() c'est le temps depuis le lancement du programme, mais compteur_temps et D j'ai du mal à saisir la façon dont je dois les utiliser.


Merci de ton aide !

bonjour
regarde ici le bout de code
http://arduino.cc/forum/index.php/topic,89413.msg686484.html#msg686484
la problématique est la même : comptage et restitution d'un nombre d'impulsions par secondes

Tom_Auser

#7
Feb 24, 2012, 01:24 pm Last Edit: Feb 24, 2012, 01:27 pm by Tom_Auser Reason: 1
Merci de votre aide !

Pour finir, j'ai décidé d'utiliser les interruptions.   :P

Je poste mon code au cas où quelqu'un serait intéressé  ;)

Code: [Select]
int compteurfm = 0;                                  // compteur de fronts montants
int nbrtour = 0;                                     // variable du nombre de tour
unsigned long compte_temps;                          // variable contenant le temps
int increm_temps = 1;                                // variable compteur de temps

void setup()
{
 pinMode (2, INPUT);
 attachInterrupt (0, anemometre, RISING);           // capteur de front montant
 Serial.begin(9600);                                // configuration de la transmission
}

void loop()
{
 delay(1000);
 Serial.print(2*3.1415*0.0455*5*nbrtour);            // calcul de la vitesse du vent et envoie sur serial
 Serial.println (" m/s");
 nbrtour = 0;
}

void anemometre()
{
 compteurfm++;
 if (compteurfm >4)
 {
   compteurfm = 0;
 }
 
 if (compteurfm == 4)    // car 4 fronts montants = 1 tour
 {
   nbrtour++;
 }
}


Voilà et bonne journée  XD

Super_Cinci

#8
Feb 24, 2012, 02:11 pm Last Edit: Feb 24, 2012, 02:17 pm by Super_Cinci Reason: 1
Si je peux me permettre... tu utilises cette formule pour calculer la vitesse du vent : 2*3.1415*0.0455*5*nbrtour. Ben moi, je te fais gagner du temps :
Code: [Select]

void loop()
{
  delay(1000);
  Serial.print(2*3.1415*0.0455*5*compteurfm/4);            // calcul de la vitesse du vent et envoie sur serial
  Serial.println (" m/s");
  compteurfm = 0;
}
void anemometre()
{
  compteurfm++;
}

tu devines ma pensée? en gros, là, tu es 4 fois plus précis...

EDIT : bonne idée, les interruptions! tu peux même faire mieux, en branchant ton anemomètre sur un timer : tu n'auras rien d'autre à faire que de relever la valeur du timer...

chrismaximilien

Salut,

Je viens de faire le montage avec mon anémomètre. Le programme fonctionne, mais j'ai une précision très mauvaise et quand le vent monte, je  n'ai presque pas de différence. Le matériel ne semble pas en mauvais état et j'entends un bruit qui me semble bon quand ça tourne, comme si l'aimant faisait bien son boulot...

Pensez- vous que cela soit du à un matériel de mauvaise qualité? Si oui quel genre d'anémomètre faut-il pour avoir une précision à 5 km/h près?

Merci pour le code qui m'a montré les interruptions.

Chris.

totolens

Fais un petit dump de ton compteurFM et des millis dans ton serial histoire de voir si ça augmente bien quand la vitesse du vent augmente.

Sinon j'ai pas testé, mais les cast implicites pour les opérations entre des int et des float se passent bien dans ton Serial.print(2*3.1415*0.0455*5*compteurfm/4);  ?
2 est un int, 2. est un float.

J'ai eu des soucis récemment sur un overflow à cause d'une valeur qu'il considérait comme int alors que pour moi c'était un long (multiplication d'un long par 10000, stocké dans un long, me renvoyait la mauvaise valeur).

totolens

Et c'est tout con, mais optimise ton code en déclarant une variable avec le résultat du calcul :
2*3.1415*0.0455*5/4
Tu n'auras plus qu'à multiplier par compteurFM pour avoir la bonne valeur  :)

tk5ep

Bonjour,

Je viens de terminer ma station météo qui comporte également un anémomètre. Le constructeur fournit une formule pour calculer la vitesse en m/s à partir de la fréquence des impulsions.

Je ne vois pas comment tu peux appliquer une formule autre que celle donnée par le constructeur... La vitesse de rotation d'une hélice doit dépendre de sa taille, son profil, etc....
Alors compter des impulsions et appliquer une formule quelconque me parait hasardeux..

Pour info , la formule pour mon anémomètre est :  vitesseVent = (frq * 0.08669) + 0.32

J'ai utilisé une librairie de fréquencemètre, je mesure pendant 1s et j'applique la formule...

Sinon si tu veux le faire toi-même tu utilises les interruptions et un timer. Il te faudra ensuite faire une comparaison entre le nombre d'impulsions à différentes vitesses de vent afin de faire une courbe et en déduire la formule...


A vérifier également, la forme des signaux issus de ton contact. Il serait surprenant que tu n'aies pas de rebonds de ton contact qu'il te faudra éliminer par un moyen ou un autre sous peine de mesures fausses...

Moi j'ai de la chance, mon anémomètre sort des signaux issus d'un codeur optique sur un optocoupleur, c'est très propre.

Bonne réalisation,

hameau

Salut,

La formule : V = 2*PI*F(N)*R*N est tout à fait correct (formule provenant de la vitesse tangentielle d'un point en rotation), par contre celle-ci : vitesseVent = (frq * 0.08669) + 0.32 est surprenante, car même quand l'anémomètre est à l'arrêt donc fréquence = 0  , il y a quand même une vitesse du vent ???, car 0*0.086669 =0, mais +0.32 donne 0.32 surprenant .

@+

tk5ep

C'est bien vu pour mon anémomètre. Le constructeur précise que la vitesse minimum mesurable est 0,5 m/s.

Je maintiens que la formule dont il est fait référence ne peut pas être utilisée telle quelle, sans connaître le facteur d'étalonnage...

Je cite :
"La fonction d'étalonnage (N dans la formule) traduit les propriétés aérodynamiques de l'anémomètre et les frottements qui altèrent le mouvement de rotation de l'anémomètre. Elle dépend des dimensions et matériaux de l'anémomètre et de sa vitesse de rotation. Seuls des essais en soufflerie à différents régimes de vent permettent de la déterminer précisément."

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy