#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;
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, 0);
lcd.print("Contador zerado!");
delay(1000); // Mostrar por 1 segundo antes de voltar ao menu
}
}
// 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();
if (inMenu) {
lcd.setCursor(0, 0);
lcd.print("Menu Principal");
delay(1000); // Aguardar 1 segundo antes de permitir nova troca
} else {
lcd.setCursor(0, 0);
lcd.print("Modo de Gravacao");
delay(1000); // Aguardar 1 segundo antes de permitir nova troca
}
} else {
showResult = false; // Sair do modo de exibição de resultados
}
}
}
if (inMenu) {
// 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;
// Mostrar valores no LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Medidas ");
lcd.setCursor(0, 1);
lcd.print("Micro: ");
lcd.print(micrometers);
lcd.print(" u");
lcd.setCursor(0, 2);
lcd.print("Mili : ");
lcd.print(millimeters);
lcd.print(" mm");
lcd.setCursor(0, 3);
lcd.print("Cent : ");
lcd.print(centimeters);
lcd.print(" cm");
oldPosition = newPosition;
delay(100); // Atraso para melhor visualização
} else if (!isRecording && !showResult) {
// Modo de gravação esperando o início
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pressione A3 para");
lcd.setCursor(0, 1);
lcd.print("iniciar gravacao");
// 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);
}
}
} 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;
float totalCentimeters = totalMillimeters / 10.0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Gravando...");
lcd.setCursor(0, 1);
lcd.print("Dir: ");
lcd.print(positiveMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 2);
lcd.print("Esq: ");
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
}
}
delay(100); // 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;
float totalCentimeters = totalMillimeters / 10.0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Fim Gravacao");
lcd.setCursor(0, 1);
lcd.print("Dir: ");
lcd.print(positiveMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 2);
lcd.print("Esq: ");
lcd.print(negativeMillimeters);
lcd.print(" mm");
lcd.setCursor(0, 3);
lcd.print("Total: ");
lcd.print(totalMillimeters); // Exibir total em milímetros
lcd.print(" mm");
delay(100); // Atualização rápida enquanto exibe o resultado
// Continua exibindo os resultados até que o botão MODE_PIN seja pressionado
}
}