#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);
const int Pin1 = 13;
const int Pin2 = 12;
const int Pin3 = 11;
const int Pin4 = 10;
const int modoPin1 = A1;
const int modoPin2 = A2;
const int modoPin3 = A3;
const int modoPin4 = 8;
const int pausaPin = 7;
const int botaoDirecaoPin = A0; // Pino do botão de direção
const int direcaoPin = 9; // Pino para indicar a direção
const int potenciometroPin = A4; // Pino do potenciômetro
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;
int contagemPulso1 = 0;
int contagemPulso2 = 0;
int contagemPulso3 = 0;
int contagemPulso4 = 0;
bool pausa = false;
bool ultimaPausa = false;
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); // Configura o botão de direção com pull-up interno
pinMode(direcaoPin, OUTPUT); // Configura o pino de direção como saída
digitalWrite(direcaoPin, LOW); // Inicializa a direção como LOW
// Inicializa o display LCD com os parâmetros corretos
lcd.begin(LCD_COLUMNS, LCD_ROWS);
lcd.backlight(); // Liga a luz de fundo do LCD
lcd.setCursor(0, 0); // Define o cursor na posição (0,0)
lcd.print("Atrasa/adianta");
}
void loop() {
// Leitura do valor do potenciômetro
int valorPotenciometro = analogRead(potenciometroPin);
// Mapeia o valor do potenciômetro para a variação do tempo base entre -1000 ms e +1000 ms
long variacaoTempo = map(valorPotenciometro, 0, 1023, -1000, 1000);
// Ajusta o tempo base em torno do valor base de 60000 ms
tempoBase = tempoBaseBase + variacaoTempo;
// Garante que o tempo base esteja dentro de um intervalo razoável
tempoBase = constrain(tempoBase, 50000, 70000); // Tempo base entre 50 e 70 segundos
// Calcula o tempo de espera com base no novo tempo base e os pulsos
tempoEspera = tempoBase - (pulso * intervaloPulso);
// Controle da direção com base no botão de direção (botão no A0)
if (digitalRead(botaoDirecaoPin) == LOW) {
// Se o botão estiver pressionado (nível baixo no A0)
digitalWrite(direcaoPin, LOW); // Define o pino 9 como LOW
} else {
// Se o botão estiver solto (nível alto no A0)
digitalWrite(direcaoPin, HIGH); // Define o pino 9 como HIGH
}
// Verifica se deve pausar
bool estadoAtualPausa = (digitalRead(pausaPin) == HIGH);
if (pausa && !estadoAtualPausa) {
// Reseta os ciclos e as contagens de pulso
tempoUltimoCiclo1 = millis();
tempoUltimoCiclo2 = millis();
tempoUltimoCiclo3 = millis();
tempoUltimoCiclo4 = millis();
contagemPulso1 = 0;
contagemPulso2 = 0;
contagemPulso3 = 0;
contagemPulso4 = 0;
}
pausa = estadoAtualPausa;
ultimaPausa = estadoAtualPausa;
if (pausa) {
// Controle manual durante a 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);
}
} else {
// Controle automático quando não está em pausa
unsigned long agora = millis();
// Motor 1
if (agora - tempoUltimoCiclo1 >= tempoEspera) {
cicloMotor(Pin1, contagemPulso1, tempoUltimoPulso1);
if (contagemPulso1 >= pulso) {
contagemPulso1 = 0;
tempoUltimoCiclo1 = agora;
}
}
// Motor 2
if (agora - tempoUltimoCiclo2 >= tempoEspera) {
cicloMotor(Pin2, contagemPulso2, tempoUltimoPulso2);
if (contagemPulso2 >= pulso) {
contagemPulso2 = 0;
tempoUltimoCiclo2 = agora;
}
}
// Motor 3
if (agora - tempoUltimoCiclo3 >= tempoEspera) {
cicloMotor(Pin3, contagemPulso3, tempoUltimoPulso3);
if (contagemPulso3 >= pulso) {
contagemPulso3 = 0;
tempoUltimoCiclo3 = agora;
}
}
// Motor 4
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 intervalo com 4 casas decimais
lcd.setCursor(0, 1);
lcd.print("intervalo:");
lcd.setCursor(0, 2);
lcd.print((float)tempoEspera / 1000, 4); // Mostra o tempo em segundos com 4 casas decimais
lcd.print(" s");
lcd.setCursor(0, 3);
lcd.print("T/ciclo ");
lcd.print((float)tempoBase / 1000, 4); // Mostra o tempo base em segundos com 4 casas decimais
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);
}