#include <Encoder.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Definir os pinos do encoder e botões
#define ENCODER_PIN_A 2
#define ENCODER_PIN_B 3
#define RESET_PIN A1
#define MODE_PIN A2
#define RECORD_PIN A3
// Criar uma instância do encoder
Encoder encoder(ENCODER_PIN_A, ENCODER_PIN_B);
// Criar uma instância do display LCD I2C (endereço 0x27 e 20 colunas x 4 linhas)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Variáveis de controle e estado
long oldPosition = 0;
long newPosition = 0;
long pulseCount = 0;
long startPosition = 0;
long currentPosition = 0;
bool isRecording = false;
bool inMenu = true;
bool showResult = false;
// Variáveis para deslocamento
long positiveDisplacement = 0;
long negativeDisplacement = 0;
// Fatores de conversão
const float pulsesPerMicrometer = 4.0;
const float micrometersPerPulse = 1.0 / pulsesPerMicrometer;
const float micrometersPerMillimeter = 1000.0;
const float micrometersPerCentimeter = 10000.0;
// Variáveis para controlar a atualização do display
bool displayUpdated = false;
void setup() {
// Inicializar o display LCD com o número de colunas e linhas
lcd.begin(20, 4);
lcd.backlight();
// Configurar os pinos dos botões como entrada com pull-up interno
pinMode(RESET_PIN, INPUT_PULLUP);
pinMode(MODE_PIN, INPUT_PULLUP);
pinMode(RECORD_PIN, INPUT_PULLUP);
// Inicializar o encoder
encoder.write(0);
// Inicializar comunicação serial para depuração
Serial.begin(9600);
}
void loop() {
// Verificar se o pino RESET_PIN está conectado ao GND para zerar o contador
if (digitalRead(RESET_PIN) == LOW) {
delay(10); // Debounce
if (digitalRead(RESET_PIN) == LOW) {
pulseCount = 0;
positiveDisplacement = 0;
negativeDisplacement = 0;
encoder.write(0);
oldPosition = 0;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Medidas zeradas!");
delay(1000); // Mostrar por 1 segundo antes de voltar ao menu
lcd.clear();
displayUpdated = false; // Forçar atualização do display na próxima iteração
}
}
// Verificar se o pino MODE_PIN está conectado ao GND para alternar entre menu e gravação
if (digitalRead(MODE_PIN) == LOW) {
delay(10); // Debounce
if (digitalRead(MODE_PIN) == LOW) {
if (!showResult) {
inMenu = !inMenu; // Alternar entre menu e gravação
lcd.clear();
displayUpdated = false; // Forçar atualização do display
delay(1000); // Aguardar 1 segundo antes de permitir nova troca
} else {
showResult = false; // Sair do modo de exibição de resultados
lcd.clear();
displayUpdated = false; // Forçar atualização do display
}
}
}
if (inMenu && !isRecording && !showResult) {
// Mostrar medidas no menu principal
newPosition = encoder.read();
long pulseDelta = newPosition - oldPosition;
pulseCount += pulseDelta;
float micrometers = pulseCount * micrometersPerPulse;
float millimeters = micrometers / micrometersPerMillimeter;
float centimeters = micrometers / micrometersPerCentimeter;
lcd.backlight();
// Atualizar o display apenas se houver mudança
if (!displayUpdated || pulseDelta != 0) {
lcd.setCursor(0,0);
lcd.print("* Medicao Digital *");
lcd.setCursor(0,1);
lcd.print(" **********");
lcd.setCursor(0,2);
lcd.print(" ********");
lcd.setCursor(0,3);
lcd.print(" Wagner Koller");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Medidas:1Zera 2Menu");
lcd.setCursor(0, 1);
lcd.print(micrometers);
lcd.print(" u");
lcd.setCursor(0, 2);
lcd.print(millimeters);
lcd.print(" mm");
lcd.setCursor(0, 3);
lcd.print(centimeters);
lcd.print(" cm ");
displayUpdated = true; // Marcar o display como atualizado
}
oldPosition = newPosition;
delay(500); // Atraso para melhor visualização
} else if (!isRecording && !showResult) {
// Modo de gravação esperando o início
if (!displayUpdated) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" MENU " );
lcd.setCursor(0, 1);
lcd.print("1 Zera medidas ");
lcd.setCursor(0, 2);
lcd.print("2 Tela Inicial");
lcd.setCursor(0, 3);
lcd.print("3 Inicia Gravacao ");
displayUpdated = true; // Marcar o display como atualizado
}
// Verificar se o pino RECORD_PIN está conectado ao GND para iniciar a gravação
if (digitalRead(RECORD_PIN) == LOW) {
delay(10); // Debounce
if (digitalRead(RECORD_PIN) == LOW) {
isRecording = true;
startPosition = encoder.read();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Gravando... ");
positiveDisplacement = 0;
negativeDisplacement = 0;
delay(500);
displayUpdated = false; // Forçar atualização do display durante a gravação
}
}
} else if (isRecording) {
// Modo de gravação em andamento, mostrando o deslocamento em tempo real
currentPosition = encoder.read();
long displacementDelta = currentPosition - startPosition;
startPosition = currentPosition; // Atualizar a posição inicial para o próximo ciclo
// Calcular deslocamento para direita e esquerda
if (displacementDelta > 0) {
positiveDisplacement += displacementDelta;
} else if (displacementDelta < 0) {
negativeDisplacement += -displacementDelta; // Tomar o valor absoluto
}
float positiveMillimeters = positiveDisplacement * micrometersPerPulse / micrometersPerMillimeter;
float negativeMillimeters = negativeDisplacement * micrometersPerPulse / micrometersPerMillimeter;
float totalMillimeters = positiveMillimeters - negativeMillimeters;
// Atualizar o display durante a gravação
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Gravando......3 Fin");
lcd.setCursor(0, 1);
lcd.print("+ ");
lcd.print(positiveMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 2);
lcd.print("- ");
lcd.print(negativeMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 3);
lcd.print("Total: ");
lcd.print(totalMillimeters); // Exibir total em milímetros
lcd.print(" mm");
// Verificar se o pino RECORD_PIN está conectado ao GND para parar a gravação
if (digitalRead(RECORD_PIN) == LOW) {
delay(10); // Debounce
if (digitalRead(RECORD_PIN) == LOW) {
isRecording = false;
showResult = true; // Mostrar o resultado da gravação
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Gravacao Finalizada");
delay(1000); // Pausa para confirmar o término da gravação
lcd.clear();
displayUpdated = false; // Forçar atualização do display
}
}
delay(500); // Atraso para evitar sobrecarga do display
} else if (showResult) {
// Exibir o resultado final da gravação
float positiveMillimeters = positiveDisplacement * micrometersPerPulse / micrometersPerMillimeter;
float negativeMillimeters = negativeDisplacement * micrometersPerPulse / micrometersPerMillimeter;
float totalMillimeters = positiveMillimeters - negativeMillimeters;
// Atualizar o display para mostrar o resultado da gravação
if (!displayUpdated) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Medidas: 3grav 2menu");
lcd.setCursor(0, 1);
lcd.print("+: ");
lcd.print(positiveMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 2);
lcd.print("-: ");
lcd.print(negativeMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 3);
lcd.print("(=): ");
lcd.print(totalMillimeters); // Exibir total em milímetros
lcd.print(" mm");
displayUpdated = true; // Marcar o display como atualizado
}
// Verificar se o pino RECORD_PIN está conectado ao GND para reiniciar a gravação
if (digitalRead(RECORD_PIN) == LOW) {
delay(10); // Debounce
if (digitalRead(RECORD_PIN) == LOW) {
isRecording = true;
showResult = false; // Sair do modo de exibição de resultados e reiniciar a gravação
startPosition = encoder.read();
positiveDisplacement = 0;
negativeDisplacement = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Gravando...");
delay(500); // Pequeno atraso para iniciar o novo ciclo
displayUpdated = false; // Forçar atualização do display
}
}
}
}