crankyoldgit / IRremoteESP8266

Infrared remote library for ESP8266/ESP32: send and receive infrared signals with multiple protocols. Based on: https://github.com/shirriff/Arduino-IRremote/
GNU Lesser General Public License v2.1
2.98k stars 833 forks source link

Need help with COOLIX vs COOLIX48 #1748

Closed Pigi-102 closed 2 years ago

Pigi-102 commented 2 years ago

I've followed the web-ac-controller example to create a sketch to control my AC unit. The unit use the 24 bit protocol ( derived by testing the remote control with the irdump example ) but whatever I do in my sketch I always send out a 48-bit message vs a 24-bit. Cannot find anywhere a way to force the use of the 24-bit protocol.

Can someone share a bit of light on this ?

Here to sketch:

#include <WebOTA.h>
#include <EEPROM.h>

#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Coolix.h>
const uint16_t kIrLed = D7;  
#define AUTO_MODE kCoolixAuto
#define COOL_MODE kCoolixCool
#define DRY_MODE kCoolixDry
#define HEAT_MODE kCoolixHeat
#define FAN_MODE kCoolixFan

#define FAN_AUTO kCoolixFanAuto
#define FAN_MIN kCoolixFanMin
#define FAN_MED kCoolixFanMed
#define FAN_HI kCoolixFanMax
#define SEND_COOLIX true
#undef SEND_COOLIX48 

IRCoolixAC ac(kIrLed);  // Set the GPIO to be used to sending the message.

int HeatingPin = D7;
const char* ssid = "SSID";                 // Your personal network SSID
const char* wifi_password = "PASSWORD";  // Your personal network password

String location = "AC_REMOTE";

// MQTT
const char* mqtt_server       = "192.168.x.x";  // IP of the MQTT broker
const char* mqtt_username     = "mqtt_usr"; // MQTT username
const char* mqtt_password     = "Password"; // MQTT password
const char* clientID          = (location).c_str(); // MQTT client ID

int brightness = 0;
int fade = 1;
unsigned long new_time = 0;
unsigned long old_time = 0;
WiFiClient wifiClient;
PubSubClient client(mqtt_server, 8883, wifiClient); 

// Custom function to connet to the MQTT broker via WiFi
void connect_WiFi(){
  boolean LEDSTS = LOW;

  Serial.print("Connecting to ");
  Serial.println(ssid);
  Serial.println(WiFi.hostname());
  // Connect to the WiFi
  WiFi.setHostname(clientID);
  WiFi.begin(ssid, wifi_password);

  // Wait until the connection has been confirmed before continuing
  pinMode(D0, OUTPUT);     // Initialize the D0 pin as an output Using Led to check if it is connect or connecting
  digitalWrite(D0, LEDSTS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    LEDSTS=LEDSTS^1;
    digitalWrite(D0, LEDSTS);
  }
  digitalWrite(D0, LOW);    // I'm connected. Led goes off

  // Debugging - Output the IP Address of the ESP8266
  Serial.println("");
  Serial.print("Version: ");
  Serial.println(vers);
  Serial.println("WiFi connected");
  Serial.println(WiFi.hostname());
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println(humidity_topic);
  Serial.println(temperature_topic);
}

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic = String((char*)topic);

     if ( ModeSt_Rec == "cool" )     { ac.setMode(kCoolixCool); }
     if ( ModeSt_Rec == "dry" )      { ac.setMode(kCoolixDry); }
     if ( ModeSt_Rec == "auto" )     { ac.setMode(kCoolixAuto); }
     if ( ModeSt_Rec == "heat" )     { ac.setMode(kCoolixHeat); }
     if ( ModeSt_Rec == "fan_only" ) { ac.setMode(kCoolixFan); }
     if ( ModeSt_Rec == "off" )      { ac.setPower(false); }// Tutti i parametri restano come sono. Spengo l'unita'

     if ( ModeSt_Rec == "auto" )     {   ac.setFan(kCoolixFanAuto0); }   // Se in auto il mode allora auto0
     if ( FanSt_Rec == "auto" )      {   ac.setFan(kCoolixFanAuto); }
     if ( FanSt_Rec == "max" )       {   ac.setFan(kCoolixFanMax); }
     if ( FanSt_Rec == "med" )       {   ac.setFan(kCoolixFanMed); }
     if ( FanSt_Rec == "min" )       {   ac.setFan(kCoolixFanMin); }
     TempSt_Rec = String((char*)payload);
     ac.setTemp(int (TempSt_Rec.toFloat()));

  if(strTopic == switch1_topic )
    {
    switch1 = String((char*)payload);
    Serial.println(switch1);
    if(switch1 == "ON")
      {
        ac.on();                 // Accendiamo
        digitalWrite(HeatingPin, HIGH);
      }
    else
      {
        ac.off();                 // Spegniamo
        digitalWrite(HeatingPin, LOW);
        ModeSt_Rec1 = "off";
      }
      ac.send();
      client.publish(modest_topic, ModeSt_Rec1.c_str());
    }
}

void setup() {

  Serial.begin(9600);
  ac.begin();                             // Inizializzazione AC
  dht.begin();                            // Initializa DHT11/12 library
                                          // Moved in setup to avoid connecting every time.
  delay(1000);       
  connect_WiFi();
  wdt_enable(5000);                       // Watchdog  timer to 5 seconds
  pinMode(BUILTIN_LED, OUTPUT);           // Initialize the BUILTIN_LED pin as an output
  pinMode(D0, OUTPUT);                    // Initialize the D0 pin as an output for Connection Led Indicator
  analogWrite(BUILTIN_LED, brightness);   // Let's put BUILTIN_LED as analog for a nice effet of the led
  Serial.setTimeout(2000);

  pinMode(HeatingPin, OUTPUT);

  // Connect to MQTT Broker
  // client.connect returns a boolean value to let us know if the connection was successful.
  if (client.connect(clientID, mqtt_username, mqtt_password)) {
    Serial.println("Connected to MQTT Broker! and subscribe ");
    client.setCallback(callback);
    client.subscribe(switch1_topic);
  }
  else {
    Serial.println("Connection to MQTT Broker failed...");
  }
  old_time = millis();
}

void loop() {
  wdt_reset();
  webota.handle();

  if (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("NotConn");
    connect_WiFi();
  }

     String hs="Hum: "+String((float)h)+" % ";
     String ts="Temp: "+String((float)t)+" C ";

     if (!client.publish(temperature_topic, String(t).c_str())) {
       client.connect(clientID, mqtt_username, mqtt_password);
       delay(10); // This delay ensures that client.publish doesn't clash with the client.connect call
       client.publish(temperature_topic, String(t).c_str());
     }

     // PUBLISH to the MQTT Broker (topic = Humidity, defined at the beginning)
     if (!client.publish(humidity_topic, String(h).c_str())) {
          client.connect(clientID, mqtt_username, mqtt_password);
          delay(10); // This delay ensures that client.publish doesn't clash with the client.connect call
          client.publish(humidity_topic, String(h).c_str());
     }
  }

}
crankyoldgit commented 2 years ago

but whatever I do in my sketch I always send out a 48-bit message vs a 24-bit.

Can you supply a capture of what it is sending? And what kind of settings you set the IRCoolixAC class to before sending it.

At first glance, I can't see anything obviously wrong in your code. Also, what version/revision of the library are you using?

Have you tried simplifying your code down to the bare minimum that produces the fault/issue? e.g. Like one of the many "TurnOn" examples.

IRCoolixAC::send() should only ever produce a "COOLIX" message, not a "COOLIX48" message. Basically, a COOLIX message is a subset of COOLIX48 messages. COOLIX messages physically contain 48-bits too, but there is a pattern to them. i.e. every second byte is inverted. That means we can shrink it to 24 bits. A COOLIX48 message is just one that does not follow that pattern.

crankyoldgit commented 2 years ago

define SEND_COOLIX true

undef SEND_COOLIX48

FYI, that will not have the effect you think it does.

Pigi-102 commented 2 years ago

Hello, that's what get captured:

Timestamp : 000013.780
Library   : v_IRREMOTEESP8266_VERSION_MAJOR._IRREMOTEESP8266_VERSION_MINOR._IRREMOTEESP8266_VERSION_PATCH

Protocol  : COOLIX48
Code      : 0xB24D7B84E01F (48 Bits)
uint16_t rawData[199] = {4642, 4502,  514, 1706,  516, 624,  488, 1704,  514, 1702,  516, 624,  488, 624,  488, 1702,  514, 626,  488, 620,  488, 1702,  4
90, 620,  512, 620,  488, 1728,  488, 1704,  514, 624,  488, 1704,  514, 620,  488, 1702,  490, 1722,  488, 1724,  514, 1728,  488, 600,  512, 1728,  490, 1706,  512, 1698,  488, 646,  486, 622,  462, 646,  488
, 624,  488, 1704,  514, 626,  488, 628,  460, 1724,  514, 1702,  514, 1724,  462, 646,  488, 624,  488, 624,  488, 626,  486, 602,  488, 646,  460, 648,  486, 626,  488, 1704,  486, 1724,  488, 1748,  488, 170
4,  514, 1708,  488, 5312,  4648, 4494,  488, 1704,  486, 646,  486, 1698,  512, 1700,  488, 646,  462, 646,  486, 1728,  462, 648,  484, 622,  462, 1724,  510, 622,  488, 626,  488, 1702,  514, 1728,  490, 626
,  488, 1730,  462, 646,  488, 1704,  512, 1724,  486, 1698,  514, 1728,  488, 626,  488, 1728,  488, 1704,  514, 1700,  512, 620,  486, 620,  488, 620,  486, 626,  490, 1728,  488, 626,  488, 628,  460, 1750, 
 488, 1728,  488, 1704,  488, 646,  488, 620,  488, 624,  488, 626,  488, 626,  462, 646,  462, 644,  488, 626,  488, 1728,  490, 1704,  486, 1724,  514, 1724,  488, 1728,  488};  // COOLIX48 B24D7B84E01F
uint64_t data = 0xB24D7B84E01F;

This is ( or at least should be ) an "off" messages. Using the same decoder, with the original IR Remote the message for an of is the following:

Timestamp : 000023.275
Library   : v_IRREMOTEESP8266_VERSION_MAJOR._IRREMOTEESP8266_VERSION_MINOR._IRREMOTEESP8266_VERSION_PATCH

Protocol  : COOLIX
Code      : 0xB27BE0 (24 Bits)
Mesg Desc.: Power: Off
uint16_t rawData[199] = {4386, 4384,  528, 1618,  528, 546,  526, 1618,  528, 1620,  528, 546,  526, 546,  526, 1618,  528, 546,  526, 546,  528, 1618,  528, 546,  528, 546,  526, 1618,  528, 1620,  528, 546,  528, 1618,  526, 546,  526, 1620,  528, 1618,  504, 1642,  528, 1618,  504, 572,  502, 1644,  528, 1618,  504, 1644,  528, 544,  502, 570,  502, 570,  502, 570,  524, 1622,  502, 572,  502, 570,  502, 1644,  502, 1644,  504, 1642,  504, 570,  502, 570,  502, 570,  502, 570,  502, 570,  502, 570,  502, 572,  502, 570,  526, 1620,  502, 1644,  502, 1644,  502, 1644,  504, 1644,  502, 5232,  4412, 4360,  526, 1620,  502, 570,  526, 1620,  502, 1644,  502, 572,  526, 546,  526, 1618,  502, 572,  502, 572,  526, 1620,  522, 550,  502, 572,  526, 1618,  528, 1620,  526, 546,  526, 1620,  526, 546,  526, 1618,  528, 1618,  528, 1618,  528, 1618,  528, 546,  526, 1618,  526, 1620,  528, 1618,  528, 546,  526, 546,  528, 546,  526, 546,  526, 1618,  528, 546,  528, 544,  528, 1618,  528, 1618,  528, 1618,  528, 544,  528, 546,  526, 546,  528, 544,  528, 544,  528, 544,  526, 546,  528, 544,  528, 1616,  528, 1618,  528, 1618,  528, 1618,  530, 1616,  528};  // COOLIX B27BE0
uint64_t data = 0xB27BE0;

Library version should be the lastone as I have d/loaded with the Arduino ide a couple of days ago From the Ide library manager I have the 2.8.1 version.

Pigi

crankyoldgit commented 2 years ago

0xB27BE0 is the correct code for "Power Off" and it turns out 0xB24D7B84E01F is the 48 bit version of the 24-bit 0xB27BE0. I hand checked it. So that leaves a slight timing tolerance issue in the COOLIX detection/decoding as the likely issue. i.e. This is a false negative. I'll try to see if I can diagnose it deeper to see which part of the message if failing.

While I do that, I suggest you tweak this value/line in the dump code: https://github.com/crankyoldgit/IRremoteESP8266/blob/f8e5662776102e57cf4c03af5e9fc54d14a07b19/examples/IRrecvDumpV2/IRrecvDumpV2.ino#L112 Try something larger than 25. i.e. 30 or 35. It may give you the correct results with that.

crankyoldgit commented 2 years ago

Yep. a Tolerance value of 27 would have matched that "Off" message as a 24-bit COOLIX message.

crankyoldgit commented 2 years ago

In short, the real device might accept it as is.

Pigi-102 commented 2 years ago

I'm actually using the IRrecvDumpV3 as receiver and already has the line you suggest. Could I modify the line

const uint8_t kTolerancePercentage = kTolerance;  // kTolerance is normally 25%

with a bit more tollerance so I can see the message ?

const uint8_t kTolerancePercentage = 30 

I'm not sure about my code and would like to see all messages I can send before trying to the real device.

Thnks for your time !

Pigi-102 commented 2 years ago

Yes ! I do confim that modifying with 30 will make dump works

Thanks a million for you time !

crankyoldgit commented 2 years ago

FYI, the changes mentioned above have now been included in the new v2.8.2 release of the library.