// Ejemplo de generación de una señal PWM - de 2 kHz y duty_cycle configurable entre 10 y 90 %
// https://wokwi.com/projects/411617808561130497
// the number of the LED pin
#define LED_PIN 23 // GPIO23
#define PULS_PIN 22 // GPIO pulsador - pin interrupcion
#define Timer0 0
// para controlar el acceso a variables globales compartidas entre los 2 cores!! - seccion critica
// portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
// setting PWM properties
const int freqPWM = 1000; // un ciclo equivale a 1/freqPWM sec => 1/1000 = 1 ms
const int resolucionPWM = 100; // el duty_cycle se controla con una resolución de 1 a 100
hw_timer_t * timer = NULL; // estructura de datos del timer
volatile int dutyCycle; // variable que va de 1 a 100, es el valor del duty_cycle
volatile int PWM; // valor 0 a 100 que controla la luminosidad
// ISR finTimer
void IRAM_ATTR finTimer() { // no incluir delay o while(condicion)
dutyCycle++;
if(dutyCycle>=100) dutyCycle=0; // va de 1 a 100
// set LED on / off
if(dutyCycle<PWM) digitalWrite(LED_PIN, HIGH); //encendido;
else digitalWrite(LED_PIN, LOW); //apagado;
}
void IRAM_ATTR ISR_pulsador(){
PWM+=10; // saltos de "iluminación" de 10 en 10 de 0 al 100%
if(PWM>100) PWM=0;
}
void setup(){
Serial.begin(115200);
Serial.printf("\n\n Ejemplo PWM - control luminosidad de un LED\n");
pinMode(LED_PIN, OUTPUT);
// esp32 a 80 MHz
timer = timerBegin(Timer0, 80, true); // prescaler entre [2, 65535]
timerAttachInterrupt(timer, &finTimer, true);
// con el prescaler a 80 -> el contador del Timer acumula microsegundos
// para tener la resolucion de 100 y una frecuencia PWM de 1000 Hz
// tiempo res = 1/(100*1000) = 10 microsegundos
timerAlarmWrite(timer, 1/(resolucionPWM*freqPWM), true); // se solicita ISR cada 10 microseg
timerAlarmEnable(timer);
PWM=50; // PWM al 50%
attachInterrupt(digitalPinToInterrupt(PULS_PIN), ISR_pulsador, FALLING);
// mode: LOW / HIGH / CHANGE / FALLING / RISING
}
void loop(){
Serial.printf("Valor PWM: %d \n", PWM);
delay(2000); // cada 2 segundos indica el valor configurado
}