Uso de los temporizadores como contadores en Arduino

Scooter

Cascarrabias crónico
Pues eso mismo.
¿Alguien ha usado los timers para contar pulsos?
He visto varios tutoriales pero empleando directamente los registros,

Edito: Hasta el momento no he encontrado una librería.

¿Alguien ha usado los contadores o puede aportar alguna experiencia/ recomendación?


La idea es usar un control de fase par regular la velocidad de un motor de colector de una lavadora. Esto ya está controlado usando un triac y el timer 2 mediante la librería FlexiTimer2. Resulta que le motor lleva un resolver alterna hasta 80Vmax hasta 3kHz y pensaba sencillamente leer los pulsos y no la tensión, para ello pensaba usar el timer 1 como contador de pulsos.
 
Última edición:
Hola Scooter.

Justamente estoy trabajando en un problema similar, aunque es en PIC y programado en Assembler.

Estoy usando el Timer1 en modo "Capture".

Si te sirve, te puedo hacer un pantallazo de cómo lo estoy encarando. Sino aprovecho este mensaje para quedar suscripto al tema.

Saludos.
 
Si hacerlo "a manubrio" lo podría hacer, pero me da pereza. Por eso busco algo hecho.
Por eso busco una biblioteca, parece ser que no tienen muy claro el concepto "counter" todas las que he visto "cuentan" el reloj del sistema... osea que temporizan.
"basta" con cambiar el bit que hace contar desde un pin en lugar del oscilador interno.
 
Cuando la tierra aún estaba caliente y los dinosaurios corrían con tacos altos para no quemarse yo usé el timer del 80C196KB para contar los pulsos de un codificador óptico incremental precisamente cambiando el bit entrada y encaminando por ahí los pulsos del encoder. Por supuesto que hay que prepocesar por hardware las dos señales del encoder para eliminar los "rebotes" cuando el motor oscila entre dos posiciones muy cercanas y también para obtener el sentido de giro del motor.
A cada instante de muestreo leía el contador, calculaba la diferencia con la cuenta anterior y en base al bit de sentido de giro sabía si debía sumar o restar esa diferencia a la ultima posición registrada.
Habían algunos chiches mas pero la base era lo que describí.
Lamentablemente, si tengo el código en lenguaje PLM) debe estar en diskettes de 5 1/4" en algún lugar perdido...y no tengo como leer diskettes :rolleyes::rolleyes:
 
Última edición:
Hola, aquí a partir del minuto 12:00, habla algo de cómo utilizar interrup. por cambio de valor en un pin externo en Arduino. Quizás te sea útil.
Eso le puede servir (es más, existe una biblioteca muy buena, rápida y completa para Arduino) el problema es la sobrecarga en tiempo de ejecución si la frecuencia de los pulsos es relativamente alta.
En cambio, usando los contadores por hardware no hay sobrecarga alguna...
 
Estoy haciendo control de fase con este sistema:
Ahí ya hay 100 interrupciones por segundo del pin externa mas dos veces el timer 2 que generan otras dos, una para activar el triac y otra para dejar de activarlo, así que ya vamos por las 150 interrupciones por segundo.
Si a eso le sumamos 3000 mas del resolver...
La idea era que un pin cuente los pulsos "él solito" y cada vez que se pase por cero, además de lanzar el timer 2 para el control de fase, se lee y se borra el registro del contador-temporizador 1 que debe de tener un número entre 0 y 30 dependiendo de la velocidad.

Las otras dos opciones son rectificar y filtrar la salida del resolver y leerla en un pin analógico peeero, no sé como de lineal es con la tensión y luego el filtrado, no es lo mismo filtrar a 3k que a 500Hz y la velocidad cambia, si filtras poco ves las crestas, si filtras mucho no las ves y tienes un tiempo de establecimiento enorme...
Por último poner un preescaler y una de dos, o leer el registro de la cuenta o medir el periodo en el que desborda... pero eso hay que pagarlo, dejamos sin usar el timer 1 que ya está comprado y sin usar y ponemos cosas por afuera.

En vacío en conexión directa el resolver da un poco mas de 3kHz 80Vmax, eso son 30 pulsos por semiciclo.
Si, puedo activar otra interrupción y hacer una rutina que solo tenga valor++ como código, y en cada paso por 0 de la red hacer velocidad = cuenta y cuenta = 0 , pero cuesta menos solo hacer velocidad = timer 1 y timer1 = 0 y sin hacer 30 veces cuenta++

Es por hacer el boticario también.
 
Última edición:
En vacío en conexión directa el resolver da un poco mas de 3kHz 80Vmax, eso son 30 pulsos por semiciclo.
Si, puedo activar otra interrupción y hacer una rutina que solo tenga valor++ como código, y en cada paso por 0 de la red hacer velocidad = cuenta y cuenta = 0 , pero cuesta menos solo hacer velocidad = timer 1 y timer1 = 0 y sin hacer 30 veces cuenta++
No es buena idea poner a 0 el contador por software, por que no sabés cuando ocurre el proximo incremento y podés perder pulsos ya que el conteo del hardware es asincrónico a la ejecución del software.
En tu caso no estaaan grave por que no acumulás pulsos para "contar posición", pero - defensivamente - YO copiaría la cuenta y luego restaría sin resetear el contador.
 
Las otras dos opciones son rectificar y filtrar la salida del resolver y leerla en un pin analógico peeero, no sé como de lineal es con la tensión y luego el filtrado, no es lo mismo filtrar a 3k que a 500Hz y la velocidad cambia, si filtras poco ves las crestas, si filtras mucho no las ves y tienes un tiempo de establecimiento enorme...

No sé cómo funcionaría porque la salida del resolver no es "cuadrada", pero para eso a lo mejor se podría utilizar un LM331 para transformar los "pulsos" en un voltaje más estable. Con una onda bien cuadrada, con un ciclo de trabajo mínimo de 25% el LM funciona muy bien. Menos de ese ciclo de trabajo yo por lo menos no lo pude hacer funcionar bien.

A lo mejor con un conformador de onda antes del LM, pero ya es agregar cada vez más cosas.
 
El problema es que cualquier proceso a la señal del resolver para volverla "analógica" genera retardos en el lazo del control de velocidad. Yo no sé que algoritmo de control usa ni la dinámica del motor, pero el retardo puede inestabilizar el lazo y generar problemas...
 
Última edición:
Estoy haciendo control de fase con este sistema:
Ahí ya hay 100 interrupciones por segundo del pin externa mas dos veces el timer 2 que generan otras dos, una para activar el triac y otra para dejar de activarlo, así que ya vamos por las 150 interrupciones por segundo.
Si a eso le sumamos 3000 mas del resolver...
La idea era que un pin cuente los pulsos "él solito" y cada vez que se pase por cero, además de lanzar el timer 2 para el control de fase, se lee y se borra el registro del contador-temporizador 1 que debe de tener un número entre 0 y 30 dependiendo de la velocidad.

Las otras dos opciones son rectificar y filtrar la salida del resolver y leerla en un pin analógico peeero, no sé como de lineal es con la tensión y luego el filtrado, no es lo mismo filtrar a 3k que a 500Hz y la velocidad cambia, si filtras poco ves las crestas, si filtras mucho no las ves y tienes un tiempo de establecimiento enorme...
Por último poner un preescaler y una de dos, o leer el registro de la cuenta o medir el periodo en el que desborda... pero eso hay que pagarlo, dejamos sin usar el timer 1 que ya está comprado y sin usar y ponemos cosas por afuera.

En vacío en conexión directa el resolver da un poco mas de 3kHz 80Vmax, eso son 30 pulsos por semiciclo.
Si, puedo activar otra interrupción y hacer una rutina que solo tenga valor++ como código, y en cada paso por 0 de la red hacer velocidad = cuenta y cuenta = 0 , pero cuesta menos solo hacer velocidad = timer 1 y timer1 = 0 y sin hacer 30 veces cuenta++

Es por hacer el boticario también.
... y todo el lio se te arma por usar el arduino, que no esta ya para estas cosas, tiene que ser C plano o ASM.

Pero si has tomado conciencia de la cantidad de interrupciones y encima hay que calcular algo y que el proceso no sea divergente (culpa de la velocidad de cálculo), en tu lugar cambio de micro... le entro al raspberry pi pico dos nucleos 133mHz, primero intentaría a lo Arduino, despues le entraría al C plano si no me piacche.

pd: proba una vez mas el 328p con c plano, nada de arduino, y a 20mHz... ya sabes programar no es tanto el cambio, llegaste a todo lo que te puede dar la plataforma Arduino...
 
La salida del resolver es senoidal, razonablemente senoidal. No le he hecho el análisis en frecuencias, podría haber pulsado el botón del osciloscopio y no lo hice.
De momento está descartado medirlo en tensión en analógico.
 
Yo creo que para empezar hay que definir que Arduino es una plataforma, que bien el chip puede ser un AVR, SAMD, STM32, RP2040, RA4M1, ESP32. . .
Y cada familia tiene su propia forma de definirlo, por toda la HAL que lleva Arduino encima no hay una librería para tocar eso, normalmente ya te vas con la HAL del fabricante, si no dices para empezar cual estas usando pues ya pareces nuevo en el foro.
 
Cierto, en cuanto te metes con cosas concretas cada familia tiene unas librerías diferentes.
Al "no decir nada" se entiende, o "yo entiendo que se entiende", que es un AVR "normal" osea un uno o semejante, los Leonardo cambian cosas pero en esencia son lo mismo.

Casi seguro que siga el primer tutorial que aporté y ya está. Es lo bastante sencillo y funcional.
 
Se usa sin problemas siguiendo el primer manual, solo que si no es un UNO el pin es otro. Hay que leer el manual y ver donde se encuentra el pin.

C++:
/*
* LAB Name: Arduino Timer (Counter Mode)
* Author: Khaled Magdy
* For More Info Visit: www.DeepBlueMbedded.com
*/

 // En el arduino leonardo los pulsos entran por el pin 13
 // En el arduino UNO los pulsos deberían de entrar por el pin 5
void setup()
{
  TCCR1A = 0;           // Init Timer1A
  TCCR1B = 0;           // Init Timer1B
  TCCR1B |= B00000111;  // External Clock on T1 Pin (RISING)
  TCNT1 = 0;
  Serial.begin(9600);
}

void loop()
{
  Serial.print("Counter Ticks = ");
  Serial.println(TCNT1);
  delay(250);
}
 
Atrás
Arriba