sustituir delay por millis, problemas

Buenas a todos, tengo realizado un sencillo código para un pequeño proyecto que estoy desarrollando en un local con unos sensores y una sirena en plan alarma, el problema viene que al usar delay hasta que no pasa el tiempo el arduino se queda parado en esa acción.

He mirado el ejemplo que hay de hacer el intermitente sin usar delay y he añadido otro led de manera que consigo hacer que cada led papadee con diferente frecuencia, pero claro a la hora de sustituir los delay por millis en el código del local no se muy bien como hacerlo para que actué según el estado de los sensores.

Aquí el código de los 2 leds con diferente tiempo de parpadeo

// constants won't change. Used here to set a pin number :
int ledPin =  13;      // the number of the LED pin
int ledPin1 = 12;
// Variables will change :
int ledState = LOW;             // ledState used to set the LED
int ledState1 = LOW;             // ledState used to set the LED

// Generally, you shuould use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long previousMillis1 = 0;        // will store last time LED was updated


// constants won't change :
const long interval = 300;           // interval at which to blink (milliseconds)
const long interval1 = 30;          // interval at which to blink (milliseconds)

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

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
  unsigned long currentMillis = millis();
  unsigned long currentMillis1 = 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);
   
}
 
  if(currentMillis1 - previousMillis1 >= interval1) {
    // save the last time you blinked the LED 
    previousMillis1 = currentMillis1;   

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

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

Aquí el código de la alarma intentando sustituir los delay por millis

int ledPin = 13; // LED conectado a pin digital 13
int ledPin1 = 12;
int analogPin1 = 1; // Entrada de señal sensor 2
int analogPin0 = 0; // potentiómetro conectado a pin analógico 3
int val = 0; // variable para almacenar el valor capturado
int threshold = 512; // valor de disparo o umbral (1024/2)
int ledState = LOW; 
int ledState1 = LOW;  
unsigned long previousMillis = 0;     
unsigned long previousMillis1 = 0;

const long interval = 300;           // interval at which to blink (milliseconds)
const long interval1 = 30;          // interval at which to blink (milliseconds)


void setup() {
  delay(30);
pinMode(ledPin, OUTPUT); // asigna modo salida el pin digital 13
}
void loop() {
  
    unsigned long currentMillis = millis();
    unsigned long currentMillis1 = millis();

val = analogRead(analogPin1); // captura el pin de entrada
if (val >= threshold) {unsigned long currentMillis = millis();    // Se toma el tiempo actual

// se comprueba si el tiempo actual menos el tiempo en que el LED cambió
// de estado por última vez es mayor que el intervalo.
if (currentMillis - previousMillis > interval){

// Si se cumple la condición se guarda el nuevo tiempo
// en el que el LED cambia de estado
previousMillis = currentMillis;

// Y ahora cambiamos de estado el LED, si está encendido a
// apagado o viceversa.
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

} else {
digitalWrite(ledPin, LOW); // apaga el LED

}


{
val = analogRead(analogPin0); // captura el pin de entrada
if (val >= threshold) {   // save the last time you blinked the LED 
    previousMillis1 = currentMillis1;   

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

    // set the LED with the ledState of the variable:
  
    digitalWrite(ledPin1, ledState1);
} else {
digitalWrite(ledPin1, LOW); // apaga el LED
}

}

}
}

Saludos y perdonar pero por mas que leo, sigo ejemplos y leo, no se muy bien como integrarlo.

Hubiera deseado que postearas el código con delay porque realmente no entiendo bien lo que quisiste hacer pero poniendo la mejor voluntad intentaré ayudarte:

Trata de describir mejor tu objetivo: Mucha explicación y nada en concreto.
Simplemente debes decir. Voy a hacer una alarma, con la sirena en el pin X. Un led debe estar encendido T1 y otro led T2, se acccionan como respuesta a Evento1 y Evento2. y bla bla bla.

De tu explicación no surge nada, y uno termina intentando entenderlo de tu código, el cual esta alterado con errores de funcionamiento.

Asi que veamos tu código modificado

Lo primero que encuentro es que no definiste el pin de salida para LedPin1

pinMode(ledPin1, OUTPUT);

Me llama la atención que ambos led se disparen al superar el mismo umbral de disparo threshold = 512
en todo caso define un segundo umbral threshold1 aunque se le asigne el mismo valor.

No se si hace lo que desesas, tampoco lo probé asi que tu me dirás.

const byte ledPin0 = 13; // LED conectado a pin digital 13
const byte ledPin1 = 12;
const byte analogPin1 = 1; // Entrada de señal sensor 2
const byte analogPin0 = 0; // potentiómetro conectado a pin analógico 3
int val = 0; // variable para almacenar el valor capturado
int threshold0 = 512; // valor de disparo o umbral (1024/2)
int threshold1 = 512; // valor de disparo o umbral (1024/2)
int ledState0 = LOW; 
int ledState1 = LOW;  


const long interval0 = 300;         // interval at which to blink (milliseconds)
const long interval1 = 200;         // interval at which to blink (milliseconds)

unsigned long startMillis0 = 0;     
unsigned int  timerLed0 = 0;
unsigned long startMillis1 = 0;
unsigned int  timerLed1 = 0;




void setup() {
 pinMode(ledPin0, OUTPUT); // asigna modo salida el pin digital 13
 pinMode(ledPin1, OUTPUT);
 startMillis0 = millis();
 startMillis1 = millis();
}
void loop() {


 val = analogRead(analogPin0); // captura el pin de entrada
 
 if (val >= threshold0) {
 
 // se comprueba si el tiempo actual menos el tiempo en que el LED cambió
 // de estado por última vez es mayor que el intervalo.
 if (millis() - startMillis0 > interval0){

 // Si se cumple la condición se guarda el nuevo tiempo
 // en el que el LED cambia de estado
 startMillis0 = millis();

 // Y ahora cambiamos de estado el LED, si está encendido a
 // apagado o viceversa.
 if (ledState0 == LOW)
 ledState0 = HIGH;
 else
 ledState0 = LOW;

 } 
 }

    if (ledState0 == HIGH) 
     digitalWrite(ledPin0, HIGH);
    else 
       digitalWrite(ledPin0, LOW);
    
 
    // Sensor 2
 val = analogRead(analogPin1); // captura el pin de entrada
 
 if (val >= threshold1) {
 
 // se comprueba si el tiempo actual menos el tiempo en que el LED cambió
 // de estado por última vez es mayor que el intervalo.
 if (millis() - startMillis1 > interval1){

 // Si se cumple la condición se guarda el nuevo tiempo
 // en el que el LED cambia de estado
 startMillis1 = millis();

 // Y ahora cambiamos de estado el LED, si está encendido a
 // apagado o viceversa.
 if (ledState1 == LOW)
 ledState1 = HIGH;
 else
 ledState1 = LOW;

 } 
 }

    if (ledState1 == HIGH) 
     digitalWrite(ledPin1, HIGH);
    else 
       digitalWrite(ledPin1, LOW);
    
}

Algunos cambios son estéticos, otros son de buen uso de variables, y finalmente el mas importante y lo explico para un led ya que el otro es similar.

en el setup() inicializo

startMillis0 = millis();

y no importa cuando se de la condicion en que superes el umbral, siempre arrancará el timer usando millis() y luego se cumple cada intervalo.
Dentro de el cambiamos las variables LedStatus0 a ON y OFF y por fuera lo hacemos con los LEDs, eso realmente es poco eficiente pero lo tenias asi y lo mantuve, puedes eliminar todo eso con esta instrucción en lugar de todo esto

// Y ahora cambiamos de estado el LED, si está encendido a
 // apagado o viceversa.
 if (ledState0 == LOW)
 ledState0 = HIGH;
 else
 ledState0 = LOW;

 } 
 }

    if (ledState0 == HIGH) 
     digitalWrite(ledPin0, HIGH);
    else 
       digitalWrite(ledPin0, LOW);

y lo reemplazas por esto

// Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
digitalWrite(ledPin0, !digitalRead(ledPin0));

Buenas, perdona por explicarme tan mal, la idea es que tengo 2 sensores en el pin 1 y 2 que activa una sirena en el pin 13.

Quiero darle mas funciones pero claro usando delay como se para el codigo cuando llega a esa linea no puedo hacer que lea mas sensores que quiero añadir.

Gracias por tu ayuda, en un rato miro el codigo que me has enviado y modificado a ver si lo consigo entender.

Te pongo el codigo con delay

int ledPin = 13; // LED conectado a pin digital 13
int analogPin1 = 1; // Entrada de señal sensor 2
int analogPin0 = 0; // Entrada de señal sensor 1
int val = 0; // variable para almacenar el valor capturado
int threshold = 512; // valor de disparo o umbral (1024/2)
void setup() {
  delay(30000);
pinMode(ledPin, OUTPUT); // asigna modo salida el pin digital 13
}
void loop() {

val = analogRead(analogPin1); // captura el pin de entrada
if (val >= threshold) {
digitalWrite(ledPin, HIGH); // enciende el LED
delay(60000);
} else {
digitalWrite(ledPin, LOW); // apaga el LED

}


{
val = analogRead(analogPin0); // captura el pin de entrada
if (val >= threshold) {
digitalWrite(ledPin, HIGH); // enciende el LED
delay(60000);
} else {
digitalWrite(ledPin, LOW); // apaga el LED
}

}

}

Saludos y gracias

De nuevo mal explicado.

Dices tengo dos sensores (que sensores?) que activan una sirena, cuando lo hacen?
En tu ejemplo tienes LedPin0 = 13 y LedPin1 = 12; o sea dos sirenas?

Que sensor tienes que activa una entrada analógica, temperatura, humedad?

Define bien tu proyecto porque no se puede encarar la programación sin tener bien definido que se quiere hacer.
Entiende que no te presiono, solo intento ayudar pero si no lo comprendemos no podemos ayudarte.

Buenas, el codigo inicial estaba puesto solo para usar una sirena, quiero usar una alerta luminosa como primer aviso y luego que salte la sirena al activarse un sensor por segunda vez.

Los sensores son de vibracion SW-420.

Se que hacer que cuente las veces que salta cada sensor y realice una tarea difenrente es mas complicado que lo que tengo realizado, pero el primer paso es conseguir quitar los delay

No entiendo muy bien como me dices que puedo hacer el codigo mas eficiente, la verdad que lo que aprendido es mirando manuales y realizando y entendiendo ejemplos, pero aun me queda mucho por aprender

Saludos y gracias

Tu sensor de vibración lo tienes en módulo o solo el sensor?

Te pregunto porque este sensor tiene una salida digital, no analógica pero no se si lo venden sin el módulo que se ve en la figura.

El sensor es con el modulo, exactamente ese mismo que has puesto. Entonces si lo conecto a entradas digitales tendría mejor resultados? aunque de esta forma funciona muy bien en tema de sensibilidad.

Mejor resultado no. El delay no cambia, pero no usas una entrada analógica donde no se debe.

Yo sinceramente no puedo creer que llevemos 6 post y aun no hayamos definido correctamente lo que se quiere hacer o soy yo.
Establecido que tus sensores de vibración actúan como pulsadores, tienes dos retardos, Intervalo1 y 2.
Quieres que los leds parpadeen? Te he pedido una explicación y solo esporádicamente lo mencionas en el primer post.

entonces S1 dispara un parpadeo a un ritmo T1 y S2 lo hace a un ritmo T2.
Donde entra la sirena no entiendo?

A ver si esto funciona. Falta la sirena que no se que relación tiene con S1 y S2.

const byte ledPinS1		= 13; // LED conectado a pin digital 13
const byte ledPinS2 	= 12;  // LED conectado a pin digital 12
const byte S1Pin 		= 2; // Entrada de señal sensor 1
const byte S2Pin	 	= 3; // Entrada de señal sensor 2
unsigned int S1         = LOW;
unsigned int S2  		= LOW;  


const long interval0 	= 300;         // interval at which to blink (milliseconds)
const long interval1 	= 200;         // interval at which to blink (milliseconds)

unsigned long startMillis0 	= 0;     
unsigned long startMillis1 	= 0;

void setup() {
	pinMode(ledPinS1, OUTPUT); // asigna modo salida el pin digital 13
	pinMode(ledPinS2, OUTPUT);
	startMillis0 = millis();
	startMillis1 = millis();
}
void loop() {

	// Sensor 1
	S1 = digitalRead(S1Pin); // captura el pin de entrada
	
	if (S1 == HIGH) {
		
		// se comprueba si el tiempo actual menos el tiempo en que el LED cambió
		// de estado por última vez es mayor que el intervalo.
		if (millis() - startMillis0 > interval0){

			// Si se cumple la condición se guarda el nuevo tiempo
			// en el que el LED cambia de estado
			startMillis0 = millis();

			// Y ahora cambiamos de estado el LED, si está encendido a
			// apagado o viceversa.
			digitalWrite(ledPinS1, !digitalRead(ledPinS1));

		} 
	}
  
	
    // Sensor 2
	S2 = digitalRead(S2); // captura el pin de entrada
	
	if (S2 == HIGH) {
		
		// se comprueba si el tiempo actual menos el tiempo en que el LED cambió
		// de estado por última vez es mayor que el intervalo.
		if (millis() - startMillis1 > interval1){

			// Si se cumple la condición se guarda el nuevo tiempo
			// en el que el LED cambia de estado
			startMillis1 = millis();

			// Y ahora cambiamos de estado el LED, si está encendido a
			// apagado o viceversa.
			digitalWrite(ledPinS2, !digitalRead(ledPinS2));
		} 
	}  
}

Buenas, el sensor hace de pulsador cuando se activa, el codigo original en el que aparece delay solo hay un led que es donde coloco la alarma, el problema es que no podía seguir con el proyecto porque se paraba el codigo.

La intencion es de relizar una alarma con sensores de vibracion en la paredes para evitar robo por butron, sensores pir, añadir un mando a distancia, comunicación con un tlf movil el cual ya tengo el cable para avisar del disparo de la alarma, pero claro, va poco a poco y realizando pruebas.

ya que quiero añadir para activar o desactivar un modulo IRFID. pero como no tengo los conocimientos suficientes pues voy poco a poco.

El funcionamiento actual con delay es un breve retardo para activar la alamar y luego al saltar un sensor directamente salta la sirena, pero claro quiero hacerlo bien, el poner que avise antes de saltar la sirena mediante luces, por eso al intentar quitar delay añadi otro led, ya que de momento estoy probando con led y no montando el sistema de la forma que se quedara.

Saludos y gracias

Guau bueno... yo me detengo aquí.
Lo que te hice tiene que parpadear cuando los sensores de vibración se activan.
Pruebalo y luego vemos.

Muchas gracias compañero, no he podido probarlo aun, este finde le daré mucha caña, si que es un gran proyecto para los conocimientos que tengo y por eso tengo que ir poco a poco.

Saludos y muchas gracias

Bien. Igualmente recuerda algo. Es importante que siempre entregues la mayor explicación posible para que los demás podamos entender que es lo que deseas hacer.

Escribelo y léelo antes de darle ENVIAR. Si tu lo entiendes al leerlo nosotros también, pero recuerda que tu manejas toda la idea y no pueden quedar cabos sueltos.

Tienes toda la razón compañero, usando el primer código que me pusiste funciona en el momento de activarse, pero no se desactiva después al no ser que se vuelva activar el sensor de nuevo, por lo que no responde al tiempo que se le pone.

Usando el segundo código he visto que usas los pines digitales, en esta ocasión ocurre lo mismo con la diferencia que el led conectado a pin 12 no responde a ningún sensor y parpadea sin parar, el led del pin 13 si responde a los sensores lo único que no se desactiva solo hasta que no se activa el sensor de nuevo.

Voy a jugar e intentar entender como funciona a ver si consigo solucionarlo yo, ya que lo que necesito es ir aprendiendo no que me lo solucionen jejejeje.

Alguien me podría poner un ejemplo de que al activar un sensor en el pin que sea, ser active una salida durante un tiempo establecido y después se desactive solo para ver si así lo puedo entender e implementarlo a mi proyecto.

Saludos y gracias

Buenas, he encontrado un codigo el cual he modificado y he conseguido que funcione de manera que cuando se activa el sensor de vibración en el pin digital 3 se activa el led del pin 13.

#define led 13
#define sensor 3
boolean pulsador;
unsigned long tiempo;
const long interval = 3000; 
void setup()
{
  pinMode(led, OUTPUT);
  pinMode(sensor, INPUT);
}
void loop()
{
  pulsador=digitalRead(sensor);
  if(pulsador == HIGH)
{
  tiempo = millis()+interval;
  digitalWrite(led,HIGH);
}
if (tiempo == millis())
{
digitalWrite(led,LOW);
tiempo=0;
}
}

Aun no entiendo muy bien como funciona y si es la mejor forma de hacerlo, pero al usar una entrada digital piendo la posibilidad de poder regular desde el programa la sensibilidad verdad?

Saludos

Ahora al duplicar el condigo para usarlo con 2 sensores y 2 sirenas diferentes me da el siguiente error:

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows XP), Board: "Arduino Uno"
sketch_feb10b.ino: In function 'void setup()':
sketch_feb10b:14: error: expected `;' before 'pinMode'
sketch_feb10b:16: error: 'led1' was not declared in this scope
sketch_feb10b.ino: In function 'void loop()':
sketch_feb10b:37: error: 'led1' was not declared in this scope
sketch_feb10b:41: error: 'led1' was not declared in this scope

Aqui el codigo, no se porque da ese error, cuando con un solo sensor y una sola sirena si funciona

#define led 13
#define led 12
#define sensor 3
#define sensor1 4
boolean pulsador;
boolean pulsador1;
unsigned long tiempo;
unsigned long tiempo1;
const long interval = 3000; 
const long interval1 = 3000; 
void setup(){
  delay(6000)
  
  pinMode(led, OUTPUT);
  pinMode(sensor, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(sensor1, INPUT);
}
void loop()
{
  pulsador=digitalRead(sensor);
  if(pulsador == HIGH)
{
  tiempo = millis()+interval;
  digitalWrite(led,HIGH);
}
if (tiempo == millis())
{
digitalWrite(led,LOW);
tiempo=0;
}

pulsador1=digitalRead(sensor1);
  if(pulsador1 == HIGH)
{
  tiempo = millis()+interval1;
  digitalWrite(led1,HIGH);
}
if (tiempo1 == millis())
{
digitalWrite(led1,LOW);
tiempo1=0;
}

}

Acá esta corregido.

#define led1 12
#define led2 13
#define sensor1 3
#define sensor2 4
boolean pulsador1;
boolean pulsador2;
unsigned long tiempo1;
unsigned long tiempo2;
const long interval1 = 3000; 
const long interval2 = 3000; 

void setup(){
	delay(6000)

	pinMode(led1, OUTPUT);
	pinMode(sensor1, INPUT);
	pinMode(led2, OUTPUT);
	pinMode(sensor2, INPUT);
}
void loop()
{
	pulsador1 = digitalRead(sensor1);
	
	if(pulsador1 == HIGH) 	{
		tiempo1 = millis();
		digitalWrite(led1,HIGH);
	}
	
	if (millis()-tiempo1 > interval1) 	{
		digitalWrite(led,LOW);
		tiempo=0;
	}
	
	pulsador2 = digitalRead(sensor2);
	
	if(pulsador2 == HIGH) 	{
		tiempo2 = millis();
		digitalWrite(led1,HIGH);
	}
	
	if (millis()-tiempo2 > interval2) 	{
		digitalWrite(led,LOW);
	}
}

Debes aprender a interpretar que te dice el compilador:

error: 'led1' was not declared in this scope

o sea.. copiaste dos veces led y led pero nunca definiste led1.

Ahora esta resuelto pero ese era tu primero error. Habia varios mas.

Buenas compañero, me siguen saliendo códigos de error y no se como solucionarlo porque según miro están declarados...

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows XP), Board: "Arduino Uno"
sketch_feb10c.ino: In function 'void setup()':
sketch_feb10c:15: error: expected `;' before 'pinMode'
sketch_feb10c.ino: In function 'void loop()':
sketch_feb10c:30: error: 'led' was not declared in this scope
sketch_feb10c:31: error: 'tiempo' was not declared in this scope
sketch_feb10c:42: error: 'led' was not declared in this scope

Aun así he conseguido que funcione con otro código que he adaptado dejando una sola salida de disparo, ya que solo tendrá una sirena.

Este es el que utilizo al final

#define led 13
#define sensor 3
#define sensor1 4
boolean pulsador;
boolean pulsador1;
unsigned long tiempo;
const long interval = 3000; 
void setup()
{
  delay(30000);
  pinMode(led, OUTPUT);
  pinMode(sensor, INPUT);
  pinMode(sensor1, INPUT);
}
void loop()
{
  pulsador=digitalRead(sensor);
  if(pulsador == HIGH)
   
{
  tiempo = millis()+interval;
  digitalWrite(led,HIGH);
}
if (tiempo == millis())
{
digitalWrite(led,LOW);
tiempo=0;
}
pulsador1=digitalRead(sensor1);
  if(pulsador1 == HIGH)
   
{
  tiempo = millis()+interval;
  digitalWrite(led,HIGH);
}
if (tiempo == millis())
{
digitalWrite(led,LOW);
tiempo=0;
}

}

no entiendo muy bien aun el funcionamiento de millis ya que cada ejemplo que pillo es diferente para hacer una misma cosa, pero poco a poco jejejeje

Y donde esta mi codigo? Usaste de nuevo el tuyo

Use el código que usted me ha proporcionado.

#define led1 12
#define led2 13
#define sensor1 3
#define sensor2 4
boolean pulsador1;
boolean pulsador2;
unsigned long tiempo1;
unsigned long tiempo2;
const long interval1 = 3000; 
const long interval2 = 3000; 

void setup(){
 delay(6000)

 pinMode(led1, OUTPUT);
 pinMode(sensor1, INPUT);
 pinMode(led2, OUTPUT);
 pinMode(sensor2, INPUT);
}
void loop()
{
 pulsador1 = digitalRead(sensor1);
 
 if(pulsador1 == HIGH) {
 tiempo1 = millis();
 digitalWrite(led1,HIGH);
 }
 
 if (millis()-tiempo1 > interval1) {
 digitalWrite(led,LOW);
 tiempo=0;
 }
 
 pulsador2 = digitalRead(sensor2);
 
 if(pulsador2 == HIGH) {
 tiempo2 = millis();
 digitalWrite(led1,HIGH);
 }
 
 if (millis()-tiempo2 > interval2) {
 digitalWrite(led,LOW);
 }
}

voy a crear un post en proyectos para explicar lo que quiero hacer con todo detalle de manera que estara todo junto y sera de mayor utilidad a otros usuarios.