Bonsoir, j'aurais aimé faire un compte tour universel avec un laser...
Grosso modo, a chaque illumination de la LDR l'arduino compte un tour et me donne le résultat en T/min, alors a priori c'est simple, mais je n'arrive pas au raisonnement qui fera que mon code va être fonctionnel !
La première application va être de déterminer la vitesse de rotation de mon ventilateur de plafond (oui, comme dans les westerns)
Pour la partie captation, c'est très facile, un laser, un miroir, et une ldr. Le miroir est fixé sur une des pales du ventilateur, le laser posé sur la table en direction du plafond, et la ldr sous le retour du laser, aussi la ldr ne recevra une impulsion uniquement toutes les 4 pâles.
Mon problème c'est que je ne vois pas comment dire a l'Arduino, tu compte le nombre de tour pendant 15s puis tu multiplie par 4 et tu me balance le résultat dans le moniteur série.
Je sais qu'il va y avoir de l'incrémentation, par exemple il va compter +1 pendant 15s, et si il compte 20, je veux qu'il le multiplie par 4 pour me donner 80 T/min.
Je vais encore y réfléchir cette nuit, mais si vous avez des pistes / conseils je suis preneur
Merci d'avance
comme je l'utilise jamais, je n'ai pas fait gaffe que c'était I, je pensais à L comme Ln = Lenght, ça semblait cohérent. désolé pour l'erreur...
Compter sur une fenêtre de 15 secondes, ça a quelques inconvénients :
Actualisation seulement toutes les 15 sec, c'est super long...
si la vitesse bouge pendant les 15 sec, tu ne le verras pas, tu auras juste la vitesse moyenne sur cette fenêtre de temps.
si tu comptes 20, alors V = 80, ok. si tu comptes 19, V = 76 (soit une précision de +/-4 tr/min)... pas top la précision...
Avec pulseIn(), aux alentours de 80tr/min, tu auras une précision (théorique) de +/- 0,0001 tr/min et une actualisation à peu près toutes les secondes.
Tu dois aller te renseigner sur cette fonction pulseIn(), car tu n'as pas du tout compris comment elle marche. Ca renvoit une valeur numérique, pas un boolean!
Super_Cinci:
comme je l'utilise jamais, je n'ai pas fait gaffe que c'était I, je pensais à L comme Ln = Lenght, ça semblait cohérent. désolé pour l'erreur...
Compter sur une fenêtre de 15 secondes, ça a quelques inconvénients :
Actualisation seulement toutes les 15 sec, c'est super long...
si la vitesse bouge pendant les 15 sec, tu ne le verras pas, tu auras juste la vitesse moyenne sur cette fenêtre de temps.
si tu comptes 20, alors V = 80, ok. si tu comptes 19, V = 76 (soit une précision de +/-4 tr/min)... pas top la précision...
Avec pulseIn(), aux alentours de 80tr/min, tu auras une précision (théorique) de +/- 0,0001 tr/min et une actualisation à peu près toutes les secondes.
Tu dois aller te renseigner sur cette fonction pulseIn(), car tu n'as pas du tout compris comment elle marche. Ca renvoit une valeur numérique, pas un boolean!
De plus, je t'ai donné une formule que je ne vois pas dans ton code, as-tu compris ce que j'ai raconté à propos de fréquence / période?
Salut Super_Cinci, effectivement, j'avais mis de coté le fait que ça renvoi une valeur , je vais allez me renseignez plus en détail.
Pour la seconde partie, la formule que tu m'a donné, je ne l'ai pas utilisé dans le code parce que j'ai besoin pour certain truc de les voir fonctionner a "nu" pour comprendre comment ça fonctionne.
Bon, j'y arrive pas..
Ou du moins j'arrive pas a comprendre comment la fonction pulseIn pourrais m'aider...
Si j'ai bien compris elle mesure la durée d'une impulsion sur une broche de l'arduino ?
Mais deux choses :
La première, en quoi la durée de l'impulsion m'intéresse quand je doit mesuré l'écart entre deux des impulsions ?
La seconde, toujours si j'ai bien compris, la fonction calcul combien de temps la broche est en HIGH ou LOW, pour renvoyer une valeur de temps, hors, quand ma LDR reçois de la lumière, elle renvois une valeur de courant je croit (de 0 à 5V selon la resistance ?) donc comment lui faire calculer ça a ma fonction pulseIn ?
Ton capteur est à 0V au repos, et sort 5V à chaque passage de la pale puis se remet à l'état bas, ta fonction pulsIn() compte le temps entre chaque état haut.
Mais cette fonction me semble peu appropriée pour ça, car tu dois comptabiliser état Haut et état Bas pour avoir la valeur d'un tour.
Jean-François:
Ton capteur est à 0V au repos, est sort 5V à chaque passage de la pale et se remet à l'état bas, ta fonction pulsIn() compte le temps entre chaque état haut.
Mais cette fonction me semble peu appropriée pour ça, car tu dois comptabiliser état Haut et état Bas pour avoir la valeur d'un tour.
J'arrive a compter et a ne rater aucune détection en faible luminosité, mais j'ai plusieurs choses que je ne comprend pas...
Arriver a 20 ou 30 je veut qu'une led s'allume et clignote, hors quand j'arrive a 20, la led clignote mais me bloque le comptage et le programme, je suis obligé de fermer la fenêtre serial et de la ré-ouvrir...
Ensuite, y a t'il un moyen de régler le seuil a partir duquel je passe de LOW a HIGH ? Histoire de pouvoir faire face a plusieurs situation lumineuse ?
int capteur = 2;
volatile int state = LOW; // déclartion d'une variable volatile
int R = 3;
int B = 5;
int V = 4;
int rpm = 0;
void setup()
{
Serial.begin(9600);
pinMode(R, OUTPUT);
pinMode(B, OUTPUT);
pinMode(V, OUTPUT);
attachInterrupt(0, compt, RISING); // attache l'interruption externe n°0 à la fonction compt()
}
void loop()
{
state = digitalRead(capteur);
digitalWrite(R, state); // la LED reflète l'état de la variable
while(rpm == 20)
{
digitalWrite(B, HIGH);
delay(100);
digitalWrite(B, LOW);
delay(200);
}
while(rpm == 30)
{
digitalWrite(V, HIGH);
delay(100);
digitalWrite(V, LOW);
delay(200);
}
}
void compt() // la fonction appelée par l'interruption externe n°0
{
if(state == LOW)
{
rpm++;
Serial.println(rpm);
}
}
Après ça il ne me manque qu'à écrire la formule pour me convertir ça en T/min et je fait les tests sur mon ventilo
Bonjour,
Supprime tes delay pour faire clignoter tes leds.
Fait une recherche sur le site Arduino avec "blinking with out delay"
Voila déjà une des réponses : http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Bonsoir, effectivement ça résout le problème en partie, parce que de temps à autre le programme reste bloquer sur le blinkage de la led
Autrement, pourriez-vous m'aidez a comprendre ça (J'ai commenter directement le code) :
volatile byte half_revolutions; // Pourquoi volatile byte ?
unsigned int rpm;
unsigned long timeold;
void setup()
{
Serial.begin(9600); // Communication serie
attachInterrupt(0, rpm_fun, RISING); // interruption
half_revolutions = 0; //
rpm = 0; // Déclarer toutes les valeurs a 0 ??
timeold = 0; //
}
void loop()
{
if (half_revolutions >= 20) //
{ //
//Update RPM every 20 counts, increase this for better RPM resolution,
//decrease for faster update
rpm = 30*1000/(millis() - timeold)*half_revolutions; // Je ne comprend pas cette ligne
timeold = millis(); // Ni elle du coup
half_revolutions = 0; // Valeur mise a jour par l'interruption ?
Serial.println(rpm,DEC);
}
}
void rpm_fun()
{
half_revolutions++;
//Each rotation, this interrupt function is run twice // Pourquoi half_revolutions ?
}
volatile byte half_revolutions; // Pourquoi volatile byte ? volatile parce que la valeur est modifiée par l'interruption
unsigned int rpm;
unsigned long timeold;
void setup()
{
Serial.begin(9600); // Communication serie
attachInterrupt(0, rpm_fun, RISING); // interruption
half_revolutions = 0; //
rpm = 0; // Déclarer toutes les valeurs a 0 ??
timeold = 0; // devrait être initialisée avec millis() sinon la première mesure est fausse
}
void loop()
{
if (half_revolutions >= 20) //
{ //
//Update RPM every 20 counts, increase this for better RPM resolution,
//decrease for faster update
// conversion de 2 impulsion par tour en tours par minute
// on calcul le temps écoulé depuis la dernière mesure millis() - timeold puis on converti en tours/min
rpm = 30*1000/(millis() - timeold)*half_revolutions; // Je ne comprend pas cette ligne,
timeold = millis(); // Ni elle du coup. on mémorise le temps où on a effectué du dernier calcul
half_revolutions = 0; // Valeur mise a jour par l'interruption ? on remet le compteur à zéro
Serial.println(rpm,DEC);
}
}
void rpm_fun()
{
half_revolutions++;
//Each rotation, this interrupt function is run twice
// Pourquoi half_revolutions ? parce que l'interruption pète 2 fois par tour c'est écrit la ligne au-dessus
}
Le programme semble écrit pour un capteur qui génère 2 impulsions par tour.
volatil permet d'interdire au compilateur de faire des optimisations sur la variable en question. En particulier elle est relue à chaque fois qu'on l'utilise dans un calcul.
Pour le rpm, ça reviendrais au même de faire 30000(au lieu de 30*1000)/(millis() - timeold)*half_revolutions; ?
Oui c'est juste pour la clarté de la chose. le 1000 c'est pour indiquer que l'on manipule des millisecondes .
Pour une impulsion par tour il faut effectivement mettre 60.
Un exemple:
rpm = 60000/(millis() - timeold)*revolutions;
si révolution = 1
si (millis() - timeold) = 1000 1000 millisecondes = 1s