Go Down

Topic: Sauvegarde d'une valeur de variable (Read 1 time) previous topic - next topic

Mike74

Bonjour,

Voilà je souhaiterais savoir si il est possible de sauvegarder la valeur d'une variable tous les "x secondes".

Je m'explique, j'ai une variable "rpm" qui est apparemment trop instable ou rapide (capteur magnétique KMZ) pour servir de référence pour différentes commandes (voir mes posts précédents), donc afin de pouvoir récupérer une valeur stable, l'idée serait de stocker tous les "x secondes" la valeur lue afin d'avoir une sorte de moyenne servant de référence pour différentes commandes (ex : arrêt moteur quand rpm=4000).

Merci pour votre aide.

fdufnews

Il vaut mieux faire une moyenne glissante sur plusieurs échantillons consécutifs

Mike74


fdufnews

Plusieurs manières
- un tableau contenant les N dernières valeurs et on fait la moyenne sur ces valeurs. A chaque nouvelle mesure on enlève la plus ancienne et on ajoute la nouvelle.
- une moyenne pondérée. V = a * mesure + (1-a) * Vprécédent. Ce filtre dispense de gérer un tableau. En jouant sur la valeur de a on pondère plus ou moins l'influence de la dernière mesures par rapport aux précédentes.

Il y a eu un sujet là-dessus il y a peu de temps http://arduino.cc/forum/index.php/topic,132674.0.html

Mike74


Mike74

Bonjour,

Ou puis je trouver la librairie ipfilter () ?


merci

fdufnews

#6
Dec 10, 2012, 12:58 pm Last Edit: Dec 10, 2012, 01:33 pm by fdufnews Reason: 1
C'est pas ipfilter. C'est lpfilter. C'est une fonction elle est dans le code qui se trouve dans le lien que je t'avais mis un peu plus haut.

Mike74

oui c'est lpFilter mais est-ce une fonction déjà installée sur l'arduino, existe-elle sur chipKit Max32 ?

Mike74

comment l'appliquer à ce code qui permet de lire et d'afficher la vitesse rpm :

Code: [Select]

unsigned byte rpmcount;
float rpm;

unsigned long timeold;

void setup()
{
   Serial.begin(9600);
   attachInterrupt(0, rpm_fun, RISING);
}

void loop() {
   if (rpmcount >= 20) {
     rpm = 60*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
   
         
   Serial.println(rpm);
   }

void rpm_fun()
{
   rpmcount++;
   //Each rotation, this interrupt function is run twice
}


merci

fdufnews


comment l'appliquer à ce code qui permet de lire et d'afficher la vitesse rpm :
merci



Code: [Select]

unsigned byte rpmcount;
float rpm, rpmFiltre;
// Ajuster la valeur suivante entre 0 et 1.0
// plus la valeur est faible plus la mesure actuelle est prépondérante et donc le résultat suit de plus près les variations de l'entrée
// plus la valeur est élevée plus l'historique est prépondérant et donc les variations rapides de l'entrée sont atténuées
float coef = 0.5;

unsigned long timeold;

void setup()
{
   Serial.begin(9600);
   attachInterrupt(0, rpm_fun, RISING);
}

void loop() {
   if (rpmcount >= 20) {
     rpm = 60*1000/(millis() - timeold)*rpmcount;
     rpmFiltre = lpfilter(rpm, coef, rpmFiltre );
     timeold = millis();
     rpmcount = 0;
   
         
   Serial.println(rpm);
   }

void rpm_fun()
{
   rpmcount++;
   //Each rotation, this interrupt function is run twice
}


float lpfilter(float data, float filterVal, float filteredVal){
  if (filterVal > 1){
    filterVal = .99;
  }
  else if (filterVal <= 0){
    filterVal = 0;
  }

  filteredVal = (data * (1 - filterVal)) + (filteredVal * filterVal);
  return filteredVal;
}




Mike74

super je te remercie par contre saurais tu comment je peux remettre la valeur rpmFiltre affichée à zero lorsque mon moteur ne tourne plus et comment afficher cette valeur sur un afficheur série ELCD 4 x 20  (lextronic) car cela fait des mois que je me bats avec ce bout de code et je n'y comprend rien. merci.

Pour la remise à zero j'ai essayé cela mais ca marche pas.

Code: [Select]

volatile byte rpmcount = 0;
float rpm, rpmFiltre = 0;
// Ajuster la valeur suivante entre 0 et 1.0
// plus la valeur est faible plus la mesure actuelle est prépondérante et donc le résultat suit de plus près les variations de l'entrée
// plus la valeur est élevée plus l'historique est prépondérant et donc les variations rapides de l'entrée sont atténuées
float coef = 0.99;

unsigned long timeold = 0;
unsigned long timeoldmesure = 0;

void setup()
{
   Serial.begin(9600);
   attachInterrupt(0, rpm_fun, RISING);
}

void loop() {
   if (rpmcount >= 20){
     rpm = 60*1000/(millis() - timeold)*rpmcount; 
     timeold = millis();
     rpmcount = 0.00;
   }
   
  if ((rpm > 100) && ((millis() - timeoldmesure)>1000)){
     rpmFiltre = lpfilter(rpm, coef, rpmFiltre );
  }
  else {
     rpmFiltre = 0;
  }   
     
   Serial.println(rpmFiltre);
 
}

void rpm_fun() {
   rpmcount++;
   //Each rotation, this interrupt function is run twice
}


float lpfilter(float data, float filterVal, float filteredVal){
  if (filterVal > 1){
    filterVal = .99;
  }
  else if (filterVal <= 0){
    filterVal = 0;
  }

  filteredVal = (data * (1 - filterVal)) + (filteredVal * filterVal);
  return filteredVal;
}

Mike74

je m'aperçois egalement que la valeur rpmFiltre augmente avec le temps sans pour autant que mon moteur accélère ??


Go Up