Go Down

Topic: Proyecto control de persianas automatizadas (Read 1 time) previous topic - next topic

ivitito

Vale pues con un igual la situación es que hace caso al sensor pero que no funciona el pulsador.
Te pego todo el codigo de nuevo que tengo ahora mismo.

Code: [Select]

//boton pulsador
const int LED =8; //pin del LED
const int LEDsubir =4; //pin del LED motor subiendo
const int LEDbajar =5; //pin del LED motor bajando

const int BOTON = 7; // pin pulsador

const int FCsubir = 2; // pin FC subida
const int FCbajar = 3; // pin FC bajada

int LDRpin= A1; // pin sensor LDR

bool val = 0; //val se emplea para almacenar el estado del boton
bool state = false; // 0 LED apagado, mientras que 1 encendido
//bool old_val = 0; // almacena el antiguo valor de val

bool val_FCsub = false; // Almacenar valor FC subir
bool val_FCbaj = false; // Almacenar valor FC bajar


void setup(){
 pinMode(LED,OUTPUT); // establecer que el pin digital es una señal de salida
 pinMode(LEDsubir,OUTPUT); // establecer que el pin digital es una señal de salida
 pinMode(LEDbajar,OUTPUT); // establecer que el pin digital es una señal de salida
 
 pinMode(BOTON,INPUT); // y BOTON como señal de entrada
 
 pinMode(FCsubir,INPUT); // y FC subida como señal de entrada
 pinMode(FCbajar,INPUT); // y FC bajada como señal de entrada

 
 pinMode(LDRpin, INPUT); // LDR como entrada
 Serial.begin(9600);
}


void loop() {

  // FC
val_FCsub= digitalRead(FCsubir); // lee el estado del FCsubir
val_FCbaj= digitalRead(FCbajar); // lee el estado del FCbajar   

Serial.println("FCsubir:");
Serial.println(val_FCsub);
Serial.println("FCbajar:");
Serial.println(val_FCbaj);
 
  // BOTON LUZ
val= digitalRead(BOTON); // lee el estado del Boton
Serial.println("boton:");
Serial.println(val);

//LDR
int LDRvalor = analogRead(LDRpin);   //leo el valor del LDR
Serial.println("LDR:");
Serial.println(LDRvalor);

delay (1000);

if (val == HIGH) {
state= !state;
delay(10);
}
Serial.println("Stado:");
Serial.println(state);


delay(1000);


if ((LDRvalor>= 200)&&(val_FCbaj==true)){ // caso 4 es de noche baja la persiana y enciende la luz
 //digitalWrite(LED, HIGH); // enciende el LED
state=1;
  bajarpersiana();
}
else if ((LDRvalor>= 200)&&(val_FCbaj==false)){ // caso 4 FIN Solo quiero que para la persiana no que controle las luces
 //digitalWrite(LED, HIGH); // enciende el LED
//state=true;
 digitalWrite(LEDbajar, LOW); //Bajo la persiana
 digitalWrite(LEDsubir, LOW); //
}
else if ((LDRvalor < 200)&&(val_FCsub==true)){ // caso 2 Es de dia sube la persiana y apaga la luz
 //digitalWrite(LED, LOW); // apaga el LED
state=false;
 subirpersiana();
}
else if ((LDRvalor<200)&&(val_FCsub==false)){ // caso 2 FIN Solo quiero que para la persiana no que controle las luces
 //digitalWrite(LED, LOW); // apaga el LED
//state=false;
 digitalWrite(LEDsubir, LOW); //subo la persiana
 digitalWrite(LEDbajar, LOW); //
}

Serial.println("Stado final LED:");
Serial.println(state);
digitalWrite(LED, state);

}


void subirpersiana () {
 digitalWrite(LEDsubir, HIGH); //subo la persiana
 digitalWrite(LEDbajar, LOW); //
}

void bajarpersiana () {
 digitalWrite(LEDbajar, HIGH); //Bajo la persiana
 digitalWrite(LEDsubir, LOW); //
}


Al Pulsar el pulsador, detecta un 1 en el BOTON, cambia el estado a 1, pero el estado al que llamo estado final de led se mantiene a 0.
Cuando hace el cambio automatico con el LDR, si es de noche enciende el LED y el estado final de led se pone a 1. Si es de dia el estado final de Led se pone a 0 y se apaga.

te cuento los finales de carrera los tengo normalmente abierto, entonces estan siempre a 1. Cuando enciende el led de motorsubiendo por ejemplo, y llega al final de subida pulsaria el FC y lo pone a cero, por tanto apaga el led de subida y se quedan los dos apagados. Eso lo hace bien.

No encuentro el fallo por mucho que lo miro. Cuando pulsas el pulsador no cambia el state del DigitalWrite pero si el state de justo despues de state=!state


rodripelto

Pues yo tampoco, por favor pon los serial.print dentro de los if para seguir el flujo del programa.
Si alguna respuesta ha solucionado tu problema, da las gracias marcándola como solucionada.

ivitito

que pongo dentro de cada if en el Print? state?

rodripelto

Mensajes diferentes, por ejemplo subiendo persiana, bajando persiana, desconectando subida, desconectando bajada o simplemente 1 2 3 4. Lo que quieras es para saber en que parte del programa esta.
Si alguna respuesta ha solucionado tu problema, da las gracias marcándola como solucionada.

ivitito

Code: [Select]

if ((LDRvalor>= 200)&&(val_FCbaj==true)){ // caso 4 es de noche baja la persiana y enciende la luz
 //digitalWrite(LED, HIGH); // enciende el LED
state=1;
  bajarpersiana();
  Serial.println("If de bajada/Persianas ON");
}

else if ((LDRvalor>= 200)&&(val_FCbaj==false)){ // caso 4 FIN Solo quiero que para la persiana no que controle las luces
 //digitalWrite(LED, HIGH); // enciende el LED
//state=true;
 digitalWrite(LEDbajar, LOW); //Bajo la persiana
 digitalWrite(LEDsubir, LOW); //
 Serial.println("If de bajada/Persianas OFF");
}
else if ((LDRvalor < 200)&&(val_FCsub==true)){ // caso 2 Es de dia sube la persiana y apaga la luz
 //digitalWrite(LED, LOW); // apaga el LED
state=false;
 subirpersiana();
 Serial.println("If de subida/Persianas ON");
}
else if ((LDRvalor<200)&&(val_FCsub==false)){ // caso 2 FIN Solo quiero que para la persiana no que controle las luces
 //digitalWrite(LED, LOW); // apaga el LED
//state=false;
 digitalWrite(LEDsubir, LOW); //subo la persiana
 digitalWrite(LEDbajar, LOW); //
 Serial.println("If de subida/Persianas OFF");
}

Serial.println("Stado final LED:");
Serial.println(state);
digitalWrite(LED, state);

}



Lo he puesto asi, y si apago la luz entra en el IF de bajada , si la enciendo entro en el If de subida. Se enciende el LED con luz apagada de noche.

El problema esta en el boton, es raro que el state del print de state=!state , si que cambia al pulsar, pero no cambia el print de stado final LED.

Si pulsas el pulsador, boton=1 y state= 1, el boton cambia a 0 al soltar y si vuelves a pulsar el boton state=0 y al soltar boton=0

 pero el state final del LED es siempre 1 si esta de noche y no cambia y es siempre 0 si esta de dia y no cambia.


rodripelto

 :smiley-confuse:  Pues la verdad no lo veo. Tendré que simularlo pero no se cuando voy a poder.
Si alguna respuesta ha solucionado tu problema, da las gracias marcándola como solucionada.

ivitito

muchisimas gracias, a ver si asi ves el fallo cuando puedas, yo seguire intentando a ver si con prueba y error, ya te digo lo raro es lo del boton, que el digitalWrite(LED, state) si es con el boton, no cambia al pulsarlo.

A ver sino, si alguien mas sabe y ayuda.

muchas gracias de nuevo.

rodripelto

Hola,

He simulado el circuito con TinkerCad y funciona bien, el tema es que tienes una condición no deseada, cuando sube la persiana se apaga la luz, si mientras se da esta situacción si enciendes la luz sevuelve  a apagar y en la bajada pasa el caso contrario. Resumiendo mientras que estan los led de subida o bajada encendidos no se puede manipular la luz. Yo ya te he dado el problema ahora es cosa tuya solucionarlo, no es dificil.
Si alguna respuesta ha solucionado tu problema, da las gracias marcándola como solucionada.

ivitito

Me podrias decir cuales son las opciones de solucion? Yo diria que la mas optima seria que estuviera como estuviera la persiana, se pudiera controlar las luces, osea que este o no encendido el led porque el motor aun no haya acabado de subir o bajar de todo, pudiera controlar las luces en todo momento. No tengo muy clara la solucion tampoco.

rodripelto

Hola,
La solución para tú código es usar un flag para saber si la persiana esta en movimiento, con este flag haremos que solo pase una vez por los if de que ponen en marcha la persiana y enciende la luz, además he añadido una condición mas al if de detener la persiana, ya que tal como lo tenias en una situación real se pararía inmediatamente al empezar a moverse la persiana, por el simple motivo de que en cuanto la persiana empezara a moverse dejaría de estar pisado el correspondiente final de carrera.
Code: [Select]

//boton pulsador
const int LED =8; //pin del LED
const int LEDsubir =4; //pin del LED motor subiendo
const int LEDbajar =5; //pin del LED motor bajando

const int BOTON = 7; // pin pulsador

const int FCsubir = 2; // pin FC subida
const int FCbajar = 3; // pin FC bajada

int LDRpin= A0; // pin sensor LDR

bool val = 0; //val se emplea para almacenar el estado del boton
bool state = false; // 0 LED apagado, mientras que 1 encendido
//bool old_val = 0; // almacena el antiguo valor de val

bool val_FCsub = false; // Almacenar valor FC subir
bool val_FCbaj = false; // Almacenar valor FC bajar
bool moviendo=false;

void setup(){
 pinMode(LED,OUTPUT); // establecer que el pin digital es una señal de salida
 pinMode(LEDsubir,OUTPUT); // establecer que el pin digital es una señal de salida
 pinMode(LEDbajar,OUTPUT); // establecer que el pin digital es una señal de salida
 
 pinMode(BOTON,INPUT); // y BOTON como señal de entrada
 
 pinMode(FCsubir,INPUT); // y FC subida como señal de entrada
 pinMode(FCbajar,INPUT); // y FC bajada como señal de entrada

 
 pinMode(LDRpin, INPUT); // LDR como entrada
    Serial.begin(9600);
}

void loop() {

  // FC
val_FCsub= digitalRead(FCsubir); // lee el estado del FCsubir
val_FCbaj= digitalRead(FCbajar); // lee el estado del FCbajar   

Serial.println("FCsubir:");
Serial.println(val_FCsub);
Serial.println("FCbajar:");
Serial.println(val_FCbaj);
 
  // BOTON LUZ
val= digitalRead(BOTON); // lee el estado del Boton
Serial.println("boton:");
Serial.println(val);

//LDR
int LDRvalor = analogRead(LDRpin);   //leo el valor del LDR
Serial.println("LDR:");
Serial.println(LDRvalor);

delay (1000);

if (val == HIGH) {
state= !state;
delay(10);
}
Serial.println("Stado:");
Serial.println(state);


delay(1000);


if ((LDRvalor>= 200)&&(val_FCbaj==true)&&(moviendo==false)){ // caso 4 es de noche baja la persiana y enciende la luz
 //digitalWrite(LED, HIGH); // enciende el LED
state=1;
  bajarpersiana();
  Serial.println("If de bajada/Persianas ON");
}

else if ((LDRvalor>= 200)&&(val_FCbaj==false)&&(val_FCsub==true)){ // caso 4 FIN Solo quiero que para la persiana no que controle las luces
 pararpersiana();
 Serial.println("If de bajada/Persianas OFF");
}
else if ((LDRvalor < 200)&&(val_FCsub==true)&&(moviendo==false)){ // caso 2 Es de dia sube la persiana y apaga la luz
 //digitalWrite(LED, LOW); // apaga el LED
state=false;
 subirpersiana();
 Serial.println("If de subida/Persianas ON");
}
else if ((LDRvalor<200)&&(val_FCsub==false)&&(val_FCbaj==true)){ // caso 2 FIN Solo quiero que para la persiana no que controle las luces
 pararpersiana();
 Serial.println("If de subida/Persianas OFF");
}

Serial.println("Stado final LED:");
Serial.println(state);
digitalWrite(LED, state);

}

void subirpersiana () {
 moviendo=true;
 digitalWrite(LEDsubir, HIGH); //subo la persiana
 digitalWrite(LEDbajar, LOW); //
}

void bajarpersiana () {
 moviendo=true;
 digitalWrite(LEDbajar, HIGH); //Bajo la persiana
 digitalWrite(LEDsubir, LOW); //
}
void pararpersiana()
{
 moviendo=false;
 digitalWrite(LEDsubir, LOW);
 digitalWrite(LEDbajar, LOW);
}
Si alguna respuesta ha solucionado tu problema, da las gracias marcándola como solucionada.

ivitito

Despues de probar lo de rodripelto, he seguido con el proyecto implementando un boton para el control de las persianas, pero no consigo hacerlo, debido a que no es como le boton de la luz que se puede hacer invirtiendo el valor de una variable, con las persianas necesito controlar, un LED de subida y otro LED de bajada. No se muy bien como hacerlo, ¿alguien me puede ayudar? muchas gracias.

noter

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.

Code: [Select]


/* 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.

ivitito

#27
Nov 05, 2017, 06:52 pm Last Edit: Nov 05, 2017, 07:17 pm by surbyte Reason: No uses reply para respuestas que se leen perfectamente
Posiblemente me explique yo mal, lo de RodriPelto funcionaba a la perfeccion pero a mayores, yo añado otro pulsador que no esta en las fotos iniciales para el control de las persianas, hasta el ultimo codigo el control de las luces esta correcto: Si pulsaba el pulsador de luz tenia prioridad estuviera como estuviera el LDR y sino funcionaba en funcion del LDR, las persianas a su vez funcionaban correcto en funcion del LDR.

El problema es al meter un segundo pulsador, este sera para controlar manualmente las persianas, osea tengo uno con el que controlo manualmente la luz( SI estas en casa igual no quieres la luz encendida aunque se de esa condicion) y con las persianas lo mismo, igual hay luz fuera y tu quieres seguir durmiendo entonces manualmente bajas la persiana.

Necesito controlar desde un pulsador de Persianas nuevo, los led de las persianas. LEDMOTORSUBIENDO y LED MOTOR BAJANDO.

Creo que entendi tu codigo pero no hace eso, solo controlas con un pulsador la luz pero no las persianas.

muchas gracias.

noter

#28
Nov 07, 2017, 01:22 am Last Edit: Nov 07, 2017, 10:07 pm by noter
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.

Code: [Select]

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
}


ivitito

He estado convirtiendo tu codigo a mis conexiones y detecto varias cosas que no funcionan:

1º Al switch LDR entra una vez si hay luz y otra si provocas un cambio, pero no lee constante el valor del LDR por tanto solo se queda con el valor del momento del cambio.

2º El juego de los LEds de persianas lo hace OK si hay luz sube y si no baja pero, los finales de carrera no funcionan, cuando detecta el final de carrera no pasa nada.

3º El manejo de los LED de la persiana de forma manual, me gustaria hacerla solo con un unico pulsador.

¿¿Me podriais ayudar, con el ultimo codigo que puso RodriPelto que era con el que empece a trabajar y el me ayudo a continuar, a meter el pulsador???

Go Up