¿Cómo puedo controlar las cosas sin usar el retardo?

5

Siempre he odiado que no pudieras hacer otras cosas mientras usabas la función delay(); . Sin embargo, quiero parpadear un LED o hacer lo que sea mientras uso la serie, pero ¿cómo funciona esto? ¿Cómo hago esto sin usar la función de demora?

    

2 respuestas

7

Las interrupciones son una forma común de hacer las cosas mientras algo está sucediendo. En el siguiente ejemplo, el LED parpadea sin utilizar delay() . Cuando Timer1 se activa, se llama a la rutina de servicio de interrupción (ISR) isrBlinker() . Enciende / apaga el LED.

Para mostrar que pueden suceder otras cosas simultáneamente, loop() escribe repetidamente foo / bar en el puerto serie independientemente del parpadeo del LED.

#include "TimerOne.h"

int led = 13;

void isrBlinker()
{
  static bool on = false;
  digitalWrite( led, on ? HIGH : LOW );
  on = !on;
}

void setup() {                
  Serial.begin(9600);
  Serial.flush();
  Serial.println("Serial initialized");

  pinMode(led, OUTPUT);

  // initialize the ISR blinker
  Timer1.initialize(1000000);
  Timer1.attachInterrupt( isrBlinker );
}

void loop() {
  Serial.println("foo");
  delay(1000);
  Serial.println("bar");
  delay(1000);
}

Esta es una demo muy simple. Los ISR pueden ser mucho más complejos y pueden activarse por temporizadores y eventos externos (pines). Muchas de las bibliotecas comunes se implementan utilizando ISR.

    
respondido por el walrii
2

Aquí hay un ejemplo en Arduino:

const int ledPin =  13;      // the number of the LED pin

int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED 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 interval = 1000;           // interval at which to blink (milliseconds)

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

void loop()
{
  // here is where you'd put code that needs to be running all the time.
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Esto registra cuando será necesario cambiar y espera hasta que sea ese momento.

Por supuesto, esta función ( millis(); ) se restablecerá después de unos 50 días cuando sea demasiado grande para almacenar, pero si no la mantiene durante más de unos 40 días, debería ser bueno. Podría evitar esto descubriendo qué tan grande puede ser este valor y hacer una declaración if cuando se acerca a la parte superior para detenerse por un minuto más o menos. Tendría problemas para agregar a los milisegundos cuando llega tan alto, pero no sé cómo resolverlo, pero esto funcionará para un proyecto pequeño.

    
respondido por el Anonymous Penguin

Lea otras preguntas en las etiquetas