tachymètre sur ELCD série

Bonjour à tous, j'ai compilé ce petit programme pour afficher les tr.min sur un ecran ELCD 4x20 (lextronic), tout fonctionne bien mais une fois que mon moteur arrête de tourner, la valeur reste sur une valeur aléatoire, auriez vous une idée, merci.

volatile word rpmcount;                    // variable rpmcount
unsigned long rpm;                                  // variable rpm
unsigned long timeold;


void setup(){
  Serial.begin(19200);                      // Initialise la connexion
  ELCD_initialize();
  delay(200);
  ELCD_Clear_LCD();
  ELCD_Cursor_OFF;
  ELCD_Cursor_Position(0, 1);
  ELCD_put_str("Rpm:");
  delay (30);
 
  attachInterrupt(0, rpm_fun, RISING);
  rpmcount = 0;
  rpm = 0;
  timeold = 0;
}

void loop(){
//Tachymètre
if (rpmcount >= 100){
  rpm = 60*1000/(millis() - timeold)*rpmcount;
  timeold = micros();
  rpmcount = 0;
  String rpm1 = (String(rpm));
  ELCD_Cursor_Position(5, 1);
  ELCD_put_chr(rpm1.charAt(0));
  ELCD_Cursor_Position(6, 1);
  ELCD_put_chr(rpm1.charAt(1));
  ELCD_Cursor_Position(7, 1);
  ELCD_put_chr(rpm1.charAt(2));
  ELCD_Cursor_Position(8, 1);
  ELCD_put_chr(rpm1.charAt(3));
  ELCD_Cursor_Position(9, 1);
  ELCD_put_chr(rpm1.charAt(4));
  }
}
 
  // Fonction RPM
  void rpm_fun() {
  rpmcount++;                //Each rotation, this interrupt function is run twice
  }
  
  
/* Initialize l'afficheur lcd */
void ELCD_initialize(){
  Serial.print(0xA0, BYTE);
}

/* Cache le curseur */
void ELCD_Cursor_OFF(){
  Serial.print(0xA3, BYTE);
  Serial.print(0x0C, BYTE); 
}

/* Affiche le curseur */
void ELCD_Cursor_ON(){
  Serial.print(0xA3, BYTE);
  Serial.print(0x0E, BYTE);  
}

/* Efface l'écran et place le curseur à (0, 0) */
void ELCD_Clear_LCD(){
  Serial.print(0xA3, BYTE);
  Serial.print(0x01, BYTE);
}

/* Place le curseur à la position (x, y) */
void ELCD_Cursor_Position(int x, int y){
  Serial.print(0xA1, BYTE);
  Serial.print(x, BYTE);
  Serial.print(y, BYTE);  
}

/* Affiche une chaine de caractéres (char[] terminé par \0) sur l'afficheur */
void ELCD_put_str(char *str){
  Serial.print(0xA2, BYTE);
  while(*str)
    Serial.print(*str++);
  Serial.print(0, BYTE);  
}

/* Affiche un caratéres ASCII sur l'afficheur (caractéres spéciaux aux LCD non pris en charge) */
void ELCD_put_chr(char ch){
  Serial.print(0xA2, BYTE);
  Serial.print(ch);
  Serial.print(0, BYTE);  
}

/* Définit un caractére personalisé à l'index défini (de 8 à 15) suivant le tableau newChar[],
 de structure identique à celui utilisé par la fonction createChar de la lib LiquidCrystal.
 Si showAfter = 1 le caractére sera afficher aprés la création, sinon il ne sera afficher qu'aprés un ELCD_put_chr(index) */
void ELCD_create_char(byte index, byte newChar[], byte showAfter) {
  if(showAfter)
    Serial.print(0xA4, BYTE);
  else
    Serial.print(0xA5, BYTE);
  Serial.print(index, BYTE);
  Serial.print(newChar[0] & 0x1F, BYTE);
  Serial.print(newChar[1] & 0x1F, BYTE);
  Serial.print(newChar[2] & 0x1F, BYTE);
  Serial.print(newChar[3] & 0x1F, BYTE);
  Serial.print(newChar[4] & 0x1F, BYTE);
  Serial.print(newChar[5] & 0x1F, BYTE);
  Serial.print(newChar[6] & 0x1F, BYTE);
  Serial.print(newChar[7] & 0x1F, BYTE);
}

Bonsoir,
Lorsque rpmcount est inférieur à 100 , tu ne faits rien donc ton affichage reste sur le dernier traitement >=100.
Il faut que tu mettes un "else" dans ton "if" et que tu effaces ton affichage.
icare

Salut icare,

Bien crois tu que je n'ai pas essayé, mais toujours même résultat. =(

Fais un if en utilisant la fonction micros(), si la valeur de temps est plus grande que xxx tu estime que ton moteur ne tourne plus et que l'affichage doit être mis à 0

Merci Jean-François mais comment fait on cela ? peux tu mettre le bout de mon code modifié, en te remerciant.

en plus dans ma boucle principale j'ai deux fonctions, une pour le tachy et une pour le thermocouple, mais lorsque le moteur tourne, les valeurs aafichées sont illisibles, la temp n'est plus correcte alors que au repos, la température et ok .

Je n'y comprends rien., merci pour votre aide.

Je te mets un bout de code d’un de mes projets :

  //if (millis() - timeold > 700 && FilteredSpeed > 0){    FilteredSpeed=0;  }
  odoDist=odo+distance[top]/100000;
  if (millis() - timeold > 500 && Speed > 0){
    Speed=0.00;
  }

  if (rpmcount >= 6) { 
    Speed = 0.002018/36/(millis() - timeold)*rpmcount*1000*3600;
    /*
    if (Speed > FilteredSpeed + 10 || Speed < FilteredSpeed - 10 )
     {
     Speed=FilteredSpeed;
     }
     
     FilteredSpeed=lpfilter(Speed*.9+(FilteredSpeed*.1), filterVal , FilteredSpeed); 
     */

    timeold = millis();
    rpmcount = 0;

  }

  if (millis()-TimeOldSpeed >100) // && newdata == false)
  {

    if (Speed < 10){
      lcd.setCursor(14, 0) ; 
      lcd.write(' ') ; 
    }
    lcd.setCursor(10, 0) ; 
    //lcd.print(gps.f_speed_kmph()) ; 
    lcd.print(Speed,2) ;  //lcd.print(FilteredSpeed) ;
    lcd.setCursor(9, 1) ; 
    lcd.print(odoDist,3) ;  // affiche la distance totale parcourue
    TimeOldSpeed=millis();
  }

ok merci Jean-François je vais essayé de compiler cela.

Et pour ce qui est de l'instabilité de l'affichage des deux valeurs "tachymetre" et "température" ? as tu une idée, est ce le même problème?

Mets la totalité de ton code avec la mesure de température, pour voir :grin:

oui voilà :

//Bibliothèques
#include  <MAX31855.h>
#include <Wire.h>

unsigned  char thermocoupleSO = A4;        //Thermocouple
unsigned  char thermocoupleCS = A5;        //Thermocouple
unsigned  char thermocoupleCLK = A6;       //Thermocouple
int temperature = 0;

volatile word rpmcount;                    // variable rpmcount
unsigned long rpm;                         // variable rpm
unsigned long timeold;

MAX31855 MAX31855(thermocoupleSO, thermocoupleCS, thermocoupleCLK);  //Thermocouple

void setup(){
  Serial.begin(19200);                     // Initialise la connexion
  ELCD_initialize();
  delay(200);
  ELCD_Clear_LCD();
  ELCD_Cursor_OFF;
  ELCD_Cursor_Position(0, 0);
  ELCD_put_str("temp:");
  delay (30);
  ELCD_Cursor_Position(0, 1);
  ELCD_put_str("Rpm:");
  delay (30);
 
  attachInterrupt(0, rpm_fun, RISING);
  rpmcount = 0;
  rpm = 0;
  timeold = 0;
}

void loop(){

// Tachymetre
if (rpmcount >= 100){
  rpm = 1000000*60/(micros() - timeold)*rpmcount;
  timeold = micros();
  rpmcount = 0;
  }
  String rpm1 = (String(rpm));
  ELCD_Cursor_Position(5, 1);
  ELCD_put_chr(rpm1.charAt(0));
  ELCD_Cursor_Position(6, 1);
  ELCD_put_chr(rpm1.charAt(1));
  ELCD_Cursor_Position(7, 1);
  ELCD_put_chr(rpm1.charAt(2));
  ELCD_Cursor_Position(8, 1);
  ELCD_put_chr(rpm1.charAt(3));
  ELCD_Cursor_Position(9, 1);
  ELCD_put_chr(rpm1.charAt(4));
 
//Thermocouple
temperature = MAX31855.readThermocouple(CELSIUS);
String temp = (String(temperature));
ELCD_Cursor_Position(5, 0);
ELCD_put_chr(temp.charAt(0));
ELCD_Cursor_Position(6, 0);
ELCD_put_chr(temp.charAt(1));
ELCD_Cursor_Position(8, 0);
ELCD_put_chr((char)223);
  
}

// Fonction RPM
void rpm_fun() {
rpmcount++;                //Each rotation, this interrupt function is run twice
}
  
  
/* Initialize l'afficheur lcd */
void ELCD_initialize(){
  Serial.print(0xA0, BYTE);
}

/* Cache le curseur */
void ELCD_Cursor_OFF(){
  Serial.print(0xA3, BYTE);
  Serial.print(0x0C, BYTE); 
}

/* Affiche le curseur */
void ELCD_Cursor_ON(){
  Serial.print(0xA3, BYTE);
  Serial.print(0x0E, BYTE);  
}

/* Efface l'écran et place le curseur à (0, 0) */
void ELCD_Clear_LCD(){
  Serial.print(0xA3, BYTE);
  Serial.print(0x01, BYTE);
}

/* Place le curseur à la position (x, y) */
void ELCD_Cursor_Position(int x, int y){
  Serial.print(0xA1, BYTE);
  Serial.print(x, BYTE);
  Serial.print(y, BYTE);  
}

/* Affiche une chaine de caractéres (char[] terminé par \0) sur l'afficheur */
void ELCD_put_str(char *str){
  Serial.print(0xA2, BYTE);
  while(*str)
    Serial.print(*str++);
  Serial.print(0, BYTE);  
}

/* Affiche un caratéres ASCII sur l'afficheur (caractéres spéciaux aux LCD non pris en charge) */
void ELCD_put_chr(char ch){
  Serial.print(0xA2, BYTE);
  Serial.print(ch);
  Serial.print(0, BYTE);  
}

/* Définit un caractére personalisé à l'index défini (de 8 à 15) suivant le tableau newChar[],
 de structure identique à celui utilisé par la fonction createChar de la lib LiquidCrystal.
 Si showAfter = 1 le caractére sera afficher aprés la création, sinon il ne sera afficher qu'aprés un ELCD_put_chr(index) */
void ELCD_create_char(byte index, byte newChar[], byte showAfter) {
  if(showAfter)
    Serial.print(0xA4, BYTE);
  else
    Serial.print(0xA5, BYTE);
  Serial.print(index, BYTE);
  Serial.print(newChar[0] & 0x1F, BYTE);
  Serial.print(newChar[1] & 0x1F, BYTE);
  Serial.print(newChar[2] & 0x1F, BYTE);
  Serial.print(newChar[3] & 0x1F, BYTE);
  Serial.print(newChar[4] & 0x1F, BYTE);
  Serial.print(newChar[5] & 0x1F, BYTE);
  Serial.print(newChar[6] & 0x1F, BYTE);
  Serial.print(newChar[7] & 0x1F, BYTE);
}

? pas de solution ?

Tu devrais essayer de faire un effacement de l'écran à chaque cycle.

ah oui j'y avais pas pensais, je vais essayé.

Merci Jean-François.

Afficher une valeur qui bouge beaucoup, c'est pas facile. le top est d'utiliser un timer qui envoie une MAJ au LCD sur des intervalles réguliers (genre 10 fois par seconde).

Si tu rafraichis ton affichage trop vite, ça devient vite illisible.

bien je vais également utiliser le petit SoftTimer de Barbudor :slight_smile:

Jean-François:
Tu devrais essayer de faire un effacement de l'écran à chaque cycle.

Pas top d'effacer tout l'écran, au final ça va donner un effet de clignotement désagréablement.

Comme la gestion des "ticks" est fait via une interruption tu doit pouvoir tout simplement ajouter un delay() avant la fin de loop().

Un delay ? avant la boucle mais le reste de ma boucle ne doit pas être impactée car il n 'y a pas que le tachymètre qui tourne.

Avec millis()

ah oui, je vais essayé, as tu un exemple ?

Ici :

Dans le 1er if, tu remplaces le traitement de l'état de la led par l'affichage de ton écran.

bonjour à tous, voilà j'utilise ce code pour afficher la vitesse de rotation rpm (0 à 99000 tr.min) d'un moteur (capteur magnétique), la valeur est correcte est stable en liaison série sur le monitor, mais lorsque je souhaite afficher la valeur sur mon afficheur, toous les chiffres défilent trop vite, rien n'est stable.

Comment faire, merci pour votre aide.

// Tachymetre
if (rpmcount >= 40 ){
  rpm = 60*1000/(millis() - timeold)*rpmcount;
  timeold = millis();
  rpmcount = 0;
  rpm1 = (String(rpm));
  ELCD_Cursor_Position(5, 1);
  ELCD_put_chr(rpm1.charAt(0));
  ELCD_Cursor_Position(6, 1);
  ELCD_put_chr(rpm1.charAt(1));
  ELCD_Cursor_Position(7, 1);
  ELCD_put_chr(rpm1.charAt(2));
  ELCD_Cursor_Position(8, 1);
  ELCD_put_chr(rpm1.charAt(3));
  ELCD_Cursor_Position(9, 1);
  ELCD_put_chr(rpm1.charAt(4));
}