Pages: [1] 2   Go Down
Author Topic: Timers en arduino  (Read 4754 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola a todos. ¿Sabéis qué librerías existen para manejar Timers en Arduino? Yo he utilizado la "MsTimer2", pero necesitaría otro timer extra...He leído por ahí que hay hasta 3, pero no he encontrado ninguna librería como la mencionada para poder utilizarlos...Soy todo orejas.
Logged

Madriz
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Glober Arduiner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

timers 1 y 3:

http://www.arduino.cc/playground/Code/Timer1
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

La librería que me pasas funciona...pero tengo también usando  la librería "VirtualWire" y ésta me deja de emitir...deben usar registros comunes...
El Timer3 no funciona en mi nano...
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

El microcontrolador que usa Arduino dispone de 3 Timers, pero cómo bien has dicho, se usan para funciones del core de Arduino.
Los Timer son 0,1 y 2.

El Timer 0 es utilizado,por ejemplo, por la función millis().
El Timer 1 y 2 es usado para PWM (si no estás utilizando PWM, pues puedes usarlo para tu menesteres).
A parte de librerías que también los usan.

¿Qué quieres hacer?
Logged


0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

simplemente encender y apagar un led con una cadencia de 250 ms
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Puedes usar la funcion millis() para eso. Esta funcion te devuelve el numero de milisegundos desde que se inicio Arduino.
Puedes usarlo para cronometrar tus tiempos.


smiley-wink
« Last Edit: February 15, 2011, 04:49:08 am by Igor R » Logged


0
Offline Offline
Jr. Member
**
Karma: 5
Posts: 72
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si es sólo para encender y apagar un led usa el código de BlinkWithoutDelay.

Si tienes que encenderlo y apagarlo a la vez que haces otras cosas funciona igual de bien (siempre que lo que tengas en el bucle loop no gaste muchos milisegundos).

Por ejemplo para controlar tres leds con distinta frecuencia copias el código del BWD y replicas las variables para cada led.
Code:
/* Blink without Delay, modificado para 3 leds */

// constants won't change. Used here to
// set pin numbers:
const int ledPinA =  13;      // the number of the LED pin A
const int ledPinB =  12;      // the number of the LED pin B
const int ledPinC =  11;      // the number of the LED pin C

// Variables will change:
int ledStateA = LOW;             // ledState used to set the LED A
int ledStateB = LOW;             // ledState used to set the LED B
int ledStateC = LOW;             // ledState used to set the LED C
long previousMillisA = 0;        // will store last time LED A was updated
long previousMillisB = 0;        // will store last time LED B was updated
long previousMillisC = 0;        // will store last time LED C was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long intervalA = 1000;           // interval at which to blink LED A(milliseconds)
long intervalB = 300;           // interval at which to blink LED B(milliseconds)
long intervalC = 700;           // interval at which to blink LED C(milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPinA, OUTPUT);     
  pinMode(ledPinB, OUTPUT);     
  pinMode(ledPinC, OUTPUT);     
}

void loop()
{
  unsigned long currentMillis = millis();
  //Led A
  if(currentMillis - previousMillisA > intervalA) {
    previousMillisA = currentMillis;   
    if (ledStateA == LOW)
      ledStateA = HIGH;
    else
      ledStateA = LOW;
    digitalWrite(ledPinA, ledStateA);
  }
  //Led B
  if(currentMillis - previousMillisB > intervalB) {
    previousMillisB = currentMillis;   
    if (ledStateB == LOW)
      ledStateB = HIGH;
    else
      ledStateB = LOW;
    digitalWrite(ledPinB, ledStateB);
  }
  //Led C
  if(currentMillis - previousMillisC > intervalC) {
    previousMillisC = currentMillis;   
    if (ledStateC == LOW)
      ledStateC = HIGH;
    else
      ledStateC = LOW;
    digitalWrite(ledPinC, ledStateC);
  }
}
Logged

0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gracias Xlopez por tu aporte, pero ya lo he utilizado y resulta que como depende de las funciones que se hagan en el "loop", hay veces que no es exactamente el tiempo que pongo en "interval"...y es capaz de apreciarse. Por eso busco el tema del timer, para conseguir exactitud en el parpadeo.
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Puedes usar el timer 2 si no estas usando PWM de los pines 3 y 11.
Mira esto que hice a ver si te sirve => http://real2electronics.blogspot.com/2011/01/timer-2.html

Puedes explicar mejor tu problema de por que solo el timer 2 no te era suficiente?
« Last Edit: February 15, 2011, 05:44:23 am by Igor R » Logged


0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Igor, por lo que entiendo, ¿puedo utilizar el timer 2 para que me ejecute 2 interrupciones diferentes? Es decir, ¿puedo hacer que se ejecute una cada 250 ms y otra cada 500ms? En este caso cuando se tenga que ejecutar la de 500ms, también lo tendrá que hacer la de 250ms a la vez.
El problema es que ya tengo el timer2  utilizado con la librería "MsTimer2.h", que es sencilla de usar.
He intentado rebajar el tiempo de dicho timer de 500ms a 250ms para poder utilizarlo para ambas operaciones, pero tengo un GPS que escupe datos cada sg y parece que si bajo esa frecuencia del timer, al micro ya no le da tiempo a capturar todos los datos bien...
Logged

0
Offline Offline
Jr. Member
**
Karma: 5
Posts: 72
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No puedes utilizar el timer para que haga dos interrupciones diferentes, pero si puedes hacer que esa interrupción haga dos cosas diferentes.

Si la interrupción se ejecuta cada 250 ms entonces:
- Cada vez que se ejecute cambias el estado del led (on / off) --> tiempo casi despreciable
- Una de cada dos ejecutas lo que quieres que se ejecute cada 500ms.

¿Como controlas lo de 'una de cada dos'?
Con la misma variable que controlas el led, por ejemplo, cuando vayas hacer el ledon ejecuta lo que quieres hacer cada 500ms.
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Solo por aclaracion, por ejemplo con un timer de 8 bits a 16 Mhz y preescaler de maximo 1024, no vas a poder hacer una interrupcion cada 250 ms....
Otra cosa, es que tengas un contador y que no "actues" hasta que dicho valor es igual a cierto valor ( ejemplo, si tu interrupcion es cada milisegundo, pues cuando la variable que incrementas dentro de la interrupcion es igual a 250). Vaya, lo que me refiero, a que tienes una interrupcion cada menos tiempo, otra cosa es que hagas algo o no.

La idea es hacer lo que dice xlopez. Usar una base de tiempos que te sea valida para "temporizar" adecuadamente todo.
Intenta hacer control de puertos/pines directamente, para que la rutina de apagar o encender sea lo mas rapida posible.
Manejar directamente el timer, en vez la libreria, tambien te ayudara a tiempo, ya que el llamar a funciones, hace que el micro tenga que hacer un "extra" trabajado cada vez que se la llama.

Si estas recibiendo cosas por puerto serie, siempre vas a tener "parones" inesperados. Ya que cuando se recibe un dato por puerto serie, el core de Arduino esta preparado para lanzar una interrupcion, y lo que se hace es guardar el byte recibido dentro del buffer de recepcion.

Necesitas mucha precision en la temporizacion?
Logged


0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gracias Xlopez, eso mismo estaba haciendo según lo comentas y funcionó. Lo que había antes lo ejecuto cada dos veces que entra la interrupción, bajando el tiempo de interrupción a la mitad (evaluando un booleano que cambia de valor cada vez que entra y verificando en el mismo código  de interrupción cuándo está a true).

Con respecto a lo que me comentas Igor, realmente no necesito demasiada precisión en los tiempos por lo que no creo necesario trabajar directamente en los registros del micro (lo del tema de los leds era porque se veía a simple vista que tenían tiempos de parpadeo no constantes y no queda muy profesional).
Por otro lado, si que he conseguido la interrupción a 250ms. No he indagado bien como funciona la librería y el tema de tocar directamente los registros del micro, pero con "MsTimer2" no he tenido problema en configurarlo a 250ms...
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Solo te decia como va por dentro....ya que pasan estas cosas cuando la cosa se empieza a complicar, que si interrupciones del timer0 para millis, que si interrupciones del puerto serie, que si interrupciones del timer 2 (que no son cada 250 ms   smiley-wink   ), llamadas a mil funciones.....Y es un pobrecito micro de 8 bits a 16 Mhz.....

Si no necesitas precision,volvemos donde empezamos..... usa millis().   smiley-lol

« Last Edit: February 15, 2011, 08:13:21 am by Igor R » Logged


0
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lo que dices es cierto Igor, es un micro pequeñito y la verdad es que lo tengo bastante "aprovechado", por eso, cualquier cosa que ponga nueva, aunque sea sencilla, me hace fallar cosas y hay que restructurar. Para eso buscaba un timer, para ponerlo sin mas con su código de interrupción. Al final he conseguido el propósito con lo propuesto por Xlopez.

Para que os hagais una idea de lo que hace:
-Testear 2 entradas analógicas a sensar.
-Tiene una intrada de interrupción asociada a un sensor infrarrojo.
-Tiene un GPS que envia entre 135 y casi 300 bytes cada segundo (lo cual tengo que parsear para sacar la info que necesito)
-Tiene a otra entrada de interrupción contando pulsos del orden de 15000 RPM.
- Además toda esta información la encapsulo y la envío por radio a otro arduino.
- Por último, los dichosos leds a intervalos de 250ms.

Creo que no me dejo nada...


Logged

Pages: [1] 2   Go Up
Jump to: