Control Persianas ***** SOLUCIONADO *****

Buenas,

Hace mucho tiempo que no jugaba con el arduino, estoy planteandome mudarme y me surje la necesidad de controlar las persianas desde el arduino, en realidad soy muy novato y no se muy bien como puedo determinar el tiempo de ejecucion al pulsar un boton.

Lo que quiero, no se si es posible es que al pulsar un boton la señal permanezca activa durante x segundos, por ejemplo pulso el boton subir y que suba durante 20 segundos... me podeis ayudar ???

No quiero que tome una señal analogica sino que por ejemplo desde el movil seleccionando un boton llamado subir persiana al pulsarlo suba toda la persina o viceversa en principio me conformo con eso, luego quisiera determinar la posicion.

Muchas gracias

Adjunto el codigo de lo que tengo hasta el momento aunque no esta la parte de la persiana por que no consigo hacerlo

const int hprinl = 2;
const int hprinv = 3;
const int cocl = 4;
const int halll = 5;
const int hallp = 6;
const int salv = 7;  // desactivados hasta saber como poder escribir en el puerto serie.
const int sall = 8;
const int terrl = 9;
int pirPin = 10;
int incomingByte;      // a variable to read incoming serial data into
int estado;
//float temperatura = A5; //variable para la temperatura
long tiempoEncendido = 10000;   // Tiempo en mili-segundos (10 segundos)
int PIRactivo=0;
long contador = 0;
int Jor = 12;
long tiempoAbierta = 1000;   // Tiempo en mili-segundos (10 segundos)
int JORactivo=0;
long abierta = 0;
 
 



void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("CASA DOMOTICA");
  Serial.println("i - APAGAR LAMPARA HABITACION PRINCIPAL");
  Serial.println("j - ENCENDER LAMPARA HABITACION PRINCIPAL");  
  Serial.println("k - APAGAR VENTILADOR HABITACION PRINCIPAL");    
  Serial.println("l - ENCENDER VENTILADOR HABITACION PRINCIPAL");
  Serial.println("m - APAGAR LAMPARA COCINA");
  Serial.println("n - ENCENDER LAMPARA COCINA");
  Serial.println("o - APAGAR LAMPARA HALL");  
  Serial.println("p - ENCENDER LAMPARA HALL");    
  Serial.println("q - CERRAR PUERTA");
  Serial.println("r - ABRIR PUERTA");
  Serial.println("a - APAGAR VENTILADOR SALON");
  Serial.println("b - ENCENDER VENTILADOR SALON");  
  Serial.println("c - APAGAR LAMPARA SALON");    
  Serial.println("d - ENCENDER LAMPARA SALON");
  Serial.println("e - APAGAR LAMPARA TERRAZA");    
  Serial.println("f - ENCENDER LAMPARA TERRAZA");
  // initialize the LED pin as an output:
  pinMode(hprinl, OUTPUT);
  pinMode(hprinv, OUTPUT);
  pinMode(cocl, OUTPUT);
  pinMode(halll, OUTPUT);
  pinMode(hallp, OUTPUT);
  pinMode(terrl, OUTPUT);
  pinMode(sall, OUTPUT);
  pinMode(salv, OUTPUT);
  pinMode(pirPin, INPUT);
  pinMode(Jor, INPUT);
  
}

void loop() {
  
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    switch (incomingByte){
      case 'i':
        digitalWrite(hprinl, LOW);
        estado=LOW;
        break;
      case 'j':
        digitalWrite(hprinl, HIGH);
        estado=HIGH;
        break;
      case 'k':
        digitalWrite(hprinv, LOW);
        estado=LOW;
        break;
      
       case 'l':
        digitalWrite(hprinv, HIGH);
        estado=HIGH;
        break; 
      
             case 'm':
        digitalWrite(cocl, LOW);
        estado=LOW;
        break;
    
             case 'n':
        digitalWrite(cocl, HIGH);
        estado=HIGH;
        break;
    
             case 'o':
        digitalWrite(halll, LOW);
        estado=LOW;
        break;
    
             case 'p':
        digitalWrite(halll, HIGH);
        estado=HIGH;
        break;
    
             case 'q':
        digitalWrite(hallp, LOW);
        estado=LOW;
        break;
    
             case 'r':
        digitalWrite(hallp, HIGH);
        estado=HIGH;
        break;
    
             case 'a':
        digitalWrite(salv, LOW);
        estado=HIGH;
        break;
    
             case 'b':
        digitalWrite(salv, HIGH);
        estado='b';
        break;
    
             case 'c':
        digitalWrite(sall, LOW);
        estado=LOW;
        break;
    
             case 'd':
        digitalWrite(sall, HIGH);
        estado=HIGH;
        break;
    
             case 'e':
        digitalWrite(terrl, LOW);
        estado=LOW;
        break;
    
             case 'f':
        digitalWrite(terrl, HIGH);
        estado=HIGH;
        break; 
      



              case 'g':
          if(estado=='b'){
             Serial.println("30.1");
          } else {
            Serial.println("24.3");
          }//if estado
        break;

   

    }//switch
  } else {
   

      
      

   JORactivo=digitalRead(Jor);   // Lee el sensor PIR
   if (JORactivo==HIGH){               // Si está activo reinicia el contador de tiempo
     abierta=tiempoAbierta;         //    al tiempo de encendido total.
   }
   if (abierta > 0) {                 // Si el contador de tiempo es positivo mantiene
     abierta = abierta - 200;        //    encendido el interruptor y decrementa el
     digitalWrite(hallp,HIGH);   //    tiempo de encendido, sino lo apaga.
   } else {                          
     digitalWrite(hallp,LOW);
   }
 
   delay (200);



  

   PIRactivo=digitalRead(pirPin);   // Lee el sensor PIR
   if (PIRactivo==HIGH){               // Si está activo reinicia el contador de tiempo
     contador=tiempoEncendido;         //    al tiempo de encendido total.
   }
   if (contador > 0) {                 // Si el contador de tiempo es positivo mantiene
     contador = contador - 200;        //    encendido el interruptor y decrementa el
     digitalWrite(halll,HIGH);   //    tiempo de encendido, sino lo apaga.
   } else {                          
     digitalWrite(halll,LOW);
   }
 
   delay (200);
 
 
 
 }
 
/*
   //Calcula la temperatura usando como referencia 5v
   //Calcula la temperatura usando como referencia 5v
   temperatura = (5.0 * analogRead(A5)*100.0)/1023.0;
   Serial.println (temperatura);
//escribe la temperatura en el serial
   delay (1000); //espera 1 segundos para la siguiente medicion
   
     
//   }
  
  
*/
       
 

} //loop

Deberías explicar el mecanismo que estas usando: ¿un motor?, ¿un servo?. Aunque no funcione deberías incluir la parte del código con la que intentas controlar las persianas.

Buenas TFTLCDCyg,

Muchas gracias por contestar, mirando en foros encontré esto de Adrian-gn, pero no se como cambiar las lecturas analogicas por digitales, la parte mecanica del boton me funciona, pero lo que necsito es cambiar la lectura analogica del LDR o NTC por una digital para controlarla desde la web.

Me gustaria asignarle un puerto digital por ejemplo el 8 que esta libre y decir que al pulsar el 8 permanezca esa accion que activaria un rele que activa un motor x segundos para subir la persiana, no se si es el calor de este verano pero no entiendo como puedo hacerlo… :confused:

int LDR = A0;    // select the input pin for the LDR
int NTC = A1;    // select the input pin for the NTC
int Down = 12;    // select the input pin for the down button
int Up = 13;    // select the input pin for the up button
int Rele1 = 2; // select the pin 2 for the Rele 1
int Rele2 = 3; // select the pin 3 for the Rele 2
int Led = 4; // select the pin 4 for the Led


int LDRValue = 0;  // variable to store the value coming from the LDR
int NTCValue = 0;  // variable to store the value coming from the LDR
int DownValue = 0;  // variable to store the value coming from the LDR
int UpValue = 0;  // variable to store the value coming from the LDR
int TiempoSubir = 0;
int TiempoSubiendo = 0;
int Posicion = 0; // set the position to 0


void setup() {
 Serial.begin(9600);
 // declare the Rele1 Pin as an OUTPUT:
 pinMode(Rele1, OUTPUT);
 // declare the Rele2 Pin as an OUTPUT:
 pinMode(Rele2, OUTPUT);
 // declare the Rele2 Pin as an OUTPUT:
 pinMode(Led, OUTPUT);

 digitalWrite(Rele1, HIGH);
 digitalWrite(Rele2, HIGH);
 digitalWrite(Led, HIGH);
 delay(20000);
 digitalWrite(Rele1, LOW);
 digitalWrite(Rele2, LOW);
 digitalWrite(Led, LOW);
 digitalWrite(TiempoSubiendo, LOW);

}

void loop() {
 // Leer valor de la ldr:
 LDRValue = analogRead(LDR);    
 // Leer valor de la NTC:
 NTCValue = analogRead(NTC);
 // Leer valor de Down button:
 DownValue = digitalRead(Down);    
 // Leer valor de Up button:
 UpValue = digitalRead(Up);  

 if (Posicion >= 20)
 {
   Posicion = 19;      
 }

 switch (DownValue) {
 case HIGH:
   //BOTON BAJAR
   digitalWrite(Rele1, HIGH);
   digitalWrite(Rele2, HIGH);
   digitalWrite(Led, HIGH);
   break;
 case LOW:
   switch (UpValue) {
   case HIGH:
     //BOTON SUBIR
     digitalWrite(Rele1, HIGH);
     digitalWrite(Rele2, LOW);
     digitalWrite(Led, HIGH);
     digitalWrite(TiempoSubiendo, HIGH);
     TiempoSubir = pulseIn(TiempoSubiendo, HIGH);

     break;
   case LOW:
     //SIN BOTONES
     digitalWrite(Rele1, LOW);
     digitalWrite(Rele2, LOW);
     digitalWrite(Led, LOW);
     digitalWrite(TiempoSubiendo, LOW);

     if (Posicion == 0)
     {
       if (NTCValue <= 200)
       {
         if (LDRValue > 100)
         {
           Posicion =+ 6;
           digitalWrite(Rele1, HIGH);
           digitalWrite(Rele2, LOW);
           delay(6000);
           digitalWrite(Rele1, LOW);
           digitalWrite(Rele2, LOW);
         }  
       }

     }








     break;
   }
   break;

 }
 Serial.print("Posicion: ");
 Serial.print(Posicion);
 Serial.print("\t LDR:" );
 Serial.print(LDRValue);
 Serial.print("\t NTC:" );
 Serial.print(NTCValue);
 Serial.print("\t Down:" );
 Serial.print(DownValue);
 Serial.print("\t Up:" );
 Serial.println(UpValue);
 Serial.print("\t Tiempo subir:" );
 Serial.println(TiempoSubir);
}

Me parece bastante complejo lo que te estan diciendo que hagas, por lo que vos pedis seria mucho mas sencillo, necesitas tres pulsadores (uno de subida,uno de bajada y un stop) me parece mucho mas facil utilizar una variable e ir incrementadole un valor. Si tenes alguna duda avisame y te doy una mano con la programacion.

ezequiel1702: Me parece bastante complejo lo que te estan diciendo que hagas, por lo que vos pedis seria mucho mas sencillo, necesitas tres pulsadores (uno de subida,uno de bajada y un stop) me parece mucho mas facil utilizar una variable e ir incrementadole un valor. Si tenes alguna duda avisame y te doy una mano con la programacion.

Quien le esta diciendo algo? TFTLCDCyg preguntó que esta moviendo si un motor o un servo. Y el único que responde es el propio autor Lo que pide es obvia ayuda asi que si puedes hacerlo ezequiel1702, todo tuyo.

Sugierele como usar los 3 botones para que cumpla con su objetivo.

Buenas muchas gracias a los dos por contestar,

Ezequiel, si me das una pista de como hacerlo te lo agradezco, el codigo que copie es de alguien que lo esta usando pero con los sensores, yo quiero simplemente poder subir y bajar las ventanas, intenté hacer esto

int ledPin = 9;
int inputPin1 = 2; // pulsador 1
int inputPin2 = 3; // pulsador 2
int p1;
int p2;
int value = 0;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin1, INPUT);
pinMode(inputPin2, INPUT);
}
void loop(){

p1=digitalRead(inputPin1);
p2=digitalRead(inputPin2);
if (p1 == HIGH) { value--; }
else if (p2 == HIGH) { value++; }
value = constrain(value, 0, 255);
analogWrite(ledPin, value);
delay(10);
}

pero el rele se activa despues de pulsar muchas veces el boton y se queda activo, eso si estoy en casa me funciona por que puedo pararlo cuando quiera pero si lo que quiero es simular presencia no me vale de nada.

Os agradezco que me ayudeis a ver como puedo enviar una señal y que dure un tiempo determinado, eso mismo quisiera usarlo para abrir el portal, enviar una señal al telefonillo para que sea como pulsar el boton y poder abrir la puerta del portal de una forma mas agil.

Un saludo y muchas gracias.

A ver si funciona. Si llegas a tener rebotes habrá que implementar una rutina antirebotes Te daras cuenta porque cada pulsación incrementa varios pasos. Miralo con el monitor serie

const byte ledPin       = 9;
const byte inputPin1    = 2; // pulsador 1
const byte inputPin2    = 3; // pulsador 2
int p1, p1Ant;
int p2, p2Ant;
int value = 0;

void setup() {
    pinMode(ledPin, OUTPUT);
    pinMode(inputPin1, INPUT);
    pinMode(inputPin2, INPUT);
}
void loop(){

    p1=digitalRead(inputPin1);
    p2=digitalRead(inputPin2);

    if (p1 == HIGH & piAnt == LOW)  
        value--; 

    if (p2 == HIGH && p2Ant == LOW) 
        value++; 
    p1Ant = p1;
    p2Ant = p2;

    value = constrain(value, 0, 255);
    analogWrite(ledPin, value);
    delay(10);
}

Buenas,

Muchas gracias, aparentemente funciona de manera similar, mi pregunta es como puedo decirle que para bajar tarda 20 segundos, me puedes ayudar con un codigo al que al pulsar por decir algo el P1Ant se mantenga activo 20 segundos ? y para subir sea igual.

En la salida 9 tengo un rele y lo que hace es que al tener determinada corriente funciona, eso es al pulsar varias veces el boton y luego se queda encendido.

Muchas gracias !!!!

A ver. Ahora no comprendo. Los pulsadores suben y bajan. No se si eso le dice al servo en que ángulo ponerse o es un motor y le cambias la velocidad. TFTLCDCyg te preguntó si era motor o servo pero no respondiste. Intenta siempre leer lo que todos escriibmos porque ayuda a nutrir el tema de lo necesario para comprenderte.

Buenas,

Sorry, me expliqué mal, es un motor que se activa mediante un rele, estoy muy perdido en el tema, no quiero cambiar la velocidad del motor, solo que googleando encontré eso.

Por resumir, lo que necesito simplemente es enviar una señal a un rele y que este se active los segundos que yo le diga, con hacer eso es suficiente para mi.

Pero lo del tiempo se me da mal, no se como crear la variable.

Muchas gracias !!

Ahhh entonces eso que tienes al final no tiene razon de ser, como tampoco subir o bajar un contador porque no tiene efecto alguno sobre un rele. Eso era para un servo o un motor al que le cambiamos la velocidad.

Entendida esa parte veamos tu problema.

Entonces un pulsador sube la ventana y otro la baja y quieres que demore 20 segundos en subirla/bajarla?

No se que velocidad tiene tu motor, de manera que activando un motor por 20 segundos no se si eso implica que suba o baje la ventana completamente.

Tu dime si es asi.

Buenas,

Si, justo es eso, un pulsador sube y otro baja, y debe durar 20 segundos subiendo y 20 bajando.

Muchas gracias !!!!

De nuevo.. debe durar 20 segundos pero si yo activo 20 segundos el rele que acciona sobre tu motor eso sube la ventana o la baja?

ALgo asi debes usar |338x500

Cambio de giro relay

ahora esto depende de la velocidad del motor

IMPORTANTE: Aunque el esquema esta bien, un solo rele puede servir para invertir giro pero no puedo detener la marcha asi que necesitas dos reles y uno debe quitarle la energia o bien usar uno para un giro y otro para el opuesto.

Buenas,

Tengo dos reles, uno para subir y otro para bajar, ese esquema no me vale porque no para nunca el motor.

El motor tiene un circuito para subir y otro para bajar.

Con hacer que se active el rele 20 segundos para subir es suficiente, no todas las ventanas son iguales, digo 20 segundos por tomarlo como una medida estandar, pero con saber la variable el tiempo lo puedo modificar luego segun el caso que sea.

Muchas gracias !!!

http://www.google.es/search?q=motor+persiana&source=lnms&tbm=isch&sa=X&ved=0CAYQ_AUoAWoVChMI692b5830xgIVkivbCh2J8wZX&biw=360&bih=615#tbm=isch&q=conexion+motor+persiana&imgrc=dLL2P8Ub5Xmj7M%3A

Estoy intentando hacer esto pero tampoco me funciona ... :confused: no se activa el led ...

const int ledPin =  13;      // the number of the LED pin
const byte inputPin1    = 3; // pulsador 1
int ledState = LOW;             // ledState used to set the LED
int p1;
long contador = 0;
long tiempoEncendido = 10000;   // Tiempo en mili-segundos (10 segundos)




void setup() {
  pinMode(ledPin, OUTPUT);     
}

void loop()
{


    p1=digitalRead(inputPin1);

   if (p1==HIGH){               // Si está activo reinicia el contador de tiempo
     contador=tiempoEncendido;         //    al tiempo de encendido total.
   }
   if (contador > + 0) {                 // Si el contador de tiempo es positivo mantiene
     contador = contador - 200;        //    encendido el interruptor y decrementa el
     digitalWrite(ledState,HIGH);   //    tiempo de encendido, sino lo apaga.
   } else {                          
     digitalWrite(ledState,LOW);
   }

   delay (10);


digitalWrite(ledPin, ledState);
}

Bien.
Para la próxima intenta (y no es reto, sino que lo tengas en cuenta) ser mas descriptivo en tu primer post, en tu post#14 recien nos cuentas que tienes un rele para subir y otro para bajar.

Okay. Entonces muy simple.

const byte ReleSubir  = 9;
const byte ReleBajar  = 10;   // Cambialo al pin que gustes
const byte inputPin1  = 2;    // pulsador 1
const byte inputPin2  = 3;    // pulsador 2

int p1, p1Ant;
int p2, p2Ant;
int value = 0;
unsigned long stime = 0;

void setup() {
  pinMode(ReleSubir, OUTPUT);
  pinMode(ReleBajar, OUTPUT);
  pinMode(inputPin1, INPUT);
  pinMode(inputPin2, INPUT);
}


void loop(){

  p1=digitalRead(inputPin1);
  p2=digitalRead(inputPin2);

  if (p1 == HIGH & piAnt == LOW)  {
    sube = true; 
    baja = false;
    stime = millis();
    digitalWrite(ReleSubir, HIGH);
  }
    

  if (p2 == HIGH && p2Ant == LOW) {
    sube = false; 
    baja = true;
    stime = millis();
    digitalWrite(ReleBajar, HIGH);
  }

  p1Ant = p1;
  p2Ant = p2;


  if (sube ) {
     if (millis() - stime > 20000UL) {
        digitalWrite(ReleSubir, LOW);
        sube = false;
     }        
  }

  if (baja ) {
     if (millis() - stime > 20000UL) {
        digitalWrite(ReleBajar, LOW);
        baja = false;
     }   
  }
}

Buenas surbyte,

Perfecto, muchisimas gracias, ya funciona como queria ... :) :) :) :)

Un saludo