#include <Arduino.h>
// Pines del motor paso a paso
const int motor_A = 23;
const int motor_B = 22;
const int motor_C = 19;
const int motor_D = 18;
// Pines de los sensores y botones
const int sensor_entrada = 4;
const int sensor_salida = 15;
const int seta_emergencia = 27;
// Pines de los LEDs
const int led_encendido = 13;
const int led_emergencia = 14;
const int led_motor = 25;
const int led_parpadeo_1 = 26;
const int led_parpadeo_2 = 5;
// Potenciómetro
const int pin_potenciometro = 34;
// Relé para desconectar el motor
const int rele_pin = 12;
// Variables de estado
volatile bool emergencia = false;
volatile bool boton_presionado = false;
volatile int productos_en_linea = 0;
// Configuración de los pasos del motor
#define NUMSEC 4
int tabla_pasos[NUMSEC][4] = {
{HIGH, LOW, LOW, LOW},
{LOW, HIGH, LOW, LOW},
{LOW, LOW, HIGH, LOW},
{LOW, LOW, LOW, HIGH}};
int paso_actual = 0;
// Temporizadores de hardware
hw_timer_t *timer_motor = NULL;
hw_timer_t *timer_leds = NULL;
hw_timer_t *timer_potenciometro = NULL;
hw_timer_t *timer_led_motor = NULL;
// Variables de voltaje y frecuencia
volatile float voltageReal = 0.0;
volatile float dacValue = 0.0;
volatile int frecMotor = 10000;
// Función para mover el motor al siguiente paso
void IRAM_ATTR mover_motor() {
if (!emergencia) {
digitalWrite(motor_A, tabla_pasos[paso_actual][0]);
digitalWrite(motor_B, tabla_pasos[paso_actual][1]);
digitalWrite(motor_C, tabla_pasos[paso_actual][2]);
digitalWrite(motor_D, tabla_pasos[paso_actual][3]);
paso_actual = (paso_actual + 1) % NUMSEC;
}
}
// ISR para manejar la emergencia
void IRAM_ATTR manejar_emergencia() {
if (digitalRead(seta_emergencia) == LOW) {
emergencia = !emergencia;
if (emergencia) {
digitalWrite(rele_pin, LOW); // Apagar motor
digitalWrite(led_emergencia, HIGH); // Encender LED de emergencia
} else {
digitalWrite(rele_pin, HIGH); // Encender motor
digitalWrite(led_emergencia, LOW);
productos_en_linea = 0; // Apagar LED de emergencia
}
}
}
// ISR para simular la llegada de un nuevo producto
void IRAM_ATTR llegada_producto() {
if (!emergencia) {
productos_en_linea++;
}
}
void IRAM_ATTR alternar_led_motor() {
if (!emergencia) {
digitalWrite(led_motor, !digitalRead(led_motor));
} else {
digitalWrite(led_motor, LOW); // Apagar el LED en caso de emergencia
}
}
// ISR para manejar la salida de productos
void IRAM_ATTR manejar_salida() {
if (!emergencia && productos_en_linea > 0) {
productos_en_linea--;
}
}
// Función para parpadear los LEDs
int frecLEDS=0;
void IRAM_ATTR parpadear_leds() {
if (!emergencia && productos_en_linea > 0) {
frecLEDS=1000000/productos_en_linea;
timerAlarm(timer_leds, frecLEDS , true, 0);
digitalWrite(led_parpadeo_1, !digitalRead(led_parpadeo_1));
digitalWrite(led_parpadeo_2, !digitalRead(led_parpadeo_2));
} else {
digitalWrite(led_parpadeo_1, LOW);
digitalWrite(led_parpadeo_2, LOW);
}
}
// ISR para leer el potenciómetro y ajustar la frecuencia
void IRAM_ATTR leer_potenciometro() {
int adcValue = analogRead(pin_potenciometro);
voltageReal = ((0.9806* adcValue + 0.1467)* 3.3) / 4095.0;
// Ajustar la frecuencia del motor
if (voltageReal < 0.825) frecMotor = 16000;
else if (voltageReal < 1.65) frecMotor = 12000;
else if (voltageReal < 2.475) frecMotor = 8000;
else frecMotor = 4000;
timerAlarm(timer_motor, frecMotor, true,0);
timerAlarm(timer_led_motor, frecMotor, true,0);
}
void setup() {
// Configuración de pines
pinMode(motor_A, OUTPUT);
pinMode(motor_B, OUTPUT);
pinMode(motor_C, OUTPUT);
pinMode(motor_D, OUTPUT);
pinMode(rele_pin, OUTPUT);
pinMode(sensor_entrada, INPUT_PULLUP);
pinMode(sensor_salida, INPUT_PULLUP);
pinMode(seta_emergencia, INPUT_PULLUP);
pinMode(led_encendido, OUTPUT);
pinMode(led_emergencia, OUTPUT);
pinMode(led_parpadeo_1, OUTPUT);
pinMode(led_parpadeo_2, OUTPUT);
pinMode(led_motor, OUTPUT);
digitalWrite(led_encendido, HIGH);
digitalWrite(rele_pin, HIGH);
attachInterrupt(digitalPinToInterrupt(sensor_entrada), llegada_producto, FALLING);
attachInterrupt(digitalPinToInterrupt(sensor_salida), manejar_salida, FALLING);
attachInterrupt(digitalPinToInterrupt(seta_emergencia), manejar_emergencia, FALLING);
Serial.begin(115200);
// Configuración de temporizadores
timer_motor = timerBegin(1000000);
timerAttachInterrupt(timer_motor, &mover_motor);
timerAlarm(timer_motor, frecMotor, true,0);
timer_led_motor = timerBegin(1000000); // Temporizador para LED motor
timerAttachInterrupt(timer_led_motor, &alternar_led_motor);
timerAlarm(timer_led_motor, 1/frecMotor, true,0);
timer_leds = timerBegin(1000000);
timerAttachInterrupt(timer_leds, &parpadear_leds);
timerAlarm(timer_leds, 500000, true,0);
timer_potenciometro = timerBegin(1000000);
timerAttachInterrupt(timer_potenciometro, &leer_potenciometro);
timerAlarm(timer_potenciometro, 1000, true,0);
}
void loop() {
// Mostrar información en la consola
Serial.printf("Productos en línea: %d\n", productos_en_linea);
Serial.printf("Voltaje: %.2f V\n", voltageReal);
Serial.printf("Frecuencia motor: %d\n", frecMotor);
delay(1000);
}