2012-05-27 12 views
8

¿Qué puedo usar para realizar una función en el ciclo si ninguna de las otras condiciones del ciclo y su código se han ejecutado después de un cierto período de tiempo? ¿Se puede hacer con retraso o hay alguna otra función?Realización de una función después del tiempo x

Respuesta

9

No creo que sea posible implementarlo ya que el Arduino no tiene un reloj interno.

EDIT: Es posible utilizar la función millis() para calcular una cantidad de tiempo transcurrido desde el inicio de la junta:

unsigned long previousMillis = 0; // last time update 
long interval = 2000; // interval at which to do something (milliseconds) 

void setup(){ 
} 

void loop(){ 
    unsigned long currentMillis = millis(); 

    if(currentMillis - previousMillis > interval) { 
    previousMillis = currentMillis; 

    // do something 
    } 
} 
+0

Un tutor mencionó que es posible agregar a mi código, pero no explicó cómo. He oído hablar de la función millis() pero no la entiendo, ¿inicia un temporizador cuando la llamas? ¿O solo muestra el tiempo transcurrido desde el inicio del ciclo? – Markaj

+1

Muestra el tiempo transcurrido desde el inicio de la placa. Este número se desbordará (vuelva a cero), después de aproximadamente 50 días (fuente: http://arduino.cc/en/Reference/millis) –

+0

Edité mi respuesta con una muestra. –

1

Pruebe la Metro library, lo que le permite hacer recurrentes eventos programados. Puedes cambiar la frecuencia del temporizador dentro del ciclo, si eso es algo deseable.

1

La función millis() normalmente funciona lo suficientemente bien para esto, a menos que desee que el tiempo de espera sobreviva al reinicio del arduino.

que sería implementar una clase Timer que no pierde de vista la última vez some_condition se cumplió:

class Timer 
{ 
public: 
    Timer(void); 
    void set_max_delay(unsigned long v); 
    void set(void); 
    boolean check(void); 
private: 
    unsigned long max_delay; 
    unsigned long last_set; 
}; 

Timer::Timer(void) 
{ 
    max_delay = 3600000UL; // default 1 hour 
} 

void Timer::set_max_delay(unsigned long v) 
{ 
    max_delay = v; 
    set(); 
} 

void Timer::set() 
{ 
    last_set = millis(); 
} 

boolean Timer::check() 
{ 
    unsigned long now = millis(); 
    if (now - last_set > max_delay) { 
     last_set = now; 
     return true; 
    } 
    return false; 
} 

Timer timer; 

void setup() 
{ 
    timer.set_max_delay(60000); // 1 minute 
} 

void loop() 
{ 
    boolean some_condition = false; 
    if (some_condition) { 
     timer.set(); 
    } 
    if (timer.check()) { 
     // nothing happened for a long time 
    } 
    delay(500); 
} 

Mientras some_condition no se cumple el valor last_set del temporizador no actualizarse. Lo que implicaría en la check() para volver true (una vez por intervalo, como check() establece el valor last_set)

Si la comprobación tiene que sobrevivir a un reinicio del procesador, entonces usted necesita una batería de copia de seguridad (en tiempo real) reloj y tienda y recuperar last_set de EEPROM.

1

Existen muchas versiones de estas rutinas de temporizador, todas asumen que si ha alcanzado o excedido el tiempo de espera, restablece la variable de temporizador de millis(). Incorrecto. ¿Qué pasa si has estado ocupado y has pasado la franja de tiempo? El lote ahora se ha extendido.

Digamos que queremos hacer algo cada 50ms. Digamos que nos retrasaron y ahora son 55 ms. Después de la última comprobación ... comprobamos ... de hecho sobrescribimos la variable del temporizador para obtener una coincidencia en 50 ms. pero ahora estamos 5ms atrás. Tenemos que compensar por llegar tarde y lo que sucede si hay un exceso de capacidad en este punto ....

1

Un temporizador que va a sobrevivir a una El reinicio del Arduino es imposible de implementar sin partes externas. El problema es que no hay forma de averiguar cuánto tiempo se reinició. Además, el gestor de arranque puede consumir una cantidad desconocida de tiempo durante el reinicio. Por lo tanto, necesitarías un reloj externo en tiempo real.

Con respecto a la ejecución del período de eventos, mi favorito es la biblioteca msTimer2.ver aquí para algunos de mis ejemplos:

http://blog.blinkenlight.net/experiments/basic-effects/persistence-of-vision/

http://blog.blinkenlight.net/experiments/removing-flicker/heartbeat/

http://blog.blinkenlight.net/experiments/basic-effects/lighthouses/

1

Mi amigo retardo() y delayMicroseconds serán toda la ayuda que usted().

En lo que respecta a otras respuestas.

mills() - Devuelve el número de milisegundos desde que la placa Arduino comenzó a ejecutar el programa actual. Este número se desbordará (volverá a cero), después de aproximadamente 50 días.

Consulte: http://arduino.cc/en/Reference/millis

Del mismo modo,

micros() - Devuelve el número de microsegundos desde la placa Arduino comenzó a correr el programa actual. Consulte: http://arduino.cc/en/Reference/Micros

Supongo que necesita trabajar un poco en estos dos para hacer ejercicio en su caso.

5

Pruebe las interrupciones del temporizador arduino. No se necesitan bibliotecas externas o incluso hardware adicional, ya que el procesador se puede considerar como un reloj ... a 16 MHz.

#include <avr/io.h> 
#include <avr/interrupt.h> 

void setup() 
{ 

    // INITIALIZE TIMER INTERRUPTS 
    cli(); // disable global interrupts 

    TCCR1A = 0; // set entire TCCR1A register to 0 
    TCCR1B = 0; // same for TCCR1B 

    OCR1A = 15624; // set compare match register to desired timer count. 16 MHz with 1024 prescaler = 15624 counts/s 
    TCCR1B |= (1 << WGM12); // turn on CTC mode. clear timer on compare match 

    TCCR1B |= (1 << CS10); // Set CS10 and CS12 bits for 1024 prescaler 
    TCCR1B |= (1 << CS12); 

    TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt 

    sei(); // enable global interrupts 

} 

// TIMER VECTOR, gets called once a second (depends on prescaler and match register) 
ISR(TIMER1_COMPA_vect) 
{ 
    // do your timeing based stuff here 
} 

need more info on interrupts?

+0

¡El artículo vinculado es muy útil! –

1

Puede utilizar a continuación muestra code.Here repitiendo los pasos para cada 1 ms.

#include <SimpleTimer.h> 

// the timer object 
SimpleTimer timer; 

// a function to be executed periodically 
void repeatMe() 
{ 
    Serial.print("Uptime (s): "); 
    Serial.println(millis()/1000); 
} 

void setup() 
{ 
    Serial.begin(9600); 
    timer.setInterval(1000, repeatMe); 
} 

void loop() 
{ 
    timer.run(); 
} 
Cuestiones relacionadas