Buenos dias, estoy haciendo un trabajo con la libreria timerone. Mi inconveniente viene dado con que quiero variar el periodo de disparo a partir de una entrada analogica y nose como hacerlo.
#include <TimerOne.h>
const int T1Pin = 11;
const int T2Pin = 12;
int n=0;
int T1 = LOW;
int T2 = HIGH;
int tim;
int InpAnalog;
void setup(void)
{
pinMode(T1Pin, OUTPUT);
pinMode(T2Pin, OUTPUT);
Timer1.initialize(40000); // Dispara cada 1 ms
Timer1.attachInterrupt(ISR_Blink); // Activa la interrupcion y la asocia a ISR_Blink
interrupts(); // Autoriza las interrupciones
}
void loop(void)
{
InpAnalog=analogRead(A1);
tim=InpAnalog*40000/1023;
}
void ISR_Blink()
{
if (n==0){
digitalWrite(T1Pin, HIGH);
delayMicroseconds(10);
digitalWrite(T1Pin, LOW);
n=1;
} else if (n==1){
digitalWrite(T2Pin, HIGH);
delayMicroseconds(10);
digitalWrite(T2Pin, LOW);
n=0;
}
}
Tu te das cuenta que tim la variable con la que pretendes cambiar la frecuencia de disparo esta en dos partes de TODO tu código?
La inicializas
int tim; // inicializas
InpAnalog=analogRead(A1);
tim=InpAnalog*40000/1023; // aca la cambias con el valor de potenciometro
Y ademas de que nadie se entera que tim será la variable para cambiar la frecuencia de disparo, ademas cometes errores obviamente por desconocimiento.
Una variable entera va desde -32764... 0...32765
si tu multiplicas 40000 que ya excede a un entero generas un overflow lo que termina en cualquier cosa.
Entonces las operaciones deben hacerse con long no con int
O puedes hacerlas con int si sabes lo que estas haciendo y como trabaja el Compilador.
Bien, queda claro que lees el potenciometro y nadie se entera asi que hagamos que se entere.
Lo obvio es que si iniciaste con Timer1.initialize(40000); debes hacer algo que modifique ese 40000 por lo que tu quieres no te parece?
prueba asi, no se si no habra que detener interrupciones primero cambiar el TIMER1 y luego volver a activarlas.
void loop(void)
{
InpAnalog = analogRead(A1);
tim = InpAnalog * 40000 / 1023;
Timer1.initialize(tim);
}
NOTA: debes usar Timer1.deatach(), lo modificas y luego otra vez como en el setup.
El problema que veo es que el AD del alrduino suele variar en cada lectura asi que, esto se va a repetir permanentemente.
Tienes que darle alguna rigidez a la rutina para que cambie en determinado contexto y no siempre.
Tal vez usando un pulsador que active la secuencia de cambio que previamente elegiste con el potenciometro o la que tu quieras, pero asi, no es buena idea.
Agradezco tu respuesta. Finalmente quedó andando así:
#include <TimerOne.h>
const int T1Pin = 11;
const int T2Pin = 12;
int n=0;
int T1 = LOW;
int T2 = HIGH;
long tim=0;
long InpAnalog;
void setup(void)
{
pinMode(T1Pin, OUTPUT);
pinMode(T2Pin, OUTPUT);
pinMode(2, INPUT);
attachInterrupt( 0, ReadValor, FALLING);
Timer1.initialize(20000); // Dispara cada 1 ms
Timer1.attachInterrupt(ISR_Blink); // Activa la interrupcion y la asocia a ISR_Blink
interrupts(); // Autoriza las interrupciones
}
void loop(void)
{
}
void ISR_Blink()
{
if (n==0){
digitalWrite(T1Pin, HIGH);
delayMicroseconds(20);
digitalWrite(T1Pin, LOW);
n=1;
} else if (n==1){
digitalWrite(T2Pin, HIGH);
delayMicroseconds(20);
digitalWrite(T2Pin, LOW);
n=0;
}
}
void ReadValor(){
Timer1.detachInterrupt();
InpAnalog=analogRead(A1);
tim=map(InpAnalog, 0, 1023, 0, 20000);
Timer1.initialize(tim); // Dispara cada 1 ms
Timer1.attachInterrupt(ISR_Blink); // Activa la interrupcion y la asocia a ISR_Blink
}