Potenciómetro para parpadeo LED a alta frecuencia

Hola a todos,

Estoy realizando un proyecto el cual necesito variar la frecuencia de parpadeo de un LED con un potenciometro desde 0 hasta unos 20kHz aproximadamente. El caso es que he visto algún ejemplo por internet pero que no me es válido ya que trabajan con frecuencias muy pequeñas.

Adjunto el código que he encontrado:

int pinPot = A0;
int pinLed = 9;
int valorPot;
int parpadeo;
void setup() {
pinMode(pinLed, OUTPUT);
}
void loop() {
valorPot = analogRead(pinPot);
parpadeo = map(valorPot, 0, 1023, 0, 500);

digitalWrite(pinLed, HIGH);
delay(parpadeo);
digitalWrite(pinLed, LOW);
delay(parpadeo);
}

El caso es que investigando he llegado a la conclusión que mediante unas interrupciones podría solucionar esto quitando la parte del código donde aparece el “delay”, pero desconozco como funcionan las interrupciones ya que nunca he trabajado con ellas…

A ver si alguien me podría echar una mano, os lo agradecería mucho!

Saludos.

Hola @ijavimartinez bienvenido al foro Arduino.
Te he enviado un privado con instrucciones para que edites tu post a fin de que uses etiquetas con tu código y que la imagen adjunta sea visible.

Respecto del código, eso que has puesto es un simple Copy & Paste de algún sitio web porque ni por asomo lograrás 20Khz con delay y además jamás puedes poner 0 en un delay de modo que como mínimo debieras modificar ese map y usar delayMicroseconds() en lugar de delay.

Con delayMicroseconds() podras mejorar las cosas.

Veamos 20000 Hz son 50 useg y para tu caso debieras usar la mitad para lograrlo.
Entonces 25 debería ser el valor máximo y el mínimo.... según esto

delayMicroseconds()
Descripción
Hace una pausa en el programa porla cantidad de tiempo (en microsegundos) especificado como parámetro. Hay mil microsegundos en una milésima de segundo, y un millón de microsegundos en un segundo.

En la actualidad, el valor más grande que producirá un retardo preciso es 16383. Esto podría cambiar con la futuras versiones de Arduino. Para retardos de más de unos pocos miles de microsegundos, debe usarse delay() en su lugar.

De modo que 16383 useg te daran x 2 ya que son dos semiperíodos 37666 seg y como la frecuencia es la inversa del período entonces

f = 1/T = 1/37666 useg = aprox 30 Hz

Quiere decir que con delayMicrosegundos() logras algo entre 20Khz y 30 Hz que para comenzar estará bien supongo.

El problema es el potenciometro y como pasar de 1024 pasos a 16383 pasos, algo imposible.
Tendrias que tener dos potenciometros, uno que haga un ajuste grueso y el otro el fino o usar dos botones pulsadores e incrementar/decramentar para conseguir lo que quieres.

Tu código tal como esta sería algo asi

int pinPot = A0;
int pinLed = 9;
int valorPot;
int parpadeo;
void setup() {
pinMode(pinLed, OUTPUT);
}
void loop() {
   valorPot = analogRead(pinPot);
   parpadeo = map(valorPot, 0, 1023, 0, 16383); // esto esta mal porque no puedes pasar de 1024 a 16383

   digitalWrite(pinLed, HIGH);
   delayMicroseconds(parpadeo);
   digitalWrite(pinLed, LOW);
   delayMicroseconds(parpadeo);
}

Y otro gran problema es que no pueden estar las lineas de analogRead y map en la misma secuencia de los digitalWrite porque alteras los cálculos anteriores.

Solo analogRead insume muchos useg para que el ADC convierta de modo que todo lo que te puse antes funciona solo para esta secuencia

   digitalWrite(pinLed, HIGH);
   delayMicroseconds(parpadeo);
   digitalWrite(pinLed, LOW);
   delayMicroseconds(parpadeo);

Tendrias que tener alguna forma de poder llamar a algo que permite ajustar y olvidarnos de la generación.

Todo esto se resuelve usando TIMERS que fueron pensados justamente para tareas como esta pero si tienes dudas con estas cosas, ir a TIMERs no es para principiantes.

Claro que puedes estudiarlo, usa Google: Arduino TIMERS

lo que no entiendo es para que quieres hacer parpadear un led a 20kHz, desde como los 40hz ya no se nota la variación, de cualquier forma sin miedo a los Timers!