Go Down

Topic: Temporizador con Arduino sin usar funcion delay() (Read 10461 times) previous topic - next topic

Zer07

Hola,

Me gustaría hacer un temporizador con arduino y un relé conectado a el. El caso es que quiero poder temporizar la duración que va estar encendido (HIGH) y el tiempo que va a estar apagado (LOW), pero esto tiene que ser sin usar la función delay() ya que hago mas cosas con la misma placa y no puede estar interrumpido por la funcion delay()..

La idea es algo así:

long tiempoON = 60000; //para estar HIGH 1 minuto
long tiempoOFF = 120000; //para estar LOW 2 minutos.

y todo lo que sigue que es donde me lió (recuerda, no puedo usar delay()).

Muchas gracias y espero haberme explicado bien!

S2.


Zer07

Gracias.. ya canocia la función millis(), pero me lió un poco al hacer eso que he explicado.. si puedes poner un ejemplo para lo que busco...

Se que es algo sencillo, pero no me sale...
No estoy muy inspirado últimamente, jeje.

Zer07

Tengo un código que monitoriza unos detectores (3 en total), si interrumpo la revisión o monitorización de los detectores poniendo un delay() entonces deja de funcionar. Por eso necesito un código que use la función millis() y que cuando corresponda haga un encendido de un relé y este un tiempo determinado en una variable.. y a continuación que se mantenga apagado por otro determinado tiempo.

Tiene que haber alguna forma de hacerlo usando la función millis() y condicionales if, pero no doy con la solución...

Gracias por vuestra ayuda.


Zer07

Lo que busco no es nada del otro mundo. Todo lo tengo controlado desde el loop(), por tanto todo se debe hacer desde hay sin usar el delay().... nada mas.

Es para cargar una batería desde arduino usando un relé.

La idea es algo así:

Si duracionCarga es de 1 hora apagar el relé (un pindigital) y esperar duracionDescarga durante 2 horas ... y loop() de esto una y otra vez sin alterar la demas cosas que tengo dentro del loop().

(No tengo en este pc el source, pero la idea es esa).

Saludos.

xlopez

En los ejemplos está BlinkWithoutDelay que hace parpadear un led, con el mismo tiempo de ON y de OFF.

Se puede modificar fácilmente para que hayan diferentes tiempos de ON y de OFF.

En el ejemplo se comprueba if(currentMillis - previousMillis > interval)

Ahora hay que diferenciar si tenemos el led apagado o encendido y comparar con el tiempo de cada uno de ellos.

El código resultante es:
Code: [Select]
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

long intervalOn = 500;           // medio segundo  ON
long intervalOff = 5000;         // cinco segundos OFF
void setup() {
  pinMode(ledPin, OUTPUT);     
}

void loop()
{
  unsigned long currentMillis = millis();
  if (ledState == LOW) {
    if(currentMillis - previousMillis > intervalOff) {
            previousMillis = currentMillis;   
            ledState = HIGH;
    }
} else {
    if(currentMillis - previousMillis > intervalOn) {
           previousMillis = currentMillis;   
          ledState = LOW;
    }
}
digitalWrite(ledPin, ledState);
}


Espero que te sirva.

Zer07


En los ejemplos está BlinkWithoutDelay que hace parpadear un led, con el mismo tiempo de ON y de OFF.

Se puede modificar fácilmente para que hayan diferentes tiempos de ON y de OFF.

En el ejemplo se comprueba if(currentMillis - previousMillis > interval)

Ahora hay que diferenciar si tenemos el led apagado o encendido y comparar con el tiempo de cada uno de ellos.

El código resultante es:
Code: [Select]
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

long intervalOn = 500;           // medio segundo  ON
long intervalOff = 5000;         // cinco segundos OFF
void setup() {
  pinMode(ledPin, OUTPUT);     
}

void loop()
{
  unsigned long currentMillis = millis();
  if (ledState == LOW) {
    if(currentMillis - previousMillis > intervalOff) {
            previousMillis = currentMillis;   
            ledState = HIGH;
    }
} else {
    if(currentMillis - previousMillis > intervalOn) {
           previousMillis = currentMillis;   
          ledState = LOW;
    }
}
digitalWrite(ledPin, ledState);
}


Espero que te sirva.


Sehh! Creo que esto me vale! Lo malo que no puedo probarlo hasta el lunes (no tengo aquí la placa). Pero si, esto es lo que busco.
Muchas gracias majo,

Saludos.

Zer07

Finalmente hoy he probado el código y funciona de maravilla!
Adicionalmente le he añadido para poder establecer las variables intervalOn y intervalOff en minutos en vez de en mili-segundos.

Gracias y un saludo.

jhonson01

Hola

Quisiera saber como hacer con la Arduino Mega un temporizador tipo monoestable....

Necesito activar un ventilador por 10 minutos cuando la variable que leo que es temperatura llegue a 30°C, pero sin usar el delay porque también estoy leyendo otras variables y a la vez enviandolas por puerto serial.

Como podría por código implementar eso?. Gracias

Heke


Hola

Quisiera saber como hacer con la Arduino Mega un temporizador tipo monoestable....

Necesito activar un ventilador por 10 minutos cuando la variable que leo que es temperatura llegue a 30°C, pero sin usar el delay porque también estoy leyendo otras variables y a la vez enviandolas por puerto serial.

Como podría por código implementar eso?. Gracias


Con la misma solucion y el 99 % del codigo que han apuntado al compañero que inicio el post.
CUIDADO !! MIS POST NO SON APTOS PARA MENORES. SI ERES MENOR DE 14 AÑOS DEBES DE LEERLOS ACOMPAÑADO DE UN ADULTO

xlopez

Hola,

Depende de si quieres el monoestable redisparable (si se aprieta el pulsador se reinicia la cuenta de los diez segundos) o no (no se reinicia).

Voy a suponer que no lo quieres redisparable.

Tienes que pensar en el monostable como una máquina de estados.

Tienes dos estados el estado 'ESPERANDO' y el estado 'ACTIVO' .

En el estado 'ESPERANDO' lo único que tienes que fijarte es si se aprieta el botón, en ese caso se hace lo siguiente:
if (pinBoton==HIGH) {
   previousMillis = currentMillis;
   estado=ACTIVO;
   ledState=HIGH;
}

Y si estamos en estado 'ACTIVO' simplente comprobamos si se han pasado los 10 segundos
if(currentMillis - previousMillis > intervalOn) {
          ledState = LOW;
          estado=ESPERANDO;
}

Quedaría algo así:
loop() {
currentMillis = millis();
if (estado==ESPERANDO){
  bloque1;
}
else {
  bloque2;
}
}

locoelectro


xlopez estoy con el tema de los millis()
e estado probando tu código, y funciona.
pero tengo un problema
mi proyecto es una alarma con rfid para activarla o desactivarla
el rfid lo tengo en la parte exterior y necesito que estando adentro, cuando abro la puerta me espere 5 segundos y si en esos 5 segundo no se mando la señal del rfid con la identificación suene la alarma, en el caso contrario que no suene pero que siga activa la alarma a penas cierre la puerta
en síntesis:
si se activa la alarma espere
5000 milisegundos en estos 5 segundos que se quede esperando si se le dio la orden para desactivarla que se desactive
en caso contrario que suene.
se entiende?

xlopez

Lo que yo entiendo de tu alarma es lo siguiente:

  • La alarma está siempre activa

  • Si se abre la puerta espera 5 segundos y si no ha llegado el código se activa

  • Supongo que si está sonando puedes enviar el código para que deje de sonar


Plantéatelo como si la alarma tiene tres estados.
1.- Alarma armada pero no sonando, es el estado inicial y que fijarás en el setup()
2.- Detectada puerta y esperando los 5 segundos.
3. Alarma sonando.

Cuando está en estado 1  (armada) lo único que hace es esperar a que se detecte la puerta.
Si se detecta la puerta haces lo siguiente:
- Inicias el temporizador previousMillis = millis()
- Fijas el estado en 2.

Cuando estás en estado 2 (puerta) haces lo siguiente:
- Si llega el código pasas a estado 1
- Si no ha llegado compruebas cuanto tiempo llevas if (millis()-previousMillis > 5000)
- Y en caso afirmativo activas la alarma y pasas a estado 3.

Cuando estás en estado 3 (sonando) lo único que haces es esperar el código y si llega apagas la alarma y pasas a estado 1.

Mancera

#13
Mar 22, 2014, 02:04 pm Last Edit: Mar 22, 2014, 02:06 pm by Mancera Reason: 1
Buenas Tardes,
Soy un poco novato en el tema de la programación en el Arduino. y tengo una problema.
Quiiero realizar un programa en el que cuando una entrada me de un impulso se me active una salida durante un determinado tiempo, a continuación utilizando un contador, cuando se de otro impulso a la entrada se me active la siguiente salida esté o no la anterior activa, y así sucesivamente con las demás, nose si me explico bien.

El problema que tengo utilizando el delay es que me para el la ejecución del programa entonces al realizar otro impulso no se me activa la siguiente salida.

Haber si alguien me pudiera ayudar. Os dejo como llevo el programa para que me ayudeis.

int cuenta = 0;

void setup(){
   pinMode(0, INPUT);
   pinMode(1, OUTPUT);
   pinMode(2, OUTPUT);
   pinMode(3, OUTPUT);
   pinMode(4, OUTPUT);
}

void loop(){
   
   if (digitalRead(0) == HIGH){

      if(digitalRead(0) == LOW){
         cuenta = cuenta++;
         delay(100);
         if(cuenta==5)
            cuenta = 0;
      }
   }
   if(cuenta == 1){
      digitalWrite(1, HIGH);
      delay(5000);
      digitalWrite(1, LOW);
   }
   if(cuenta == 2){
      digitalWrite(2, HIGH);
      delay(5000);
      digitalWrite(2, LOW);
   }
   
   if(cuenta == 3){
      digitalWrite(3, HIGH);
      delay(5000);
      digitalWrite(3, LOW);
   }
   
   if(cuenta == 4){
      digitalWrite(4, HIGH);
      delay(5000);
      digitalWrite(4, LOW);
   }
}

Muchas Gracias

Go Up