Go Down

Topic: Proyecto control de persianas automatizadas (Read 2747 times) previous topic - next topic

ivitito

Sep 29, 2017, 02:32 pm Last Edit: Jun 14, 2018, 12:27 am by ivitito
Buenas tardes,

estoy haciendo un proyecto de final de carrera de un sistema de control de persianas y luces. Me encuentro con que las persianas y las luces funcionan en algunos caso pero en otros no:


NO FUNCIONA: si el LDR NO DETECTA LUZ (LED ROJO ENCENDIDO) Y ESTAS PULSADO EL PULSADOR DE LA LUZ (pulsador amarillo), no enciende y apaga el led rojo.

en caso contrario, estando el LDR detectando LUZ(LED rojo APAGADO), puedes pulsar el pulsador y el LED se encienda y apaga.


los led amarillo y verde son motor subiendo y motor bajando respectivamente.

la Protoboard pequeña es para otra parte del proyecto y simplemente tengo en comun GND.

Estoy un poco perdido ahora mismo porque no encuentro mi error o errores, ayuda por favor.

surbyte

Puedes explicarte mejor!!

Yo no comprendo la relación entre subir/bajar y el LDR ademas de tu botón que cambia el estado.

Recuerda que nosotros no estamos ahi pero lo que mas me sorprende es que es tu tesis de modo que deberías poder explicarte con mayor claridad. Si nosotros no entendemos, espero que tu profesor si.

A ver si mejoras las comunicación.
Yo tengo tu código corregido pero haciendo lo mismo porque luego no pude entender tus objetivos.

Persianas,suben o bajan. Ok
Luz dia/noche => Luz dia ABRIR. Luz de noche BAJAR

Bien, que mas? quieres que el boton pase por encima de esta orden y suba/baje las persianas independientemente de la luz exterior?

ivitito

Sigue haciendo lo mismo que antes, funciona segun el LDR pero detecta la pulsación y cambia la variable state pero no cambia el estado del LED.

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.

noter

#4
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???

noter

#6
Nov 13, 2017, 11:08 pm Last Edit: Nov 13, 2017, 11:09 pm by noter
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???
Pues no lo probé profundamente, pero en la simulación que hice, creo que funcionaba bastante bien, aunque quedaba algún pequeño fleco por arreglar. La diferencia con el otro código en el que estáis trabajando, es básicamente que no hay ningún momento de "desatención" en el programa. Es decir, que en mitad de una subida o bajada de persiana los pulsadores manuales pueden interrumpir dicho movimiento, sin esperar a que se complete la subida o bajada en curso.

No obstante, si el código de RodriPelto lo lleváis más maduro, es lógico que continuéis por esa vía, teniendo en cuenta lo que él te ha dicho sobre el planteamiento de un proyecto, porque coincido en que es mejor el planteamiento global que el ir parcheando sobre un planteamiento puntual.


Go Up