Hola.
Presumiblemente lo que te ocurre es que estás actuando constantemente sobre la luz, por ejemplo, encendiendo o apagando siempre que el LDR esté por encima o debajo de un valor, en lugar de sólo cuando se produzca el salto de condición. Por ello, aunque la actives manualmente, en el siguiente loop se establece de nuevo según el valor del LDR.
Esto es una máquina de estados. El meollo de la misma es el switch que se evalúa en cada loop. Dependiendo del estado de la máquina, se verifican unas condiciones, y se realizan determinadas acciones, entre las que está el cambiar dicho estado. En esos cambios, precisamente, actuamos sobre los distintos led, una sola vez.
Fuera de la máquina de estados, sencillamente trabajamos el interruptor de forma independiente, con lo que permanecerá en dicho estado hasta que vuelva a haber un cambio de estado en la máquina.
/* Use File->Load Prog to
load a different Program
*/
//boton pulsador
const int LED =8; //pin del LED
const int LEDSUBE =4; //pin del LED motor subiendo
const int LEDBAJA =5; //pin del LED motor bajando
const int PULSADOR = 7; // pin pulsador
const int FINCARRERAUP = 2; // pin FC subida
const int FINCARRERADOWN = 3; // pin FC bajada
const int LDR = A0; // pin sensor LDR
int ultimoEstadoPulsador=LOW;
enum { SUBIENDO, ARRIBA, BAJANDO, ABAJO, DESCONOCIDO} estadoPersiana = DESCONOCIDO;
void setup(){
pinMode(LED,OUTPUT); // establecer que el pin digital es una señal de salida
digitalWrite(LED, LOW);
pinMode(LEDSUBE,OUTPUT); // establecer que el pin digital es una señal de salida
digitalWrite(LEDSUBE, LOW);
pinMode(LEDBAJA,OUTPUT); // establecer que el pin digital es una señal de salida
digitalWrite(LEDBAJA, LOW);
pinMode(PULSADOR,INPUT); // y BOTON como señal de entrada
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(estadoPersiana) {
case SUBIENDO:
if (digitalRead(FINCARRERAUP)) { // si la persiana abre del todo
digitalWrite(LEDSUBE, LOW); // detenemos subida
digitalWrite(LED, LOW); // apagamos la luz cuando ha terminado de subir
estadoPersiana = ARRIBA;
}
break;
case BAJANDO:
if (digitalRead(FINCARRERADOWN)) { // si la persiana cierra del todo
digitalWrite(LEDBAJA, LOW); // detenemos bajada
estadoPersiana = ABAJO;
}
break;
case ARRIBA:
if (analogRead(LDR) < 200) { // si baja la luz
baja();
}
break;
case ABAJO:
if (analogRead(LDR) > 300) { // podemos dejar un tramo de histéresis entre subida y bajada
sube();
}
break;
default: // por descarte, DESCONOCIDO
if (analogRead(LDR) > 300)
sube();
else
baja();
}
// independientemente de lo que hagamos en el switch actuamos sobre el interruptor
if (ultimoEstadoPulsador!= digitalRead(PULSADOR)) {
ultimoEstadoPulsador = !ultimoEstadoPulsador;
if (ultimoEstadoPulsador) {
digitalWrite(LED, !digitalRead(LED));
}
}
}
void baja()
{
digitalWrite(LEDBAJA, HIGH); // iniciamos bajada de persiana
digitalWrite(LED, HIGH); // encendemos la luz antes de bajar del todo
estadoPersiana = BAJANDO;
}
void sube()
{
digitalWrite(LEDSUBE, HIGH); // iniciamos subida de persiana
estadoPersiana = SUBIENDO;
}
No está totalmente probado, aunque creo que se aproxima a lo que buscas. Lo importante es que seas capaz de comprender el funcionamiento.
Saludos.