Hola, me he dejado caer por aquí, ya te aparte de ser novato con Arduino, me ha surgido una pequeña gran duda.
Como consigo generar un conmutador con varias entradas para accionar un relé.??
Me explico brevemente, el proyecto es de tipo domotica(hobbie), controlar la luz de una habitación, por medio de un mando de TV, un pulsador y un sensor de movimiento...
El CODIGO:
#include <IRremote.h>
int estado = 0;
int estadoAnterior = 0;
int salida = 0;
int IRpin = 11;
IRrecv irrecv(IRpin);
decode_results results;
boolean LEDon = true;
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
pinMode(9, OUTPUT);
pinMode(14, INPUT);
}
void loop() {
// **********************************PULSADOR***********************************
estado = digitalRead(14);
if ((estado == HIGH) && (estadoAnterior == LOW)) {
salida = 1 - salida;
delay(20);
}
estadoAnterior = estado;
if (salida == 1) {
digitalWrite(9, HIGH);
}
else {
digitalWrite(9, LOW);
}
// **********************************IRREMOTE************************************
//codigos emitidos por el mando OKI 117,83,84,85,86
if (irrecv.decode(&results)) {
irrecv.resume();
}
if(results.value == 117) {
if (LEDon == true) {
LEDon == false;
salida = 0; //como prueba...
digitalWrite(9, HIGH);
}
if (results.value == 83,84,85,86){
LEDon = true;
//salida = 0; //como prueba...
digitalWrite(9, LOW);
}
}
}
Aun me falta por ponerle la sección del del sensor de movimiento, pero no conozco ni he encontrado algún código que me permita usar como conmutador entre el mando y el pulsador.
Lo único que he podido dar hasta ahora es que si activas el pulsador, el relé entra , al darle con el mando este no corta con un toque... al segundo abre el relé.
Gracias de antemano.
PD:. Soy autodidacta... nadie me ha enseñado y no he tenido la oportunidad de estudiar nada referente a electrónica digital, no pido el código, solo que me lo expliquen y me corrijan.
No he analizado el código, pero en estos casos tienes que usar una variable flag (bandera)
Es decir, una variable que en cada cambio por cualquier conmutador guarde como se quedó el relé y en base a ese dato así podrás tomar una decisión con los otros conmutadores.
La variable puede ser tipo boolean (true (el relé esta activado) o false)
Buenas:
Siempre es bueno aclaraciones en el código. Respecto a la conmutación, yo personalmente no lo entiendo bien, no se si lo que quieres es que el mando, el interruptor o pulsador y el detector de movimiento conmuten una luz. Es decir, que si se acciona uno de los anteriores la luz cambie a otro estado. ¿Entiendo eso?
Creo que sí, para hacer esto, lo mejor son las interrupciones. ¿Qué es una interrupción?, pues digamos que el arduino tiene una serie de pines en las que si se produce un cambio en voltaje, por ejemplo pasar de 5V a 0V, se ejecuta un código. Hay ejemplos en la propia web de arduino.
Las interrupciones tienen una desventaja, arduino uno solo tiene 2 pines, con lo que solo puedes tener dos entradas...Por lo que yo te recomiendo, si solo es encender una luz, que lo hagas como lo estabas haciendo. El método de estar siempre comprobando una entrada se llama polling o espera activa, y normalmente se evita porque consume bastantes recursos (por ejemplo energéticos ya que gastas más energía, puede que no sea tu problema este consumo).
El código anterior te ocurrirá un efecto rebote, por ejemplo que el interruptor se quede en alto (high) más de un ciclo (ciclo es cuando termine el void loop), por lo que cuando vuelva a hacer el loop, entre en el if otra vez y te vuelva a conmutar...Para ello usa las interrupciones, otra opción sería poner un pequeño delay de digamos 0,1 segundos, para que te de tiempo a soltar el interruptor. No es muy elegante esta solución.
Otra cosa, el tema del detector de movimiento. Este cuando detecta movimiento se quedaría a 5V durante un periodo de tiempo que tu puedes programar, pero que es bastante, creo que lo mínimo era 0,5 segundos en los que venden ya fabricados. Pero si te vuelves a mover, se apagaría...Con lo que yo no lo haría conmutador con las condiciones de los anteriores.
Plogar, gracias por las aclaraciones.
Te hice caso con el tema de los retardos... ya tiene mejor aspecto.
La idea del sensor de movimieto, estaria bien para un pasillo, cuarto de baño y demas... en una sala... como que no cuadra muy bien y menos con animales ....
Comparto el codigo, a ver si estos dias hago el friz...
//Proyeto de Domotica, controlar luces de una habitación a travez de un mando de TV y pulsadores.
//La principal idea es commutar un rele entre varios dispocitivos de entrada
#include <IRremote.h>
int OUTpin = 5; //pin de salida
int sw1 = 14; //pulsador o entrada 1
int sw2 = 15; //pulsador o entrada 2
int IRpin = 11; //pin OUT del IR TSOP 1738
IRrecv irrecv(IRpin);
decode_results results;
boolean running = false;
void setup()
{
Serial.begin(9660);
irrecv.enableIRIn();
pinMode(OUTpin, OUTPUT); //pin conf. salida (rele)
pinMode(sw1, INPUT); // pin conf. entrada
pinMode(sw2, INPUT); // pin conf. entrada
pinMode(IRpin, INPUT); // pin IR conf. entrada
}
void loop()
{
if (digitalRead(sw1) == HIGH) // cuando pulsador o entrada 1 es alto
{
delay(60);
running = !running; // compara
digitalWrite(OUTpin, running); // da salida
}
if (digitalRead(sw2) == HIGH) // cuadno pulsador o entrada 2 es alto
{
delay(60);
running = !running; // compara
digitalWrite (OUTpin, running); // da salida
}
if (irrecv.decode(&results)) // al recibir resultados del IR, almacena resultado
{
irrecv.resume();
}
if (results.value == 117){ // 117 CODIGO DEL BOTON DEL MANDO para activar
running = !running;
digitalWrite (OUTpin, running);
}
if (results.value = !117){
running = !running;
digitalWrite (OUTpin, running);
}
delay(600);
}
Ya este fin de semana me pongo y miro lo de las interrupciones.
Gracias compadre¡¡
Bien, no se que arduino usas, pero supongo que es el UNO, por lo que los pines para las interrupciones son 2, el digital 2 y el 3. Creo que no necesitarías más para tu proyecto.
Te paso el enlace donde puedes consultar la función, ejemplos y demás de las interrupciones: https://www.arduino.cc/en/Reference/AttachInterrupt
Te paso un ejemplo que hice hace algún tiempo.
boolean estado = false;
void setup(){
Serial.begin(9600);
pinMode(13,OUTPUT);
attachInterrupt( 0, ServicioBoton, FALLING);
/* 0 corresponde con el pin digital 2, si ponemos 1 iría con el pin digital 3.*/
/* ServicioBoton es la función que se ejecuta cuando se produzca dicha interrupción*/
/* FALLING es el tipo de interrupción, sería el cambio de 5V a 0V
}
void loop()
{
if(estado==true){
detachInterrupt(0); //Desactiva solo la interrupcion del pin 2
//noInterrupts();//Descativa las interrupciones, delays son interrupciones y los desactiva también
Serial.println("Interrupcion detectada");
estado=false;
/* Enciendo y apago un led */
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13,LOW);
delay(500);
digitalWrite(13, HIGH);
delay(500);
}
interrupts();//Activa interrupciones, no necesario si usamos detachInterrupt
attachInterrupt( 0, ServicioBoton, FALLING); // Volvemos a reactivar la interrupción
digitalWrite(13,LOW);
}
/* Función de la interrupción */
void ServicioBoton()
{
//Debe de ser rápido, poco mas que invocaciones a funciones o subir flags, no un Serialprint
estado=true;
}
Para hacer dos interrupciones solo tienes que hacer otra llamada a la interrupción (entiéndase "attachInterrupt( 1, ServicioMando, RISING);" )
Y en el bucle principal puedes hacer lo que quieras, es aconsejable que durmieras el arduino.
Si tienes mas dudas, por ejemplo el tema de dormir al arduino, o de la activación del relé (que no se podrá activar directamente desde la salida, sino que tendrás que usar o un módulo o un transistor)