#include <TM1637TinyDisplay.h>
#include <Preferences.h>
#define CLK 18
#define DIO 19
#define SENSOR_START 2
#define SENSOR_STOP 0
#define BOTAO_PRETO 5
#define BOTAO_VERDE 15
#define STEP_PIN 12
#define ENABLE_PIN 27
#define PIN_SIRENE 25
TM1637TinyDisplay display(CLK, DIO);
Preferences prefs;
unsigned int contador = 0;
unsigned long tempoInicio = 0;
bool motorAtivo = false;
bool esperandoStop = false;
bool jaContou = false;
bool ultimoEstadoStart = HIGH;
bool ultimoEstadoStop = HIGH;
bool alarmeAtivo = false;
enum MotivoAlarme { NENHUM, ERRO_SELO };
MotivoAlarme motivoAlarme = NENHUM;
// Modo F
bool modoF = false;
int funcaoAtual = 1;
unsigned long tempoUltimaInteracao = 0;
bool ajustandoValor = false;
// Valores configuráveis
unsigned int tempoExtraParada = 0; // F01
unsigned int velocidadeMotor = 5000; // F02
void salvarConfiguracoes() {
prefs.putUInt("tempoExtra", tempoExtraParada);
prefs.putUInt("velocidade", velocidadeMotor);
}
void carregarConfiguracoes() {
tempoExtraParada = prefs.getUInt("tempoExtra", 0);
velocidadeMotor = prefs.getUInt("velocidade", 5000);
}
void exibirFuncao() {
char buf[5];
snprintf(buf, sizeof(buf), "F%d", funcaoAtual);
display.showString(buf);
}
void exibirValor(unsigned int valor) {
display.showNumberDec(valor, false);
}
void setup() {
pinMode(SENSOR_START, INPUT_PULLUP);
pinMode(SENSOR_STOP, INPUT_PULLUP);
pinMode(BOTAO_PRETO, INPUT_PULLUP);
pinMode(BOTAO_VERDE, INPUT_PULLUP);
pinMode(STEP_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
digitalWrite(ENABLE_PIN, HIGH);
pinMode(PIN_SIRENE, OUTPUT);
digitalWrite(PIN_SIRENE, LOW);
display.setBrightness(7);
prefs.begin("cnt", false);
contador = prefs.getUInt("valor", 0);
carregarConfiguracoes();
display.showNumberDec(contador, true);
}
void loop() {
static unsigned long tempoPressionadoPreto = 0;
static unsigned long tempoPressionadoVerde = 0;
static unsigned long ultimoTempoVerde = 0;
static unsigned long ultimoTempoPreto = 0;
static bool ultimoEstadoBotaoPreto = HIGH;
static bool ultimoEstadoBotaoVerde = HIGH;
// Zerar contador com botão verde pressionado por 7s
if (digitalRead(BOTAO_VERDE) == LOW) {
if (tempoPressionadoVerde == 0) tempoPressionadoVerde = millis();
if ((millis() - tempoPressionadoVerde >= 7000)) {
contador = 0;
prefs.putUInt("valor", contador);
display.showNumberDec(contador, true);
delay(500);
while (digitalRead(BOTAO_VERDE) == LOW) delay(10);
tempoPressionadoVerde = 0;
}
} else {
tempoPressionadoVerde = 0;
}
// Entrar no modo F com botão preto pressionado por 5s
if (digitalRead(BOTAO_PRETO) == LOW) {
if (tempoPressionadoPreto == 0) tempoPressionadoPreto = millis();
if (!modoF && (millis() - tempoPressionadoPreto >= 5000)) {
modoF = true;
funcaoAtual = 1;
ajustandoValor = false;
tempoUltimaInteracao = millis();
exibirFuncao();
}
} else {
tempoPressionadoPreto = 0;
}
// -------------------- MODO F --------------------
if (modoF) {
if (ajustandoValor && (millis() - tempoUltimaInteracao > 4000)) {
salvarConfiguracoes();
ajustandoValor = false;
exibirFuncao();
tempoUltimaInteracao = millis();
} else if (!ajustandoValor && (millis() - tempoUltimaInteracao > 4000)) {
modoF = false;
display.showNumberDec(contador, true);
return;
}
// VERDE: Aumenta valor ou troca função
bool estadoVerde = digitalRead(BOTAO_VERDE);
if (estadoVerde == LOW && ultimoEstadoBotaoVerde == HIGH) {
tempoUltimaInteracao = millis();
if (!ajustandoValor) {
funcaoAtual++;
if (funcaoAtual > 2) funcaoAtual = 1;
exibirFuncao();
} else {
if (funcaoAtual == 1 && tempoExtraParada < 3000) tempoExtraParada++;
else if (funcaoAtual == 2 && velocidadeMotor < 10000) velocidadeMotor += 100;
exibirValor(funcaoAtual == 1 ? tempoExtraParada : velocidadeMotor);
}
ultimoTempoVerde = millis();
}
ultimoEstadoBotaoVerde = estadoVerde;
// PRETO: Diminui valor ou entra em ajuste
bool estadoPreto = digitalRead(BOTAO_PRETO);
if (estadoPreto == LOW && ultimoEstadoBotaoPreto == HIGH) {
tempoUltimaInteracao = millis();
if (!ajustandoValor) {
ajustandoValor = true;
exibirValor(funcaoAtual == 1 ? tempoExtraParada : velocidadeMotor);
} else {
if (funcaoAtual == 1 && tempoExtraParada > 0) tempoExtraParada--;
else if (funcaoAtual == 2 && velocidadeMotor > 100) velocidadeMotor -= 100;
exibirValor(funcaoAtual == 1 ? tempoExtraParada : velocidadeMotor);
}
ultimoTempoPreto = millis();
}
ultimoEstadoBotaoPreto = estadoPreto;
// Repetição contínua para VERDE
if (estadoVerde == LOW && ajustandoValor && (millis() - ultimoTempoVerde > 700)) {
if (millis() % 100 < 10) {
tempoUltimaInteracao = millis();
if (funcaoAtual == 1 && tempoExtraParada < 3000) tempoExtraParada++;
else if (funcaoAtual == 2 && velocidadeMotor < 10000) velocidadeMotor += 100;
exibirValor(funcaoAtual == 1 ? tempoExtraParada : velocidadeMotor);
}
}
// Repetição contínua para PRETO
if (estadoPreto == LOW && ajustandoValor && (millis() - ultimoTempoPreto > 700)) {
if (millis() % 100 < 10) {
tempoUltimaInteracao = millis();
if (funcaoAtual == 1 && tempoExtraParada > 0) tempoExtraParada--;
else if (funcaoAtual == 2 && velocidadeMotor > 100) velocidadeMotor -= 100;
exibirValor(funcaoAtual == 1 ? tempoExtraParada : velocidadeMotor);
}
}
return;
}
// ------------------ FUNCIONAMENTO NORMAL ------------------
bool estadoAtualStart = digitalRead(SENSOR_START);
bool estadoAtualStop = digitalRead(SENSOR_STOP);
if (alarmeAtivo && motivoAlarme == ERRO_SELO) {
display.showString("SELO");
digitalWrite(PIN_SIRENE, HIGH);
if (digitalRead(BOTAO_VERDE) == LOW) {
alarmeAtivo = false;
motivoAlarme = NENHUM;
digitalWrite(PIN_SIRENE, LOW);
display.showNumberDec(contador, true);
delay(500);
}
return;
}
if (ultimoEstadoStart == HIGH && estadoAtualStart == LOW && !motorAtivo) {
motorAtivo = true;
esperandoStop = true;
jaContou = false;
tempoInicio = millis();
digitalWrite(ENABLE_PIN, LOW);
}
if (motorAtivo) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(velocidadeMotor);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(velocidadeMotor);
if (ultimoEstadoStop == HIGH && estadoAtualStop == LOW && esperandoStop && !jaContou) {
delay(tempoExtraParada);
contador = (contador + 1) % 10000;
prefs.putUInt("valor", contador);
if (!alarmeAtivo) display.showNumberDec(contador, true);
jaContou = true;
esperandoStop = false;
motorAtivo = false;
digitalWrite(ENABLE_PIN, HIGH);
}
if (millis() - tempoInicio >= 2000 && esperandoStop && !jaContou) {
esperandoStop = false;
jaContou = true;
motorAtivo = false;
digitalWrite(ENABLE_PIN, HIGH);
alarmeAtivo = true;
motivoAlarme = ERRO_SELO;
}
}
ultimoEstadoStart = estadoAtualStart;
ultimoEstadoStop = estadoAtualStop;
}