/*
  Ejercicio 2 examen, Genera un trapecio con PWM.
*/

// Librerías.

#include <Arduino.h>                                // Arduino.
#include <iostream>                                 // Declara los objetos que controlan la lectura y escritura en los flujos estándar.

// Defines.

// Variables globales.
volatile uint8_t counter = 0;                       // Variable numérica sin signo que cuenta el tiempo entre la subida del trapecio y la bajada.

const int PWMChannel = 0;                           // Canal PWM, puede ser de 0 a 15. puede haber 16 PWM distintos en el esp32.
const int PWMPin = 0;                               // Pin GPIO 0 al que está conectado el dispositivo.
const int frequency = 5000;                         // Frecuencia en Hz. >1000Hz evita parpadeos.
const int resolution = 8;                           // Resolución en bits (de 1 a 15), se pone 8 porque 2^8=256 (0-255).

// set up.
void setup()
{
  Serial.begin(115200);                             // Comunicación con el puerto serie a 115200 baudios.

  // Configuración del PWM.

  // El periférico LEDC (LED Control) es muy eficiente y permite generar señales PWM de alta resolución y frecuencia ajustable.
  ledcSetup(PWMChannel, frequency, resolution);
  ledcAttachPin(PWMPin, PWMChannel);                // Asocia el pin al canal.
}

// Loop.
void loop()
{
  if (counter == 0)                                   // Si el contador es 0 (Inicio).
  {
    // Incrementar el ciclo de trabajo gradualmente para aumentar la intensidad del LED.
    for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++)
    {
      ledcWrite(PWMChannel, dutyCycle);               // Enciende el LED con la atenuación que hay en dutycycle.
      delay(10);                                      // Espera 10ms para el cambio de brillo.
    }
  }

  counter++;                                          // Se actualiza el contador.

  if (counter > 3000)                                  // Si el contador es mayor que 300 (10ms*300=3s).
  {
    // Disminuir el ciclo de trabajo gradualmente para reducir la intensidad del LED
    for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--)
    {
      ledcWrite(PWMChannel, dutyCycle);               // Enciende el LED  con la atenuación que hay en dutycicle.
      delay(10);
    }

    counter = 0;                                      // Se reinicia el contador.
  }

  delay(10);                                          // Espera 10ms para que no se crashee el programa.
}