// Pesquisar por "LiquidCrystal I2C" e selecionar uma das opções:
// LiquidCrystal I2C (by Frank de Brabander) (Arduino IDE 2.x) ou
// LiquidCrystal I2C (by Marco Schwarts) (Arduino IDE 1.x)
#include <LiquidCrystal_I2C.h>
// Pinos dos encoders
#define pin_Encoder_MotorA 32
#define pin_Encoder_MotorB 33
// Limiar de tempo sem interrupção para considerar que a velocidade é 0.
#define limiarZeraVelocidade 1e5 // Valor em us
// As variáveis "volatile" são acessadas nas funções das interrupções
volatile double velocidadeRPM_MotorA;
volatile double velocidadeRPM_MotorB;
volatile unsigned long tempoBordaAnteriorEncoder1; //tempo entre bordas de CLK
volatile unsigned long tempoBordaAnteriorEncoder2; //tempo entre bordas de CLK
LiquidCrystal_I2C lcd(0x27,16,2); //Display endereço 0x27, 16 colunas, 2 linhas
// -------------------------------------------------------------------
// Função para medição da velocidade pelo encoder A
// -------------------------------------------------------------------
void encoderHandlerA(){ // Usar essa linha com Arduino
//void IRAM_ATTR encoderHandlerA(){ // Usar essa linha com ESP32
unsigned long tempoBordaAtual = micros(); // Tempo da borda atual
unsigned long dt_us = tempoBordaAtual - tempoBordaAnteriorEncoder1;
velocidadeRPM_MotorA = 3*1e6/dt_us; // Para o disco de 20 furos
tempoBordaAnteriorEncoder1 = tempoBordaAtual;
}
// -------------------------------------------------------------------
// Função para medição da velocidade pelo encoder B
// -------------------------------------------------------------------
void encoderHandlerB(){ // Usar essa linha com Arduino
//void IRAM_ATTR encoderHandlerB(){ // Usar essa linha com ESP32
unsigned long tempoBordaAtual = micros(); // Tempo da borda atual
unsigned long dt_us = tempoBordaAtual - tempoBordaAnteriorEncoder2;
velocidadeRPM_MotorB = 3*1e6/dt_us; // Para o disco de 20 furos
tempoBordaAnteriorEncoder2 = tempoBordaAtual;
}
void setup(){
Serial.begin(9600);
// Habilita as interrupções nos pinos dos encoder no evanto RISING (subida)
attachInterrupt(digitalPinToInterrupt(pin_Encoder_MotorA), encoderHandlerA, RISING);
attachInterrupt(digitalPinToInterrupt(pin_Encoder_MotorB), encoderHandlerB, RISING);
// Inicia o display ------------------------------
lcd.init();
lcd.clear();
lcd.backlight(); // Liga a iluminação do display
// -----------------------------------------------
}
void loop(){
imprimeLCD();
zeraVelocidade();
delay(500);
}
void zeraVelocidade(){
// Zera a velocidade se deixar de ocorrer interrupções
unsigned long tempoAtual = micros();
if (tempoAtual - tempoBordaAnteriorEncoder1 > limiarZeraVelocidade)
velocidadeRPM_MotorA = 0;
if (tempoAtual - tempoBordaAnteriorEncoder2 > limiarZeraVelocidade)
velocidadeRPM_MotorB = 0;
}
void imprimeLCD(){
lcd.clear(); // Limpa o display
lcd.setCursor(0, 0); // Coluna 0, linha 0
lcd.print("VA(RPM) = ");
lcd.print(velocidadeRPM_MotorA);
lcd.setCursor(0, 1); // Coluna 0, linha 1
lcd.print("VB(RPM) = ");
lcd.print(velocidadeRPM_MotorB);
}