Cambiar función de un led al pulsar un botón

Buenas noches!

Estoy con un proyecto el cual requiere cambiar la actividad de un led en función de unos sensores.

Control tres sensores:

  • LDR (Para la luz)
  • CNY70 (Para detectar si una puerta esta cerrada)
  • Servo (Para detectar si esta puesto el cerrojo)

Estas son las situaciones posibles:

//SITUACIONES POSIBLES:
// 2 NO HAY LUZ + PUERTA CERRADA + CERROJO PUESTO = Luz parpadeando lento y se puede pulsar botón para abrir cerrojo.
// 3 NO HAY LUZ + PUERTA CERRADA + SIN CERROJO = Luz parpadeando rápido y se puede pulsar botón para cerrar O Esperar 10 segundos y cerrar cerrojo
// 4 NO HAY LUZ + PUERTA ABIERTA + SIN CERROJO = Luz fija.

// 5 SI HAY LUZ + PUERTA ABIERTA + SIN CERROJO = Luz fija
// 6 SI HAY LUZ + PUERTA CERRADA + SIN CERROJO = Luz parpadeando rápido y se puede pulsar botón para cerrar O Esperar 10 segundos y cerrar cerrojo
// 1 SI HAY LUZ + PUERTA CERRADA + CERROJO PUESTO = No hacer nada

He realizado 4 funciones para el led:

  • Apagado
  • Encendido
  • Parpadeo lento
  • Parpadeo rápido

He probado sin incorporar la función del pulsador y funciona correctamen el proble viene cuando incorporo la función del pulsador:

void Pulsador()
{
if (digitalRead(buttonPin)==HIGH)
{
contador++;
//Esperar a que se suelte el pulsador
while (digitalRead(buttonPin)==HIGH )
{
delay(10);
}
if (digitalRead(buttonPin)==LOW)
{
if (contador == 1)
{
posicion=90;
myservo.write(posicion);
delay(15);
}
if (contador == 2)
{
posicion=0;
myservo.write(posicion);
delay(15);
contador=0;
}
//Serial.println("Pulsacion ");
//Serial.println(contador);
}
}

}

Tengo realizadas las funciones con Millis pero solo funcionan cuando mantengo pulsado el pulsador.

¿Sugerencias?

Espero vuestra ayuda.

Un saludo!

Sube el sketch completo ,porque la lectura del pulsador la tienes dentro de una funcion que no se sabe cuando ni como se la llama....

MatuScien:

  • Servo (Para detectar si esta puesto el cerrojo)

El servo no te dira si esta puesto un cerrojo o no, igual te refieres a echar el cerrojo? o es que necesitas otro sensor

Las situaciones que has resuelto, las has conseguido en base a delay, mientras tanto te pierdes eventos o demoras en responder a los mismos.
Divide tu programa en estas situaciones.

  1. Generar cada respuesta de los leds y considera usar millis() en lugar de delay.
    Estudia el ejemplo BlinkWithoutDelay.ino en los ejemplos.

  2. Lee todos los sensores y actúa en consecuencia.

Arma una tabla de verdad con tus situaciones como entradas y genera la salida que corresponda.

// 1 SI HAY LUZ + PUERTA CERRADA + CERROJO PUESTO = No hacer nada
// 2 NO HAY LUZ + PUERTA CERRADA + CERROJO PUESTO Luz parpadeando lento y se puede pulsar botón para abrir cerrojo.
// 3 NO HAY LUZ + PUERTA CERRADA + SIN CERROJO = Luz parpadeando rápido y se puede pulsar botón para cerrar O Esperar 10 segundos y cerrar cerrojo
// 4 NO HAY LUZ + PUERTA ABIERTA + SIN CERROJO = Luz fija.
// 5 SI HAY LUZ + PUERTA ABIERTA + SIN CERROJO = Luz fija
// 6 SI HAY LUZ + PUERTA CERRADA + SIN CERROJO = Luz parpadeando rápido y se puede pulsar botón para cerrar O Esperar 10 segundos y cerrar cerrojo

LUZ PUERTA CERRADA CERROJO Abrir Cerrojo Salida
1 1 1 Nada
0 1 1 Habiliitado Luz LENTO
0 1 0 Habiliitado Luz RAPIDO
y asi

Buenas chicos!

Gracias por responder tan pronto!

Os voy a poner el código entero así podéis visualizarlo mejor.

He realizado algunos cambio con las funciones de las luces, ya no es Led_Lento y Led_Rapido, solo hay Led_Fade

Ya me decís algo.

Gracias!!

[/
#include <Servo.h>

//SERVO
Servo myservo;
int posicion=0; // Posición inicial del servo

//PULSADOR
const int buttonPin = 2; // El número del pin, entrada del pulsador
int contador=0;

//LED
const int ledPin = 13; // El número del pin, salida al LED

int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;

//LDR
int LDR_pin = 0; //Leeremos del pin 0
int LDR_val = 0; //Variable para leer los datos del LDR

//CNY70
int pinReceptor = A2; //Guardamos en esta variable el pin Analógico
int sensorVal; //Variable del sensor

void setup() {
digitalWrite(13, LOW);
myservo.attach(9);
myservo.write(posicion); // Ponemos el servo en la posicion inicial (0 Grados)
pinMode(buttonPin, INPUT); // Inicializa el pin 2 como pin de entrada
pinMode(ledPin, OUTPUT); // Inicializa el pin 13 como pin de salida
Serial.begin(9600); // Inicializa la comunicación serial
currentTime = millis();
loopTime = currentTime;
}

//SITUACIONES POSIBLES:

// 1 SI HAY LUZ + PUERTA CERRADA + CERROJO PUESTO = Led fijo
// 2 NO HAY LUZ + PUERTA CERRADA + CERROJO PUESTO = Led FADE y se puede pulsar boton para abrir cerrojo.
// 3 NO HAY LUZ + PUERTA CERRADA + SIN CERROJO = Led fijo y se puede pulsar boton para cerrar O Esperar 10 segundos y cerrar cerrojo
// 4 NO HAY LUZ + PUERTA ABIERTA + SIN CERROJO = Led fijo.

// 5 SI HAY LUZ + PUERTA ABIERTA + SIN CERROJO = Led fijo
// 6 SI HAY LUZ + PUERTA CERRADA + SIN CERROJO = Led FADE y se puede pulsar boton para cerrar O Esperar 10 segundos y cerrar cerrojo
// 99 SITAUCION FALLO NO PUEDE DARSE EL CASO.

void Led_Apagado()
{
digitalWrite(ledPin, LOW);
}

void Led_Fijo()
{
digitalWrite(ledPin, HIGH);
}

void Led_Fade()
{
currentTime = millis();
if(currentTime >= (loopTime + 20)){
// set the brightness of pin 9:
analogWrite(9, brightness);

// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;

// reverse the direction of the fading at the ends of the fade:
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
loopTime = currentTime; // Updates loopTime
}
// Other processing can be done here

}

void Pulsador()
{
if (digitalRead(buttonPin)==HIGH)
{
contador++;
//Esperar a que se suelte el pulsador
while (digitalRead(buttonPin)==HIGH )
{
delay(10);
}
if (digitalRead(buttonPin)==LOW)
{
if (contador == 1)
{
posicion=90;
myservo.write(posicion);
delay(15);
}
if (contador == 2)
{
posicion=0;
myservo.write(posicion);
delay(15);
contador=0;
}
}
}
}

void loop() {

//Serial.println(posicion);
//Serial.println(LDR_val);
//Serial.println(sensorVal);
//Serial.println("Pulsacion ");
//Serial.println(contador);

LDR_val = analogRead(LDR_pin);
sensorVal = analogRead(pinReceptor);

if ((LDR_val<10))
{
if((sensorVal>100)) // PUERTA CERRADA
{
if((posicion==0))
{

// LUZ (APAGADA)
// PUERTA (CERRADA)
// CERROJO (ACTIVADO)
// Situacion = 2;

Led_Fade();
Pulsador();

}
else
{
// LUZ (APAGADA)
// PUERTA (CERRADA)
// CERROJO (DESACTIVADO)
// Situacion = 3;

Led_Fijo();
Pulsador();
}
} // FIN CONTROL PUERTA (CERRADA)
else //PUERTA ABIERTA
{
if((posicion==0))
{
// LUZ (APAGADA)
// PUERTA (ABIERTA)
// CERROJO (ACTIVADO)
// Situacion = 99;

contador=0;
Led_Apagado();
}
else
{
// LUZ (APAGADA)
// PUERTA (ABIERTA)
// CERROJO (DESACTIVADO)
// Situacion = 4;
contador=0;
Led_Fijo();
}
} // FIN CONTROL DE PUERTA (ABIERTA)
} // FIN DE CONTROL DE LUZ (APAGADA)
else
{
if((sensorVal<100))
{
if((posicion==0))
{
// LUZ (ENCENDIDA)
// PUERTA (ABIERTA)
// CERROJO (ACTIVADO)
// Situacion = 99;

contador=0;
Led_Apagado();
}
else
{
// LUZ (ENCENDIDA)
// PUERTA (ABIERTA)
// CERROJO (DESACTIVADO)
// Situacion = 5;

contador=0;
Led_Fijo();

}
}
else
{
if((posicion==0))
{
// LUZ (ENCENDIDA)
// PUERTA (CERRADA)
// CERROJO (ACTIVADO)
// Situacion = 1;

contador=0;
Led_Apagado();

}
else
{
// LUZ (ENCENDIDA)
// PUERTA (CERRADA)
// CERROJO (DESACTIVADO)
// Situacion = 6;

Led_Fijo();
Pulsador();

}
}
} // FIN CONTROL DE LUZ (ENCENDIDA)
}

quote]

solo es una sugerencia pero yo pondria la lectura del pulsador en el loop principal
una libreria como esta
http://www.avdweb.nl/arduino/hardware-interfacing/simple-switch-debouncer.html

no usa delays por lo que el codigo ira mas rapido (mas sensibilidad al toque del pulsador)

void loop(){

if(digital.Read pulsador == HIGH)
{
pulso++
}
}

de esta manera siempre lees el pulsador, solo agregas un "roll over" en caso de que quieras que comience de 0 cuando llegue a cierto numero de casos...

if( pulsa > numCasos) pulsa = 0;

Y en tu subrutina de pulsador... lees la variable y lanzas la subrutina que necesites.

-Alex.