(Solucionado) Error codigo IR y relé

Hola a todos.

Tengo un problema, y no lo pude solucionar aún así reescribiendo el código 4 veces.

Tengo un relé, un receptor IR (TSOP2236), un LED IR, otro verde y otro rojo conectados a un Arduino Uno R3. Lo que quiero hacer es controlar un aire acondicionado “split” que tiene la placa rota, por lo que cuando apaga el equipo refrigerante (el grande que se encuentra afuera de la habitación), luego de subir algunos grados no lo vuelve a prender.

El “esquema” de funcionamiento es el siguiente:

1- Relé apagado (A/C apagado), esperando a señal IR de prendido (del control remoto del A/C).

2- Señal IR de prendido recibida, prender relé, esperar 3-4 segundos (todavía no decidí) mandar señal IR de prendido al A/C.

3- Esperar 10-15 minutos (todavía no tomé el tiempo que necesito. En el código esta puesto 20 segundos para poder depurar más rápido). Mientras espera, escuchar señal IR de apagado. Si es así, mandar señal de apagado (por las dudas si el A/C no lo recibió del control), esperar 3-4 segundos, apagar el relé y volver al loop para esperar señal de encendido.

4- Pasado ese tiempo sin una señal de apagado recibida, mandar señal de apagado, esperar 3-4 segundos, apagar el relé y volver al loop, donde con unas variables e if volverá al paso 1.

Los problemas son:

1- Ahora no se que modifiqué, pero no vuelve a hacer el ciclo en el paso 4, es decir no pasa de nuevo al paso 1.
2- No detecta la señal de apagado en el paso 3.

Acá les dejo el código, a ver si me pueden ayudar.

#include <IRremote.h>

unsigned long On = 0x9E00040A; // where XXXXXXXX is on our your remote's values
unsigned long Off = 0x8E00040A; // where XXXXXXXX is another button on your remote

#define ON_LED_PIN 10
#define RELAY_PIN 9
#define RELAY_LED_PIN 12
int RECV_PIN = 11;
int interval = 20000;
int check = 0;
int ant = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;
void irOn();
void irOff();
void relayOn();
void relayOff();
void blinkRelLed();
void opciones();
void opciones2();
void apagadoTotal();
void opcionesPrev();

unsigned int powerOn[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};
unsigned int powerOff[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};
unsigned long currentMillis = millis();
unsigned long previousMillis = 0;


void setup() {

  Serial.begin(9600);
  pinMode(RELAY_LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(ON_LED_PIN, OUTPUT);
  digitalWrite(ON_LED_PIN, HIGH);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
     // Receive the next value
    irrecv.resume();
  }
  if(results.value == Off){
    apagadoTotal();
  }
   if(check == 0){
    opcionesPrev();
  }
  if ((unsigned long)(millis() - previousMillis) >= interval) {
    if(check == 1){
      previousMillis = millis();
      opciones2();
  }
  }

}

void opciones(){
  ant = 0;
  check = 1;
  relayOn();
  delay(4000);    
  irOn();
}

void opciones2(){
  check = 0;
  ant = 1;
  irOff();
  delay(3000);
  relayOff();
  delay(4000);
}

void apagadoTotal(){
  check = 0;
  blinkRelLed();
  irOff();
  delay(3000);
  relayOff();
  delay(4000);
}

void opcionesPrev(){
  if(results.value == On){
    opciones();
  }
}



void irOn(){
  irsend.sendRaw(powerOn,68,38);
}

void irOff(){
  irsend.sendRaw(powerOff,68,38);
}

void relayOff(){
  digitalWrite(RELAY_PIN, LOW);
  digitalWrite(RELAY_LED_PIN, LOW);
}

void relayOn(){
  digitalWrite(RELAY_PIN, HIGH);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

void blinkRelLed(){  
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

PD: Apenas escrito la parte del reconocimiento del IR, y en base a eso prender o apagar el relé (sin bucles ni nada) anduvo las cuatro veces y siempre me tomaba nuevos códigos, pero despues no anda más, aunque no toque nada relacionado al receptor IR.

Muchas gracias.

Nicolás.

Esto esta mal

int interval    = 20000;

Debe ser

unsigned long interval  = 20000;

y esto

if ((unsigned long)(millis() - previousMillis) >= interval) {
    if(check == 1){
      previousMillis = millis();
      opciones2();
   }
  }

debe ser asi con interval definido como ya te dije y

// En la definición de variables
unsigned long previousMillis = millis();
// en el loop

if (millis() - previousMillis >= interval) {
    if(check == 1){
      previousMillis = millis();
      opciones2();
   }
}

Hola surbyte, muchas gracias por tu respuesta.

Modifique lo que dijiste y pude solucionar el problema 1 (que en el primer post me equivoque, debe volver al paso 2, pero eso esta solucionado), pero aun asi no reconoce otra señal IR, solo se queda con la primera. Si le mando una señal de apagado al comienzo, realiza la fucion "apagadoTotal()", pero despues no toma la señal de encendido, y viceversa.

Nicolas

Hola,

Modifique parte del código para cambiar el método de espera con la función “millis()”, por lo que descargué la librería “Timer” y lo reemplazé por este. De esta manera, pude crear una función aparte llamada “takeReading” para que tome la señal IR, aún así tengo el mismo problema de antes (el n° 2).

#include <IRremote.h>
#include "Timer.h"

unsigned long On = 0x9E00040A; // where XXXXXXXX is on our your remote's values
unsigned long Off = 0x8E00040A; // where XXXXXXXX is another button on your remote

#define ON_LED_PIN 10
#define RELAY_PIN 9
#define RELAY_LED_PIN 12
int RECV_PIN = 11;
int check = 0;
int ant = 0;
int apg = 0;
int readNeed = 1;
int varNU1 = 0;
int varNU2 = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;
Timer t;
void irOn();
void irOff();
void relayOn();
void relayOff();
void blinkRelLed();
void opciones();
void opciones2();
void apagadoTotal();
void opcionesPrev();
void blinkRelLedN();
void takeReading();
void waitMilis();

unsigned int powerOn[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};
unsigned int powerOff[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};


void setup() {
  Serial.begin(9600);
  pinMode(RELAY_LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(ON_LED_PIN, OUTPUT);
  digitalWrite(ON_LED_PIN, HIGH);
  irrecv.enableIRIn(); // Start the receiver
  t.every(1, takeReading);
  t.every(20000, waitMilis);
}

void loop() {
  if(readNeed == 1){
  t.update();
  }
  if(apg == 0){
    if(results.value == Off){
      apagadoTotal();
  }
  }
  Serial.println("I am in a loop");
  if(check == 0){
    opcionesPrev();
  }
  if(ant == 1){
    opciones();
  }
  if(check == 1){
    Serial.println("I should be able to turn it off at this moment");
  }
}

void opciones(){
  readNeed = 1;
  ant = 0;
  check = 1;
  relayOn();
  delay(4000);    
  irOn();
}

void opciones2(){
  readNeed = 0;
  check = 0;
  ant = 1;
  blinkRelLedN();
  irOff();
  delay(3000);
  relayOff();
  delay(4000);
}

void apagadoTotal(){
  apg = 1;
  check = 0;
  blinkRelLed(); 
  irOff();
  delay(3000);
  relayOff();
  delay(4000);
}

void opcionesPrev(){
  if(results.value == On){
    opciones();
  }
}

void takeReading(){
  if (irrecv.decode(&results)) {
   irrecv.resume();
   }
}

void waitMilis(){
  if(check == 1){
    opciones2();
  }
}



void irOn(){
  irsend.sendRaw(powerOn,68,38);
}

void irOff(){
  irsend.sendRaw(powerOff,68,38);
}

void relayOff(){
  digitalWrite(RELAY_PIN, LOW);
  digitalWrite(RELAY_LED_PIN, LOW);
}

void relayOn(){
  digitalWrite(RELAY_PIN, HIGH);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

void blinkRelLed(){  
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

void blinkRelLedN(){  
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(350);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(350);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(350);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(350);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(350);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

Espero que me puedan ayudar.

Nicolás.

No me habia percatado de los delays en tus 4 etapas. Estas seguro que no complican el uso de IRremote?

Estamos atascados acá?

2- Señal IR de prendido recibida, prender relé, esperar 3-4 segundos (todavía no decidí) mandar señal IR de prendido al A/C.

Activas el Relé
esperas 4 segundos (lo que dice el código)
mandas IR prender al Aire Acondicionado

Es decir esta parte ?

void opciones(){
  ant = 0;
  check = 1;
  relayOn();
  delay(4000);    
  irOn();
}

relayOn() es facil de comprobar
delay(4000) no debe fallar

irOn() no FUNCIONA?

Hola,

Al problema n. 2 me refería a que no toma la segunda señal IR, así sea prendido o apagado, no que el problema esta en la etapa 2 (me referia al 2º problema, el que se encuentra en el primer post).

Aún así esos delays están bien, puesto que no quiero apagar el equipo en ese momento, solo quiero tener la opción de hacerlo en esos 10-15 min.

No creo que complique el uso del IRRemote, ya que es solo un delay y nada mas. Con el uso de la función “Serial.prinln(”");" puedo saber si ya llego a la etapa donde debe esperar a la señal de apagado, no se si me explico. (Si lo queres ver esta en mi último post, no lo pongo acá porque estoy con el celular y no me deja).

Se que funcionan tanto la función “irOn()” como la “irOff()” porque ese código IR que manda es el de unos parlantes (luego cuando lo vaya a probar definitivamente le voy a poner el código del aire) y los pone en “Mute”.

Como dije anteriormente el fallo esta en que no me toma la segunda señal IR, aúnque la primera señal sea apagado o prendido, la próxima no la toma.

Espero haberme expresado bien.

Muchas gracias.

Nicolás.

Ok, hice algunas pruebas y descubrí (al menos creo) que el error esta cuando creo (aunque no la llame) la función “irOn()”, supongo que pasará lo mismo con el “irOff()”, pero no lo probé.

Cuando creaba esta función (aunque no la llame), SOLO recibía UN codigo IR. Les dejo el código por si creen que me equivoque:

#include <IRremote.h>

#define ON_LED_PIN 10
#define RELAY_PIN 9
#define RELAY_LED_PIN 12

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;

void relayOn();
void relayOff();
void primeraParte();

unsigned long On = 0x9E00040A; // where XXXXXXXX is on our your remote's values
unsigned long Off = 0x8E00040A; // where XXXXXXXX is another button on your remote
unsigned int powerOn[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};
unsigned int powerOff[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};



void setup(){
  Serial.begin(9600);
  pinMode(RELAY_LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(ON_LED_PIN, OUTPUT);
  digitalWrite(ON_LED_PIN, HIGH);
  irrecv.enableIRIn(); // Start the receiver
}

void loop(){
  if (irrecv.decode(&results)) {
       switch (results.value) {
         case 0x9E00040A:
           primeraParte();
           break;
         case 0x8E00040A:
           relayOff();
           break;
         }
   irrecv.resume();
  }
}


void primeraParte(){
  relayOn();
  delay(500);
}

void relayOn(){
  digitalWrite(RELAY_PIN, HIGH);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

void relayOff(){
  digitalWrite(RELAY_PIN, LOW);
  digitalWrite(RELAY_LED_PIN, LOW);
}

Nicolas.

Hola, por fin!! Luego de cuatro días y cinco sketchs!! Lo que le faltaba era la funcion “irrecv.enableIRIn();” que, según la persona que escribió la librería, se debe poner SIEMPRE después de utilizar un LED IR para volver a activar el receptor IR (supongo que será para evitar falsos positivos).

Acá les dejo el código terminado. Muchas gracias por su ayuda. Si hay algo que este mal corríjanme.

#include <IRremote.h>

unsigned long On = 0x9E00040A; // where XXXXXXXX is on our your remote's values
unsigned long Off = 0x8E00040A; // where XXXXXXXX is another button on your remote

#define ON_LED_PIN 10
#define RELAY_PIN 9
#define RELAY_LED_PIN 12
int RECV_PIN = 11;
int check = 0;
int ant = 0;
int apg = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;
void irOn();
void irOff();
void relayOn();
void relayOff();
void blinkRelLed();
void blinkRelLedN();
void opciones();
void opciones2();
void apagadoTotal();
void opcionesPrev();

unsigned int powerOn[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};
unsigned int powerOff[68] = {8950, 4350, 650, 450, 650,450,650, 450, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 1550, 700, 1500, 700, 1550, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 700, 400, 650, 450, 650, 450, 650, 500, 600,1600, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 700, 1500, 700, 1500, 700, 400, 650, 1600, 650};
unsigned long currentMillis = millis();
unsigned long previousMillis = 0;
unsigned long interval 	= 7000;


void setup() {

  Serial.begin(9600);
  pinMode(RELAY_LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(ON_LED_PIN, OUTPUT);
  digitalWrite(ON_LED_PIN, HIGH);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
     // Receive the next value
    irrecv.resume();
  }
  if(apg == 0){
    if(results.value == Off){
      apagadoTotal();
  }
  }
  if(check == 0){
    opcionesPrev();
  }
  if(ant == 1){
    opciones();
  }
  if (millis() - previousMillis >= interval) {
    if(check == 1){
      previousMillis = millis();
      opciones2();
      irrecv.enableIRIn();
  	}
}
  if(check == 1){
    Serial.println("I should be able to turn it off at this moment");
  }
}

void opciones(){
  apg = 0;
  ant = 0;
  check = 1;
  relayOn();
  delay(4000);    
  irOn();
  previousMillis = millis();
  irrecv.enableIRIn();
}

void opciones2(){
  check = 0;
  ant = 1;
  blinkRelLedN();
  irOff();
  delay(3000);
  relayOff();
  delay(4000);
  irrecv.enableIRIn();
}

void apagadoTotal(){
  apg = 1;
  check = 0;
  blinkRelLed();
  irOff();
  delay(3000);
  relayOff();
  delay(4000);
  irrecv.enableIRIn();
}

void opcionesPrev(){
  if(results.value == On){
    opciones();
  }
}



void irOn(){
  irsend.sendRaw(powerOn,68,38);
}

void irOff(){
  irsend.sendRaw(powerOff,68,38);
}

void relayOff(){
  digitalWrite(RELAY_PIN, LOW);
  digitalWrite(RELAY_LED_PIN, LOW);
}

void relayOn(){
  digitalWrite(RELAY_PIN, HIGH);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

void blinkRelLed(){  
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(100);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(100);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

void blinkRelLedN(){  
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(350);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(350);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(350);
  digitalWrite(RELAY_LED_PIN, HIGH);
  delay(350);
  digitalWrite(RELAY_LED_PIN, LOW);
  delay(350);
  digitalWrite(RELAY_LED_PIN, HIGH);
}

Nuevamente, muchas gracias por todo.

Nicolás.