Go Down

Topic: Mise en fonction d'un Anémomètre (Read 2328 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...

Go Up