Ok. No había entendido entonces tu problema.
Prueba a ver con este otro código como base. He intentado comentarlo profusamente a ver si resulta comprensible el funcionamiento buscado y tal vez falte algún fleco, pero creo que se aproxima.
const int LED = 4; //pin del LED
const int LEDSUBE = 5; //pin del LED motor subiendo
const int LEDBAJA = 6; //pin del LED motor bajando
const int PULSADORLUZ = 7; // pin pulsadorLUZ
const int PULSADORUP = 8; // pin pulsador subida
const int PULSADORDOWN = 9; // pin pulsador bajada
const int FINCARRERAUP = 2; // pin FC subida
const int FINCARRERADOWN = 3; // pin FC bajada
const int LDR = A0; // pin sensor LDR
int ultimoEstadoPulsadorLuz=LOW, ultimoEstadoPulsadorDown=LOW, ultimoEstadoPulsadorUp=LOW;
int nuevoEstadoPulsadorLuz=LOW, nuevoEstadoPulsadorDown=LOW, nuevoEstadoPulsadorUp=LOW;
int estadoFinCarreraUp, estadoFinCarreraDown;
enum { DIA, NOCHE, DESCONOCIDO} estadoLDR = DESCONOCIDO;
void setup(){
// Salidas de luz y motores de persiana
pinMode(LED,OUTPUT);
digitalWrite(LED, LOW);
pinMode(LEDSUBE,OUTPUT);
pinMode(LEDBAJA,OUTPUT);
digitalWrite(LEDSUBE, LOW);
digitalWrite(LEDBAJA, LOW);
// Entradas botones manuales de luz y persiana
pinMode(PULSADORLUZ,INPUT);
pinMode(PULSADORUP,INPUT);
pinMode(PULSADORDOWN,INPUT);
// Entradas finales de carrera
pinMode(FINCARRERAUP,INPUT); // y FC subida como señal de entrada
pinMode(FINCARRERADOWN,INPUT); // y FC bajada como señal de entrada
Serial.begin(9600);
}
void loop() {
switch(estadoLDR) {
case DIA:
if (analogRead(LDR) < 200) { // si baja la luz
baja();
estadoLDR = NOCHE;
}
break;
case NOCHE:
if (analogRead(LDR) > 300) { // podemos dejar un tramo de histéresis entre subida y bajada
sube();
estadoLDR = DIA;
}
break;
default: // por descarte, DESCONOCIDO
if (analogRead(LDR) > 300) {
sube();
estadoLDR = DIA;
}
else {
baja();
estadoLDR = NOCHE;
}
}
// LECTURA DE INTERRUPTORES Y FINALES DE CARRERA
estadoFinCarreraDown=digitalRead(FINCARRERADOWN);
estadoFinCarreraUp=digitalRead(FINCARRERAUP);
nuevoEstadoPulsadorLuz = digitalRead(PULSADORLUZ);
nuevoEstadoPulsadorUp = digitalRead(PULSADORUP);
nuevoEstadoPulsadorDown = digitalRead(PULSADORDOWN);
// Si se detecta final de carrera paramos.
if (estadoFinCarreraUp) {
digitalWrite(LEDSUBE, LOW);
digitalWrite(LED, LOW); // apagamos la luz al terminar de subir
}
if (estadoFinCarreraDown) {
digitalWrite(LEDBAJA, LOW);
}
// independientemente de lo que hagamos en el switch actuamos sobre el cambio en estado interruptor
if (ultimoEstadoPulsadorLuz != nuevoEstadoPulsadorLuz) {
ultimoEstadoPulsadorLuz = nuevoEstadoPulsadorLuz;
// Si el interruptor pasa de OFF a ON, hacemos el switch de la luz
if (nuevoEstadoPulsadorLuz) {
digitalWrite(LED, !digitalRead(LED));
}
}
// independientemente de la máquina de estados trabajamos los cambios de estado en pulsadores de persiana.
if (ultimoEstadoPulsadorUp != nuevoEstadoPulsadorUp) {
ultimoEstadoPulsadorUp = nuevoEstadoPulsadorUp;
// Si iniciamos pulsación y no es final de carrera, subimos
if (nuevoEstadoPulsadorUp && !estadoFinCarreraUp) {
sube();
}
// Al soltar pulsador, para en cualquier punto
else {
digitalWrite(LEDSUBE, LOW);
}
}
// con el else, evitamos responder a los dos pulsadores (tendría preferencia el up)
else if (ultimoEstadoPulsadorDown != nuevoEstadoPulsadorDown) {
ultimoEstadoPulsadorDown = nuevoEstadoPulsadorDown;
// Si iniciamos pulsación y no es final de carrera, subimos
if (nuevoEstadoPulsadorDown && !estadoFinCarreraDown) {
baja();
}
// Al soltar pulsador, para en cualquier punto
else {
digitalWrite(LEDBAJA, LOW);
}
}
}
void baja()
{
digitalWrite(LEDSUBE, LOW); // Aseguramos no encender los dos motores simultáneamente
digitalWrite(LEDBAJA, HIGH); // iniciamos bajada de persiana
digitalWrite(LED, HIGH); // encendemos la luz antes de bajar del todo
}
void sube()
{
digitalWrite(LEDBAJA, LOW); // Aseguramos no encender los dos motores simultáneamente
digitalWrite(LEDSUBE, HIGH); // iniciamos subida de persiana
}