Atualização de rpm fora do loop

Não consigo atualizar a informação do rpm medido de forma automática no lcd (16x2)
essa função fica fora da void loop e esta em forma de função. arduino mega, ponte H l298n. sensor optico

#include <ctype.h>
#include <string.h>
#include <Button.h>
#include <Keypad.h>
#include <LiquidCrystal.h>

#define rs 6
#define en 7
#define d4 8
#define d5 9
#define d6 10
#define d7 11

LiquidCrystal lcd = LiquidCrystal(6,7,8,9,10,11);

#define pinoSensor 2
#define btCima 22
#define btBaixo 23
#define btSeta 24
#define btReseta 25

#define ledVd 29
#define ledVm 28
#define ledAm 30
#define ledAz 31

#define sA  44
#define sB  45
#define velMotor 46

#define linha1 A0
#define linha2 A1
#define linha3 A2
#define linha4 A3
#define coluna1 A4
#define coluna2 A5
#define coluna3 A6
#define coluna4 A7

const byte nL=4;
const byte nC=4;
byte pinL[nL]={linha1, linha2, linha3, linha4};
byte pinC[nC]={coluna1, coluna2, coluna3, coluna4};
char teclas[nL][nC]=
{
  {'1','2','3','A'},     

  {'4','5','6','B'},

  {'7','8','9','C'},

  {'*','0','#','D'}
};
Keypad teclado=Keypad(makeKeymap(teclas),pinL,pinC,nL,nC);

Button nav_Cima=Button(btCima, BUTTON_PULLUP_INTERNAL, true, 5);
Button nav_Baixo=Button(btBaixo, BUTTON_PULLUP_INTERNAL, true, 5);
Button nav_Seta=Button(btSeta, BUTTON_PULLUP_INTERNAL, true, 5);
Button nav_Reseta=Button(btReseta, BUTTON_PULLUP_INTERNAL, true, 5);



void mudaMenu();
void nMenus();


String msg0;
String msgA;
String msgB;
String msgC;
String msgD;
String msgE;

volatile unsigned long pulsos;
unsigned long marca;
unsigned int pulsos_por_volta = 8;
int rpm;

int menu=0;
bool atualizarMenu=true;

bool atualizarRpm=true;
bool flag_rpm=false;

bool leTeclado1=false;
bool leTeclado2=false;
 
bool permiteNavegar=true;
bool conjunto = false; 
bool novo = false;
char valorTemp[4]="___"; 
long valor=-1;

bool sentido=true;
bool ligado=false;
byte vel=127;


void setup(){

  msg0="Menu CCM";
  msgA="1. Ligar motor";
  msgB="2. Sentido B";
  msgC="3. Setar vel.";
  msgD="4. Rpm";
  msgE="5. Mdo. Auto."; 
  
  pinMode(pinoSensor, INPUT_PULLUP);
  pinMode(velMotor,OUTPUT);
  pinMode(sA, OUTPUT);
  pinMode(sB, OUTPUT);  
  pinMode(ledVd, OUTPUT);                            
  pinMode(ledVm, OUTPUT);
  pinMode(ledAm, OUTPUT);                            
  pinMode(ledAz, OUTPUT);
  
  digitalWrite(sA, 1);
  digitalWrite(sB, 0);
  analogWrite(velMotor,0);

  
  
  attachInterrupt(digitalPinToInterrupt(pinoSensor),contaPulsos,RISING);
  lcd.begin(16,2);
  Serial.begin(115200);
  
  pulsos = 0;
  rpm = 0;
  }

  void loop(){
    
    mudaMenu();
    nMenus();
    
    
    
 if ((millis()-marca)>1000) {   
    noInterrupts(); // desligo as interrupções
    rpm=(60*1000/pulsos_por_volta)/(millis()-marca)*pulsos;
    
    unsigned temp=pulsos;
    pulsos=0;
    interrupts();
    Serial.print("RPM = ");
    Serial.println(rpm, DEC);
    Serial.println(vel);    
    marca = millis();  
 
  }
}

 void contaPulsos(){
  pulsos++;
}

void mudaMenu(){

char lido=teclado.getKey();

if(leTeclado1){
  if(lido!=0){
    if(lido=='#'){
       for(int i=0; i<strlen(valorTemp); i++){
         if (valorTemp[i]=='_') valorTemp[i]='0';
          }
          valor=atoi(valorTemp);          
            if(valor>100){
            valor=-1;
            strncpy(valorTemp,"___",3);
            lcd.setCursor(0,1);
            lcd.print(valorTemp);
           }else{            
            strncpy(valorTemp,"___",3);
            permiteNavegar = true;
            menu=2;            
            atualizarMenu=true;
            leTeclado1=false;            
            vel=map(valor, 0, 100, 0, 255);            
            analogWrite(velMotor,vel);
            }
      }else{
        if(isdigit(lido)){
          valorTemp[0]=valorTemp[1];
          valorTemp[1]=valorTemp[2];
          valorTemp[2]=lido;
          lcd.setCursor(0,1);
          lcd.print(valorTemp);
         }
      }
    
  }             
} 
if(leTeclado2){
  if(lido=='A'){
      
        if(vel<255){                  
        vel++;
        analogWrite(velMotor,vel);
        atualizarRpm=true;        
        }
     }
     
  if(lido=='B'){
      
        if(vel>0){                  
        vel--;
        analogWrite(velMotor,vel);
        atualizarRpm=true;
        }
     }
  }
  bool cima=nav_Cima.uniquePress();
  bool baixo=nav_Baixo.uniquePress();
  bool seta=nav_Seta.uniquePress();
  bool reseta=nav_Reseta.uniquePress();
   if(cima){
    if(permiteNavegar){
      atualizarMenu=true;
      menu++;
      if(menu>4)menu=0;
      }
    }
    if(baixo){
    if(permiteNavegar){
      atualizarMenu=true;
      menu--;
      if(menu<0)menu=4;
      }
    }
    if(seta){      
      switch(menu){
        case 0:
          ligado=!ligado;
          if(ligado){
            analogWrite(velMotor,vel);
            msgA="1.Desligar motor";
            }
            else{
              analogWrite(velMotor,0);
              msgA="1. Ligar motor";
              }
              atualizarMenu=true;
         break;

         case 1:
           sentido=!sentido;
             if(sentido){
              digitalWrite(sA, 0);
              digitalWrite(sB, 1);
              msgB="B. Sentido A";              
              }else{
                digitalWrite(sB, 0);
                digitalWrite(sA, 1);
                msgB="2. Sentido B";
                }
                atualizarMenu=true;
           break;

           case 2: 
             leTeclado1=true;             
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("Insira % vel: ");
             lcd.setCursor(0,1);
             lcd.print(valorTemp); 
           break;  

           case 3: 
             leTeclado2=true;                
               if(atualizarRpm){
                 lcd.clear();
                 lcd.setCursor(0,0);
                 lcd.print("Rpm medido=");
                 lcd.setCursor(12,0);
                 lcd.print(rpm, DEC);
                 lcd.setCursor(0,1);
                 lcd.print("Tcl A+   Tcl B-");
                 atualizarRpm=true; 
                 }            
           break;   
                           
         }
    }  
}

void nMenus(){
  switch(menu){
    
    case 0:
      if (atualizarMenu){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(msg0);
        lcd.setCursor(0,1);
        lcd.print(msgA);
        atualizarMenu=false;
      }
      break;

    case 1:
      if (atualizarMenu){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(msg0);
        lcd.setCursor(0,1);
        lcd.print(msgB);
        atualizarMenu=false;
      }
      break;

    case 2:
      if (atualizarMenu){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(msg0);
        lcd.setCursor(0,1);
        lcd.print(msgC);
        atualizarMenu=false;
      }
      break;

    case 3:
      if (atualizarMenu){
        //if
        lcd.clear();
        lcd.setCursor(0,0);        
        lcd.print(msg0);        
        lcd.setCursor(0,1);
        lcd.print(msgD);
        atualizarMenu=false;
      }
      break;  

    case 4:
      if (atualizarMenu){
        lcd.clear();
        lcd.setCursor(0,0);        
        lcd.print(msg0);        
        lcd.setCursor(0,1);
        lcd.print(msgE);
        atualizarMenu=false;
      }
      break; 
  }
}

Olá,

Esqueceste de mostrar o esquema e o código. Só esse bocado não chega :wink: . Quando escreveres a próxima mensagem, antes de colocares o código clica no botão </> para ficar correctamente formatado.

Não tenho experiência com essa biblioteca "Button". Parece que usas a função uniquePress() para obter o estado dos botões e navegar nos menus.

De acordo com a documentação que encontrei ( Arduino Playground - Button Library ) essa função, uniquePress(), devolve verdadeiro apenas numa alteração do estado do botão e quando é premido:

"Checks to see if the state of the button has changed AND the button is pressed. This will only return true the first time the button has been pressed. (As opposed to the isPressed() which will return true as long as the button is pressed. "

No teu código, parece-me que mostras o valor RPM no LCD apenas quando pressionas o botão para seleccionar o RPM. Possivelmente terias de pressionar varias vezes no botão para actualizar o RPM... o que não é o pretendido.

Sugiro que uses uma variável de controlo global, uma flag (true/false), que fica "true" quando seleccionas o menu RPM e "false" noutros casos. Depois no loop bastaria chamar outra função que apenas actualizaria o RPM no LCD no caso da flag estar a "true".

Por exemplo:

bool menuRPMligado = false;

Poderias activar a flag quando o menu RPM é accionado:

           case 3:
             menuRPMligado=true;
             leTeclado2=true;
             leTeclado1=false;
               lcd.clear();
               lcd.setCursor(0,0);
               lcd.print("Rpm medido=");
               lcd.setCursor(12,0);
               lcd.print(rpm, DEC);
               lcd.setCursor(0,1);
               lcd.print("Tcl A+   Tcl B-");
            break;

Depois terias de colocar esta flag a "false" quando o utilizador seleccionasse outras opções...

A função para actualizar o RPM no LCD poderia ser igual ao código anterior:

void actualizaRPMnoLCD(void){
               lcd.clear();
               lcd.setCursor(0,0);
               lcd.print("Rpm medido=");
               lcd.setCursor(12,0);
               lcd.print(rpm, DEC);
               lcd.setCursor(0,1);
               lcd.print("Tcl A+   Tcl B-");
}

Depois é chamar essa função no loop() caso a flag seja verdadeira:

void loop() {

  ...

  if (menuRPMligado) {
    actualizaRPMnoLCD();
  }
}
1 Like