#include <TM1637.h> // Librería para controlar el display TM1637
// Definición de pines
#define ENCODER_CLK 3 // Pin A del encoder (CLK)
#define ENCODER_DT 4 // Pin B del encoder (DT)
#define ENCODER_SW 5 // Pin del pulsador
#define CLK_PIN 6 // Pin de reloj para el display
#define DIO_PIN 7 // Pin de datos para el display
TM1637 tm(CLK_PIN, DIO_PIN); // Inicialización del display TM1637
const int pinPWMOut1 = 13; // Pin para señal PWM
const int pinOut1 = 12; // Pin de habilitación
const int pinOut2 = 11; // Pin de dirección
const int pinOut3 = 2; // Pin de LED indicador
const int pinInput1 = 9; // Pin de dirección 1
const int pinInput5 = 8; // Pin de dirección 2
const int pinInput2 = 10; // Pin de habilitación
const int pinInput3 = 0; // Pin de encendido
const int pinInput4 = 1; // Pin de velocidad
int pinPWMnew; // Valor de la frecuencia PWM
int counter = 1; // Contador para el encoder
bool stopLoop = false; // Variable de control para detener el ciclo
void setup() {
Serial.begin(9600);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
tm.init(); // Inicializa el display
tm.set(BRIGHT_TYPICAL); // Ajusta el brillo
pinMode(pinPWMOut1, OUTPUT); // Configura los pines como salida
pinMode(pinOut1, OUTPUT);
pinMode(pinOut2, OUTPUT);
pinMode(pinInput1, INPUT_PULLUP);
pinMode(pinInput5, INPUT_PULLUP);
pinMode(pinInput2, INPUT_PULLUP);
pinMode(pinInput3, INPUT_PULLUP);
pinMode(pinInput4, INPUT_PULLUP);
pinMode(pinOut3, OUTPUT); // LED indicador
digitalWrite(pinOut3, HIGH);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING); // Interrupción para el encoder
}
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
counter += (dtValue == HIGH) ? 1 : -1;
counter = constrain(counter, 1, 100); // Limita el valor del contador entre 1 y 300
}
int getCounter() {
int result;
noInterrupts(); // Deshabilita interrupciones temporalmente
result = counter;
interrupts(); // Vuelve a habilitar interrupciones
return result;
}
void resetCounter() {
noInterrupts();
counter = 1;
interrupts();
}
void loop() {
// Manejo del botón de encendido con debounce usando millis()
if (digitalRead(pinInput3) == LOW) {
stopLoop = !stopLoop; // Cambia el estado de stopLoop
digitalWrite(pinOut3, stopLoop ? LOW : HIGH); // Enciende o apaga el LED indicador
delay(1000); // Actualiza el tiempo del último evento
}
// Mostrar el contador en el display TM1637
int displayValue = getCounter();
tm.display(0, (displayValue / 1000) % 10);
tm.display(1, (displayValue / 100) % 10);
tm.display(2, (displayValue / 10) % 10);
tm.display(3, displayValue % 10);
// Mapeo de contador a PWM si no es cero
pinPWMnew = map(displayValue, 100, 1, 1, 300); // Mapea el contador de 1 a 300 a un rango de PWM
Serial.println(stopLoop); // Si deseas ver el valor de stopLoop
int inputState1 = digitalRead(pinInput1); // Dirección 1
int inputState3 = digitalRead(pinInput5); // Dirección 2
int inputState2 = digitalRead(pinInput2); // Enable
// Si el pulsador de velocidad está presionado, el PWM se pone a 0
if (digitalRead(pinInput4) == LOW) {
pinPWMnew = 0; // Resetear PWM si el pulsador está presionado
}
// Lógica de control de dirección y velocidad
if (inputState1 == HIGH) {
if (inputState2 == LOW) {
Dir_R(pinPWMnew);
} else if (inputState3 == LOW) {
Dir_L(pinPWMnew);
} else {
stopMotor();
}
} else {
stopMotor();
}
// Resetear el contador si se presiona el pulsador del encoder
if (digitalRead(ENCODER_SW) == LOW) {
resetCounter();
}
}
void stopMotor() {
digitalWrite(pinOut1, LOW);
digitalWrite(pinOut2, LOW);
digitalWrite(pinPWMOut1, LOW); // Detener PWM
stopLoop = false;
digitalWrite(pinOut3, HIGH);
}
void Dir_R(int pwm) {
digitalWrite(pinOut1, LOW); // Dirección hacia adelante
digitalWrite(pinOut2, LOW);
generatePWM(pwm);
}
void Dir_L(int pwm) {
digitalWrite(pinOut1, LOW); // Dirección hacia atrás
digitalWrite(pinOut2, HIGH);
generatePWM(pwm);
}
void generatePWM(int pwm) {
for (int i = 0; i < 1000; i++) {
digitalWrite(pinPWMOut1, HIGH);
delayMicroseconds(pwm);
digitalWrite(pinPWMOut1, LOW);
delayMicroseconds(pwm);
if (!stopLoop) break; // Detener si el sistema está apagado
}
}