#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Endereço do display LCD I2C
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 20
#define LCD_ROWS 4
// Cria uma instância do display LCD
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
// Pinos do motor
const int Pin1 = 13;
const int Pin2 = 12;
const int Pin3 = 11;
const int Pin4 = 10;
// Pinos do modo e pausa
const int modoPin1 = A1;
const int modoPin2 = A2;
const int modoPin3 = A3;
const int modoPin4 = 8;
const int pausaPin = 7;
const int botaoDirecaoPin = A0;
const int direcaoPin = 9;
const int pinoDisplay = 4; // Pino para controlar o display LCD
// Pinos do encoder
const int encoderPinA = 2;
const int encoderPinB = 3;
const int pulso = 180; // Número de pulsos para o motor
const int intervaloPulso = 2; // Tempo entre os pulsos em milissegundos
const unsigned long tempoBaseBase = 60000; // Valor base do tempo em milissegundos (60 segundos)
unsigned long tempoBase = tempoBaseBase; // Tempo entre ciclos em milissegundos
unsigned long tempoEspera = tempoBase - (pulso * intervaloPulso);
unsigned long tempoUltimoCiclo1 = 0;
unsigned long tempoUltimoCiclo2 = 0;
unsigned long tempoUltimoCiclo3 = 0;
unsigned long tempoUltimoCiclo4 = 0;
unsigned long tempoUltimoPulso1 = 0;
unsigned long tempoUltimoPulso2 = 0;
unsigned long tempoUltimoPulso3 = 0;
unsigned long tempoUltimoPulso4 = 0;
unsigned long inicioCronometro = 0;
bool cronometroIniciado = false;
int contagemPulso1 = 0;
int contagemPulso2 = 0;
int contagemPulso3 = 0;
int contagemPulso4 = 0;
bool pausa = false;
bool ultimaPausa = false;
volatile int encoderPos = 0;
int lastEncoderPos = 0;
void setup() {
pinMode(Pin1, OUTPUT);
pinMode(modoPin1, INPUT_PULLUP);
pinMode(Pin2, OUTPUT);
pinMode(modoPin2, INPUT_PULLUP);
pinMode(Pin3, OUTPUT);
pinMode(modoPin3, INPUT_PULLUP);
pinMode(Pin4, OUTPUT);
pinMode(modoPin4, INPUT_PULLUP);
pinMode(pausaPin, INPUT_PULLUP);
pinMode(botaoDirecaoPin, INPUT_PULLUP);
pinMode(direcaoPin, OUTPUT);
pinMode(pinoDisplay, OUTPUT); // Pino para controlar o display LCD
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
attachInterrupt(digitalPinToInterrupt(encoderPinA), readEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPinB), readEncoder, CHANGE);
lcd.begin(LCD_COLUMNS, LCD_ROWS);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Iniciando...");
digitalWrite(direcaoPin, LOW); // Inicializa a direção como LOW
digitalWrite(pinoDisplay, LOW); // Desliga o display LCD
}
void loop() {
// Controle do display LCD
bool estadoAtualPausa = (digitalRead(pausaPin) == HIGH);
if (estadoAtualPausa) {
digitalWrite(pinoDisplay, HIGH); // Liga o display LCD
} else {
digitalWrite(pinoDisplay, LOW); // Desliga o display LCD
lcd.clear(); // Limpa o display LCD
}
if (pausa && !estadoAtualPausa) {
tempoUltimoCiclo1 = millis();
tempoUltimoCiclo2 = millis();
tempoUltimoCiclo3 = millis();
tempoUltimoCiclo4 = millis();
contagemPulso1 = 0;
contagemPulso2 = 0;
contagemPulso3 = 0;
contagemPulso4 = 0;
cronometroIniciado = false;
}
pausa = estadoAtualPausa;
ultimaPausa = estadoAtualPausa;
if (pausa) {
if (digitalRead(modoPin1) == LOW) {
comtinuo(Pin1);
} else {
digitalWrite(Pin1, LOW);
}
if (digitalRead(modoPin2) == LOW) {
comtinuo(Pin2);
} else {
digitalWrite(Pin2, LOW);
}
if (digitalRead(modoPin3) == LOW) {
comtinuo(Pin3);
} else {
digitalWrite(Pin3, LOW);
}
if (digitalRead(modoPin4) == LOW) {
comtinuo(Pin4);
} else {
digitalWrite(Pin4, LOW);
}
// Atualiza o tempo base com base no encoder
if (encoderPos != lastEncoderPos) {
long variacaoTempo = (encoderPos - lastEncoderPos) * 100; // Ajuste a unidade conforme necessário
tempoBase = tempoBaseBase + variacaoTempo;
tempoBase = constrain(tempoBase, 50000, 70000); // Tempo base entre 50 e 70 segundos
tempoEspera = tempoBase - (pulso * intervaloPulso);
lastEncoderPos = encoderPos;
}
} else {
unsigned long agora = millis();
if (!cronometroIniciado) {
inicioCronometro = agora;
cronometroIniciado = true;
}
if (agora - tempoUltimoCiclo1 >= tempoEspera) {
cicloMotor(Pin1, contagemPulso1, tempoUltimoPulso1);
if (contagemPulso1 >= pulso) {
contagemPulso1 = 0;
tempoUltimoCiclo1 = agora;
}
}
if (agora - tempoUltimoCiclo2 >= tempoEspera) {
cicloMotor(Pin2, contagemPulso2, tempoUltimoPulso2);
if (contagemPulso2 >= pulso) {
contagemPulso2 = 0;
tempoUltimoCiclo2 = agora;
}
}
if (agora - tempoUltimoCiclo3 >= tempoEspera) {
cicloMotor(Pin3, contagemPulso3, tempoUltimoPulso3);
if (contagemPulso3 >= pulso) {
contagemPulso3 = 0;
tempoUltimoCiclo3 = agora;
}
}
if (agora - tempoUltimoCiclo4 >= tempoEspera) {
cicloMotor(Pin4, contagemPulso4, tempoUltimoPulso4);
if (contagemPulso4 >= pulso) {
contagemPulso4 = 0;
tempoUltimoCiclo4 = agora;
}
}
}
// Atualiza o display LCD com o tempo base e o cronômetro
if (digitalRead(pinoDisplay) == HIGH) {
unsigned long tempoDecorrido = millis() - inicioCronometro;
unsigned long horas = (tempoDecorrido / 3600000); // 1 hora = 3600000 ms
unsigned long minutos = (tempoDecorrido % 3600000) / 60000; // Minutos restantes
unsigned long segundos = (tempoDecorrido % 60000) / 1000; // Segundos restantes
lcd.setCursor(0, 0);
lcd.print("Tempo base: ");
lcd.print(tempoBase / 1000.0, 4); // Mostra o tempo base em segundos com 4 casas decimais
lcd.print("s");
lcd.setCursor(0, 1);
lcd.print("T/P=(");
lcd.print("P");
lcd.print(pulso);
lcd.print("*I");
lcd.print (intervaloPulso);
lcd.print(")T");
lcd.print (tempoBase);
lcd.setCursor(0, 2);
lcd.print("Intervalo = ");
lcd.print(tempoEspera);
lcd.setCursor(0, 3);
lcd.print("Cronometro");
lcd.setCursor(11, 3);
lcd.print(horas);
lcd.print("h ");
lcd.print(minutos);
lcd.print("m ");
lcd.print(segundos);
lcd.print("s");
delay(100); // Pequeno atraso para suavizar a atualização do LCD
}
}
void cicloMotor(int pin, int& contagemPulso, unsigned long& tempoUltimoPulso) {
unsigned long agora = millis();
if (agora - tempoUltimoPulso >= intervaloPulso && contagemPulso < pulso) {
digitalWrite(pin, HIGH);
delayMicroseconds(100);
digitalWrite(pin, LOW);
tempoUltimoPulso = agora;
contagemPulso++;
}
}
void comtinuo(int pin) {
digitalWrite(pin, HIGH);
delay(intervaloPulso);
digitalWrite(pin, LOW);
delay(intervaloPulso);
}
void readEncoder() {
int stateA = digitalRead(encoderPinA);
int stateB = digitalRead(encoderPinB);
if (stateA == stateB) {
encoderPos++;
} else {
encoderPos--;
}
}