Millis o interrupciones.

Que tal buenas tardes, soy nuevo en el mundo de arduino, he estado tratando de leer sobre los millis pero todo es muy confuso, veo que mucha gente nueva tiene problemas con eso.

El detalle que yo tengo es que tengo que ejecutar la apertura de una secuencia de relevadores durante algunos segundos, por lo cual ocupo un delay.

ahora cuando estoy ejecutando la tarea necesito poner un paro, que termine todas las tareas que se realizan y se active una alarma, para lo cual todo mundo me hablo de los millis.

El sistema de delay mantiene atorado el circuito hasta que termine, lo se y necesito entender bien la función millis, Pueden explicarme como ocupar correctamente los milis , asi como sus elementos basicos.

Se que es algo muy sencillo pero es mi primer contacto con arduino y el material que he visto no resuelve las dudas.

Gracias.

millisi te dice la cantidad de mili segundos que pasan desde que se pone en marcha arduino

la forma de usarlo es guardar el momento en el que pones a uno una salida y después esperar a que pasen x milisegundos desde ese momento para ponerla a 0

no pones el código pero en tu caso sería suficiente con activar las interrupciones externas y conectarlo el pulsador a un pin que tenga esa funcionalidad depende del arduino que sea.

en tu rutina de interrupción mandas todos los relés a un valor seguro y activas un Flag para saber que pulsado el paro y que la secuencia no siga en el loop

es decir algo como

if !emergencia 
{
digital write xx, high
delayms xx
}

if !emergencia 
{
digital write xx, high
delayms xx
}

... más relés

if (emergencia) 
{ emergencia = false
... otro código de emergwncia)}

así en el momento que detecta la emergencia no sigue ejecutando el resto de relés (se espera a que acabe el delay, pero con el relé ya desactivado)

perdón por el pseudocodigo jaja

Hay que manejar con cuidado las interrupciones y <delay()> o <millis()>

Por ejemplo delay() bloquea las interrupciones durante una gran parte de su funcionamiento.
Algo similar le ocurre a <millis()>.
Y ademas ninguna de las dos funciona dentro de una rutina de atencion a la interrupcion (ISR).

Quizás si pusieras el código podriamos estudiar otras alternativas.

Perfecto, muchas gracias en seguida leo sobre las interrupciones, excelente idea.

GO_zalo: millisi te dice la cantidad de mili segundos que pasan desde que se pone en marcha arduino

la forma de usarlo es guardar el momento en el que pones a uno una salida y después esperar a que pasen x milisegundos desde ese momento para ponerla a 0

no pones el código pero en tu caso sería suficiente con activar las interrupciones externas y conectarlo el pulsador a un pin que tenga esa funcionalidad depende del arduino que sea.

en tu rutina de interrupción mandas todos los relés a un valor seguro y activas un Flag para saber que pulsado el paro y que la secuencia no siga en el loop

es decir algo como

if !emergencia 
{
digital write xx, high
delayms xx
}

if !emergencia { digital write xx, high delayms xx }

... más relés

if (emergencia) { emergencia = false ... otro código de emergwncia)}




así en el momento que detecta la emergencia no sigue ejecutando el resto de relés (se espera a que acabe el delay, pero con el relé ya desactivado)

perdón por el pseudocodigo jaja

este es el codigo, me gustaria eliminar todos los delays, es muy sencillo pero necesito aprender a usar los millis para poder hacer otra parte de mi codigo, que seria que si el estadoActivacion =0; se desactive todo y un buzzer intermitente se accione, y cuando lo reactive,se desactive el buzzer.

si hago eso del buzzer con un delay de 1000, al accionar tengo que presionar varias veces hasta atinarle al termino de un delay.

espero me entiendan.

const int LedON =12;
const int Seguridad =9;
const int Arranque =10;
const int Cambio =11;
const int Buzzer =8;
const int Variable =4;
const int Activacion =1;
const int SW1=2;
const int SW2=3;



int estadoActivacion =0;
int estadoanteriorActivacion =0;
int estadoSW1 =0;
int estadoanteriorSW1 =0;
int estadoSW2 =0;
int estadoanteriorSW2 =0;
int estadoSeguridadSW1 =0;
int estadoSeguridadSW2 =0;
int estadoInicial=0;
int estadoVariable=0; 


void setup(){

pinMode (Seguridad , OUTPUT);
pinMode (Arranque , OUTPUT);
pinMode (Cambio , OUTPUT);
pinMode (Buzzer , OUTPUT);
pinMode (LedON , OUTPUT);
pinMode (Activacion,INPUT);
pinMode (SW1,INPUT);
pinMode (SW2,INPUT);
pinMode (Variable,INPUT);

 
}
void loop(){ 

estadoActivacion= digitalRead (Activacion);
if(estadoActivacion==HIGH){
estadoInicial = 1 - estadoInicial;
delay (20);
}
estadoActivacion= estadoanteriorActivacion;
if (estadoInicial==0){
digitalWrite (LedON,LOW);
digitalWrite (Arranque,LOW);
delay(300);
digitalWrite (Seguridad,LOW);
delay(300);
digitalWrite (Cambio,LOW);
estadoInicial=0;
}
else {
digitalWrite (LedON,HIGH);
digitalWrite (Seguridad,HIGH);
delay(500);
digitalWrite (Arranque,HIGH);
delay(500);
}

estadoSW1= digitalRead (SW1);
estadoActivacion= digitalRead (Activacion);
if (estadoInicial==HIGH)
if(estadoSW1==HIGH){
estadoSeguridadSW1 = 1 - estadoSeguridadSW1;
delay (20);
}
estadoSW1 = estadoanteriorSW1;
if (estadoSeguridadSW1==1){
digitalWrite (Arranque,LOW);
delay(300);
digitalWrite (Seguridad,LOW);
delay(300);
digitalWrite (Cambio,LOW);
delay(300);
digitalWrite (Seguridad,HIGH);
delay(300);
digitalWrite (Arranque,HIGH);
delay(300);
estadoSeguridadSW1=0;
estadoSW2=0;
}

estadoSW2= digitalRead (SW2);
estadoActivacion= digitalRead (Activacion);
if (estadoInicial==HIGH)
if(estadoSW2==HIGH) {
estadoSeguridadSW2 = 1 - estadoSeguridadSW2;
delay (20);
}
estadoSW2= estadoanteriorSW2;
if (estadoSeguridadSW2==1){
digitalWrite (Arranque,LOW);
delay(300);
digitalWrite (Seguridad,LOW);
delay(300);
digitalWrite (Cambio,HIGH);
delay(300);
digitalWrite (Seguridad,HIGH);
delay(300);
digitalWrite (Arranque,HIGH);
delay(300);
estadoSeguridadSW2=0;
estadoSW1=0;
}
}

Alfaville:
Hay que manejar con cuidado las interrupciones y <delay()> o <millis()>

Por ejemplo delay() bloquea las interrupciones durante una gran parte de su funcionamiento.
Algo similar le ocurre a <millis()>.
Y ademas ninguna de las dos funciona dentro de una rutina de atencion a la interrupcion (ISR).

Quizás si pusieras el código podriamos estudiar otras alternativas.

Alfaville:
Hay que manejar con cuidado las interrupciones y <delay()> o <millis()>

Por ejemplo delay() bloquea las interrupciones durante una gran parte de su funcionamiento.
Algo similar le ocurre a <millis()>.
Y ademas ninguna de las dos funciona dentro de una rutina de atencion a la interrupcion (ISR).

Quizás si pusieras el código podriamos estudiar otras alternativas.

Alfaville:
Hay que manejar con cuidado las interrupciones y <delay()> o <millis()>

Por ejemplo delay() bloquea las interrupciones durante una gran parte de su funcionamiento.
Algo similar le ocurre a <millis()>.
Y ademas ninguna de las dos funciona dentro de una rutina de atencion a la interrupcion (ISR).

Quizás si pusieras el código podriamos estudiar otras alternativas.

En primer lugar, hay un par de “cosas raras” en tu programa:

.
.
.
estadoSW1= digitalRead (SW1);
estadoActivacion= digitalRead (Activacion);

// ---- esta linea no hace nada -
if (estadoInicial==HIGH)
//------------------------------
.
.
.
estadoSW2= digitalRead (SW2);
estadoActivacion= digitalRead (Activacion);

// ---- y esta linea tampoco ----
if (estadoInicial==HIGH)
//------------------------------

Mirando el flujo del mismo, y aunque usaras millis(), no hay modo de evitar que el programa se detenga el tiempo que le tienes marcado a cada activacion/desactivacion de las levas.
Ejemplo de millis() en tu programa:

unsigned long tiempo;
.
.
.
// esto es con delay()
if(estadoActivacion==HIGH)
{
 estadoInicial = 1 - estadoInicial;
 delay (20);
}

// esto con millis()
if(estadoActivacion==HIGH)
{
 estadoInicial = 1 - estadoInicial;
        tiempo=millis();
 while(millis()-tiempo<20) {}
}

Como veras en tu caso no aportan demasiadas ventajas.

Quizás la solucion mas inmediata sea, como te comentó GO_zalo, usar interrupciones (teniendo presente las salvedades que yá comenté).

Supongo que este hilo esta relacionado con http://forum.arduino.cc/index.php?topic=445838.0

Es asi o estoy equivocado?

son dos proyectos diferentes.

el del sensor hall es para un sillon (5botones). y este es para un sistema de pruebas de brazos (1 boton +2 limit swhitch)

pero gracias por atender =)

surbyte: Supongo que este hilo esta relacionado con http://forum.arduino.cc/index.php?topic=445838.0

Es asi o estoy equivocado?