//**************************************************
// Proyecto 1
// Electronica Digital 1
// Andrée Herratre Paredes 21368
//**************************************************
#include <Arduino.h>
#include "driver/ledc.h"
#define pinADC 34 // Pin utilizado para la lectura del ADC
#define BUTTON_PIN 35 // Pin utilizado para el botón
struct Button {
const uint8_t PIN;
volatile uint32_t numberKeyPresses;
volatile bool pressed;
};
Button btn1 = {BUTTON_PIN, 0, false};
unsigned long button_time = 0;
unsigned long last_button_time = 0;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
float adcRaw = 0.0; // Almacena la lectura cruda del ADC
float promedioLecturas = 0; // Almacena el valor promedio de las lecturas
int numLecturas = 10; // Número de muestras para el promedio
float bufferLecturas[10]; // Buffer para las lecturas del promedio móvil
int indexLecturas = 0; // Índice actual del buffer de lecturas
long mAvgSuma = 0; // Suma de lecturas para el promedio móvil
long adcFiltrado = 0; // Valor del ADC después del promedio móvil
double adcFiltradoEMA = adcRaw; // Valor del ADC después del filtro EMA
double alpha = 0.8; // Factor de suavizado (0-1)
// Parámetros de PWM para LEDs RGB
#define pwmChannel 0 // canal del servo
#define pwmChannelR 4 // canal led rojo
#define pwmChannelG 5 // canal led verde
#define pwmChannelB 6 //canal led azul
#define freqPWM_RGB 5000
#define resolution_PWM 8
#define pinLedR 19
#define pinLedG 18
#define pinLedB 5
#define pinServo 2
#define freqServo 50
#define resolucionServo 8
#define servoMin 6 // valor minimo de ciclo de trabajo
#define servoMax 30 // valor maximo de cilo de trabajo
#define COLD_TEMP 0
#define HOT_TEMP 38
// Declaracion de las funciones
void promedio(void);
void mediaMovil(void);
void filtroEMA(void);
float convertToTemperature(float adcValue);
void configurarPWM(void);
void actualizarLEDsRGB(float temperatura);
void handlerBTN1ISR();
int mapServoPosition (float temperatura);
void configurarServoPWM(void);
void handlerBTN1ISR() {
portENTER_CRITICAL_ISR(&mux);
button_time = xTaskGetTickCount();
if (button_time - last_button_time > 250) {
btn1.numberKeyPresses++;
btn1.pressed = true;
last_button_time = button_time;
}
portEXIT_CRITICAL_ISR(&mux);
}
void setup() {
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
pinMode(pinADC, INPUT);
pinMode(btn1.PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(btn1.PIN), handlerBTN1ISR, FALLING);
configurarPWM(); // Configurar PWM para LEDs RGB
configurarServoPWM();
}
void loop() {
adcRaw = analogRead(pinADC); // Leer el valor crudo del ADC
promedio(); // Realizar el cálculo del promedio
mediaMovil(); // Realizar el cálculo del promedio móvil
portENTER_CRITICAL_ISR(&mux);
if (btn1.pressed) { // Si el botón ha sido presionado
float voltage = convertToTemperature(adcRaw); // Convertir ADC a Celsius
Serial.print(" Temperature: ");
Serial.print(voltage);
Serial.println(" °C");
btn1.pressed = false;
// Llamar a la función para actualizar los LEDs RGB según la temperatura
actualizarLEDsRGB(voltage);
//Controlar servomotor basado en la temperatura
int mappedPosition = mapServoPosition(voltage);
ledcWrite(pwmChannel, mappedPosition);
btn1.pressed = false;
}
portEXIT_CRITICAL_ISR(&mux);
delay(100);
}
void promedio(void) {
int sumaLecturas = 0;
for (int k = 0; k < numLecturas; k++) {
sumaLecturas += analogRead(pinADC);
delay(1);
}
promedioLecturas = sumaLecturas / numLecturas;
}
void mediaMovil(void) {
adcRaw = analogReadMilliVolts(pinADC);
}
float convertToTemperature(float adcValue) {
float voltage =adcValue/10;
return voltage;
}
void configurarPWM(void) {
ledcSetup(pwmChannelR, freqPWM_RGB, resolution_PWM);
ledcSetup(pwmChannelG, freqPWM_RGB, resolution_PWM);
ledcSetup(pwmChannelB, freqPWM_RGB, resolution_PWM);
ledcAttachPin(pinLedR, pwmChannelR);
ledcAttachPin(pinLedG, pwmChannelG);
ledcAttachPin(pinLedB, pwmChannelB);
}
void actualizarLEDsRGB(float temperatura) {
int r = 0, g = 0, b = 0;
if (temperatura <= 37) {
// Color frío (azul)
b = 255;
} else if (temperatura > 37 && temperatura <= 37.5) {
// Verde encendido
g = 255;
} else if (temperatura > 37.5) {
// Rojo encendido
r = 255;
}
// Aplicar los valores de PWM a los pines correspondientes
ledcWrite(pwmChannelR, r);
ledcWrite(pwmChannelG, g);
ledcWrite(pwmChannelB, b);
}
void configurarServoPWM(void){
ledcSetup(pwmChannel, freqServo, resolucionServo);
ledcAttachPin(pinServo, pwmChannel);
}
int mapServoPosition(float temperatura){
if (temperatura < 37.0)
{
return map(45, 0, 180, servoMin, servoMax);
}
else if (temperatura > 37.0 && temperatura <= 37.5)
{
return map(90, 0, 180, servoMin, servoMax);
}
else
{
return map(135, 0, 180, servoMin, servoMax);
}
}