Heatpump controller



  • Hello

    First of all, I know very little about programming and Arduino but I am trying to learn.

    I just dont get the whole picture about how to use this library in the right way for this project.

    I want a microcontroller for controlling my heatpump via OpenHAB. I have sucessfully tried this library with the simple example provided in the library and it works https://github.com/ToniA/arduino-heatpumpir

    What I want to do is to make a sketch that is based on a arduino + the nrf24 and the mysensors library.
    If you look in the sample sketch for the heatpump library https://github.com/ToniA/arduino-heatpumpir/blob/master/examples/simple/simple.ino it should be quite simple to adapt this.

    I dont have the need to send variables over the nrf24 i can hardcode maybe 4-5 different states the heatpump library sends and then just control them with different values (ie value 1 = heatpumpIR[i]->send(irSender, POWER_ON, MODE_HEAT, FAN_2, 24, VDIR_UP, HDIR_AUTO);, value 2 is maybe power off or something

    Does anyone have a clue about how to customize this to a mysensor?
    Which sensot item etc should i use?

    Any help and input in this matter will be higly appreciated


  • Contest Winner

    you could try to get a basic device like a relay or a thermometer and explore.

    then, once you get through the steps, and you know what it takes to put it together, you will have an easier time of it.

    catch your first bass before you go marlin fishing kind-of-thing.



  • Hello
    You are of course right
    I have successfully made a couple of temperature sensors and more or less also got a humid understanding about how the code works.
    What I hesitate about now is how to go further.
    I think the easiest is to evaluate the incoming message in a switch statement from where I send 5 different commands

    I revert with some kind off code later this weekend

    All input and help is highly appreciated



  • Hello
    I have made the following code (actually not, made i have combined the heatpump example sketch and the ir mysensor sketch to make a controller that can turn ON/OFF the heatpump. But... It doesnt work. I am not sure which node id the controller gets **(how to check that??) **

    How is the MQTT message structured?
    I have tried to send the following with an android app (who is connected to the gateway off course)
    Topic: MyMQTT/22/1/V_LIGHT
    Message:1

    Have also tried node id 23-28 without result.

    I have a couple of temperature nodes working with MQTT and Openhab so the "system" is working for sure.
    But its easier to just find a published message. Harder to publish i maybe??
    Any ideas/suggestions?

    One thing I have noticed is that I dont get the "Starting" message in the serial monitor.
    Is maybe something happening which stalls the code before that?

    All help I can get is highly appreciated!!
    ps, the code inside the do loops is already tested and confirmed working in a simpler sketch without mysensors library.

                  // Example sketch showing how to control ir devices
                  // An IR LED must be connected to Arduino PWM pin 3.
                  // When binary light on is clicked - sketch will send heatpump command with on
                  // When binary light off is clicked - sketch will send heatpump command with off
                  
                  #include <Arduino.h>
                  #include <FujitsuHeatpumpIR.h>
                  #include <PanasonicCKPHeatpumpIR.h>
                  #include <PanasonicHeatpumpIR.h>
                  #include <CarrierHeatpumpIR.h>
                  #include <MideaHeatpumpIR.h>
                  #include <MitsubishiHeatpumpIR.h>
                  #include <SamsungHeatpumpIR.h>
                  #include <MySensor.h>
                  #include <SPI.h>
                  
                  
                  
                  #define CHILD_1  1  // childId
                  
                  IRSender irSender(3); // pin where ir diode is sitting
                  
                  MySensor gw;
                  MyMessage msg(CHILD_1, V_VAR1);
                  
                  HeatpumpIR *heatpumpIR[] = {new PanasonicCKPHeatpumpIR(), new PanasonicDKEHeatpumpIR(), new PanasonicJKEHeatpumpIR(),
                                              new PanasonicNKEHeatpumpIR(), new CarrierHeatpumpIR(), new MideaHeatpumpIR(),
                                              new FujitsuHeatpumpIR(), new MitsubishiFDHeatpumpIR(), new MitsubishiFEHeatpumpIR(),
                                              new SamsungHeatpumpIR(), NULL};
                    // will take away everything except PanasonicJKE when everything ready to reduce sketch size
                  
                  void setup()  
                  {  
                  
                    gw.begin(incomingMessage); // Start listening
                  
                    // Send the sketch version information to the gateway and Controller
                    gw.sendSketchInfo("IR Sensor", "1.0");
                  
                    // Register a sensors to gw. Use binary light for test purposes.
                    gw.present(CHILD_1, S_LIGHT);
                    
                    Serial.begin(9600); // Start serial only for debugging. Will be taken away when development is finished
                    delay(500);
                  
                    Serial.println(F("Starting"));
                    
                  }
                  
                  
                  void loop() 
                  {
                    
                  }
                  
                  
                  
                  void incomingMessage(const MyMessage &message) {
                    // We only expect one type of message from controller. But we better check anyway.
                    if (message.type==V_LIGHT) {
                       int incomingRelayStatus = message.getInt();
                       if (incomingRelayStatus == 1) {
                           
                            int i = 0; //counter
                            prog_char* buf;         
                         
                          do {
                         // Send the same IR command to all supported heatpumps
                                  Serial.print(F("Sending IR to "));
                              
                                  buf = (prog_char*)heatpumpIR[i]->model();
                                  // 'model' is a PROGMEM pointer, so need to write a byte at a time
                                  while (char modelChar = pgm_read_byte(buf++))
                                  {
                                    Serial.print(modelChar);
                                  }
                                  Serial.print(F(", info: "));
                              
                                  buf = (prog_char*)heatpumpIR[i]->info();
                                  // 'info' is a PROGMEM pointer, so need to write a byte at a time
                                  while (char infoChar = pgm_read_byte(buf++))
                                  {
                                    Serial.print(infoChar);
                                  }
                                  Serial.println();
                              
                                  // Send the IR command
                                  heatpumpIR[i]->send(irSender, POWER_ON, MODE_HEAT, FAN_2, 24, VDIR_UP, HDIR_AUTO);
                                  delay(500);
                                }
                                  while (heatpumpIR[++i] != NULL);
                     
                      } else if (incomingRelayStatus == 1) {
                                 
                            int i = 0; //counter
                            prog_char* buf;
                       
                        do {
                                  // Send the same IR command to all supported heatpumps
                                  Serial.print(F("Sending IR to "));
                              
                                  buf = (prog_char*)heatpumpIR[i]->model();
                                  // 'model' is a PROGMEM pointer, so need to write a byte at a time
                                  while (char modelChar = pgm_read_byte(buf++))
                                  {
                                    Serial.print(modelChar);
                                  }
                                  Serial.print(F(", info: "));
                              
                                  buf = (prog_char*)heatpumpIR[i]->info();
                                  // 'info' is a PROGMEM pointer, so need to write a byte at a time
                                  while (char infoChar = pgm_read_byte(buf++))
                                  {
                                    Serial.print(infoChar);
                                  }
                                  Serial.println();
                              
                                  // Send the IR command
                                  heatpumpIR[i]->send(irSender, POWER_OFF, MODE_HEAT, FAN_2, 24, VDIR_UP, HDIR_AUTO);
                                  delay(500);
                                }
                                while (heatpumpIR[++i] != NULL);
                   
                   }
                  }
                  }


  • @Fredrik-Carlsson no ideas?
    How can i see which node id the sensor gets?


  • Admin

    @Fredrik-Carlsson said:

    I am not sure which node id the controller gets

    Which controller? Do you mean the node?

    @Damme might be able to help with the MQTT stuff.

    You should see a "starting" message. If not there might be a code problem.

    loop() should at least contain gw.process() to pick up incoming messages.



  • Haha yes i have forgotten gw process in the loop. that is corrected now.
    Yes i want to know which mqtt address the node has (for example i have 2 temperatures nodes with id MyMQTT/20/ and MyMQTT/21/


  • Admin

    It is usually printed in serial monitor at startup .
    ...or by calling gw.getNodeId();



  • TOUCHDOWN!
    Here is working code. Whit this i can with mymqtt android app publish topic MyMQTT/20/1/V_LIGHT with message "1" for heatpump on (with 24 degrees etc etc) and "0" for heatpump off. I have tried it with my Panasonic heatpump and it works.
    I also added a little serial string in order to find out node Id (mine was 20 then)

    Next step is to increase the different modes.
    I was thinking from beginning of only having 5 different "hardcoded" modes that would actually be more then enough for my use, but it would be really nice to send over variables some how instead so you have complete control of the heatpump from OpenHAB (temp, heatingmode etc). I am just not sure about how long messages you can send with the nrf protocol. Must dig into that

    Thanks for all the help, as I said I have almost no programming nor Arduino knowledge since before. Just starting out.
    // Example sketch showing how to control ir Heatpumps
    // An IR LED must be connected to Arduino PWM pin 3.

          #include <Arduino.h>
          #include <FujitsuHeatpumpIR.h>
          #include <PanasonicCKPHeatpumpIR.h>
          #include <PanasonicHeatpumpIR.h>
          #include <CarrierHeatpumpIR.h>
          #include <MideaHeatpumpIR.h>
          #include <MitsubishiHeatpumpIR.h>
          #include <SamsungHeatpumpIR.h>
          #include <MySensor.h>
          #include <SPI.h>
          
          
          
          #define CHILD_1  1  // childId
          
          IRSender irSender(3); // pin where ir diode is sitting
          
          MySensor gw;
          MyMessage msg(CHILD_1, V_VAR1);
          
          HeatpumpIR *heatpumpIR[] = {new PanasonicCKPHeatpumpIR(), new PanasonicDKEHeatpumpIR(), new PanasonicJKEHeatpumpIR(),
                                      new PanasonicNKEHeatpumpIR(), new CarrierHeatpumpIR(), new MideaHeatpumpIR(),
                                      new FujitsuHeatpumpIR(), new MitsubishiFDHeatpumpIR(), new MitsubishiFEHeatpumpIR(),
                                      new SamsungHeatpumpIR(), NULL};
            // will take away everything except PanasonicJKE when everything ready to reduce sketch size
          
          void setup()  
          {  
          
            gw.begin(incomingMessage); // Start listening
          
            // Send the sketch version information to the gateway and Controller
            gw.sendSketchInfo("IR Sensor", "1.0");
          
            // Register a sensors to gw. Use binary light for test purposes.
            gw.present(CHILD_1, S_LIGHT);
            
            Serial.begin(9600); 
            delay(500);
          
            Serial.println(F("Starting"));
            Serial.print("Node Id is set to: ");
            Serial.println(gw.getNodeId());
          }
          
          
          void loop() 
          {
          
            gw.process();
           
          }
          
          
          
          void incomingMessage(const MyMessage &message) {
            // We only expect one type of message from controller. But we better check anyway.
            if (message.type==V_LIGHT) {
               int incomingRelayStatus = message.getInt();
               if (incomingRelayStatus == 1) {
                   
                    int i = 0; //counter
                    prog_char* buf;         
                 
                  do {
                 // Send the same IR command to all supported heatpumps
                          Serial.print(F("Sending IR to "));
                      
                          buf = (prog_char*)heatpumpIR[i]->model();
                          // 'model' is a PROGMEM pointer, so need to write a byte at a time
                          while (char modelChar = pgm_read_byte(buf++))
                          {
                            Serial.print(modelChar);
                          }
                          Serial.print(F(", info: "));
                      
                          buf = (prog_char*)heatpumpIR[i]->info();
                          // 'info' is a PROGMEM pointer, so need to write a byte at a time
                          while (char infoChar = pgm_read_byte(buf++))
                          {
                            Serial.print(infoChar);
                          }
                          Serial.println();
                      
                          // Send the IR command
                          heatpumpIR[i]->send(irSender, POWER_ON, MODE_HEAT, FAN_2, 24, VDIR_UP, HDIR_AUTO);
                          delay(500);
                        }
                          while (heatpumpIR[++i] != NULL);
             
              } else if (incomingRelayStatus == 0) {
                         
                    int i = 0; //counter
                    prog_char* buf;
               
                do {
                          // Send the same IR command to all supported heatpumps
                          Serial.print(F("Sending IR to "));
                      
                          buf = (prog_char*)heatpumpIR[i]->model();
                          // 'model' is a PROGMEM pointer, so need to write a byte at a time
                          while (char modelChar = pgm_read_byte(buf++))
                          {
                            Serial.print(modelChar);
                          }
                          Serial.print(F(", info: "));
                      
                          buf = (prog_char*)heatpumpIR[i]->info();
                          // 'info' is a PROGMEM pointer, so need to write a byte at a time
                          while (char infoChar = pgm_read_byte(buf++))
                          {
                            Serial.print(infoChar);
                          }
                          Serial.println();
                      
                          // Send the IR command
                          heatpumpIR[i]->send(irSender, POWER_OFF, MODE_HEAT, FAN_2, 24, VDIR_UP, HDIR_AUTO);
                          delay(500);
                        }
                        while (heatpumpIR[++i] != NULL);
           
           }
          }
          }

  • Hero Member

    @Fredrik-Carlsson

    Nice Job!



  • well, i have run into some problems. It doesnt have anything to do with the sketch though. Its either OpenHab or the gateway that is causing headache.

    First of all, I have changed the code into this:

                // Example sketch showing how to control ir Heatpumps
                // An IR LED must be connected to Arduino PWM pin 3.
                
                
                #include <Arduino.h>
                #include <PanasonicHeatpumpIR.h>
                #include <MySensor.h>
                #include <SPI.h>
                
                
                
                #define CHILD_1  1  // childId
                
                IRSender irSender(3); // pin where ir diode is sitting
                
                MySensor gw;
                MyMessage msg(CHILD_1, V_VAR1);
                
                HeatpumpIR *heatpumpIR[] = {new PanasonicJKEHeatpumpIR(), NULL};
                  // will take away everything except PanasonicJKE when everything ready to reduce sketch size
                
                void setup()  
                {  
                
                  gw.begin(incomingMessage); // Start listening
                
                  // Send the sketch version information to the gateway and Controller
                  gw.sendSketchInfo("IR Sensor", "1.0");
                
                  // Register a sensors to gw. Use binary light for test purposes.
                  gw.present(CHILD_1, S_HEATER);
                  
                  Serial.begin(9600); 
                  delay(500);
                
                  Serial.println(F("Starting"));
                  Serial.print("Node Id is set to: ");
                  Serial.println(gw.getNodeId());
                }
                
                
                void loop() 
                {
                
                  gw.process();
                 
                }
                
                
                
                void incomingMessage(const MyMessage &message) {
                  // We only expect one type of message from controller. But we better check anyway.
                  if (message.type==V_HEATER) {
                     int incomingHeatingStatus = message.getInt();
                     if (incomingHeatingStatus == 0) {
                                heatpumpIR[0]->send(irSender, POWER_OFF, MODE_HEAT, FAN_AUTO, 22, VDIR_AUTO, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                        } else if (incomingHeatingStatus == 1) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 21, VDIR_AUTO, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 2) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 22, VDIR_AUTO, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 3) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 23, VDIR_AUTO, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 4) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 24, VDIR_AUTO, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 5) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 25, VDIR_AUTO, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 6) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 22, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 7) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_1, 22, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 8) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_3, 22, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 9) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_HEAT, FAN_4, 22, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 10) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_COOL, FAN_AUTO, 18, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 11) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_COOL, FAN_AUTO, 20, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              } else if (incomingHeatingStatus == 12) {
                                heatpumpIR[0]->send(irSender, POWER_ON, MODE_COOL, FAN_AUTO, 22, VDIR_UP, HDIR_AUTO);
                                delay(500);
                                Serial.println("Setting mode to ");
                                Serial.println(incomingHeatingStatus);
                              }
                }
                }
    

    With the Android app MyMQTT I have tried the different modes and all works, Currently the scetch has been up running a couple of days without problems.

    The problem is when i try to do this from OpenHAB.
    First of all, the Mqtt binding IS working, at least with inbound messages because I have also a couple of temperature sensors and that works fine. But when i try with the following setup the command line of openhab shows: "Heatpump received command ON", but nothing is happening with the arduino. Very strange. Any ideas?

    Openhab Item:

           Switch Heatpump (varmesystem,All)      {mqtt=">[mysensor:MyMQTT/20/1/V_HEATER:command:ON:1],>      [mysensor:MyMQTT/20/1/V_HEATER:command:OFF:0]"}
    

    OpenHAB Sitemap:

         Switch item=Heatpump label="VΓ€rmepump"
    

    Any ideas what is going wrong?



  • Well, after a few restarts of both the node, the gateway and openhab it suddenly works.



  • Hi,

    Thank you for the inspiration. I skuld like to use this to control my Daikin heatpump in my cabin. Unfortunatley I am not able to travel there for I while to access the remote. I think I need it to analyze the signal since Daikin is not supported by the library you used.

    I am thinking just two buttons (on 22 degrees/ on 10 degrees)

    Did you stumble over any Daikin codes while working on this project?

    Maybe it is possible to use the code these guys decoded http://www.hifi-remote.com/forums/viewtopic.php?t=11769



  • Hello
    nice that you cna use it for something πŸ™‚
    Sorry, I have no idea regarding Daikin, but if you build sometihng to record the codes with maybe you can figure it out and just add that to the library somehow?

    Anyway, i have thought more about this and i do actually want to be able to make it a little smarter than the code above.
    It would be nice if its possible to send a whole string direct from the controller. ie "send(irSender, POWER_ON, MODE_HEAT, FAN_AUTO, 21, VDIR_AUTO, HDIR_AUTO)" Then I can on the controller side make all the logic and that way have complete control of how the heatpump behaves.

    I have tried to search a little, but can not find any concrete answer. How big is the maximum size of the payload you can send with this library?


  • Admin

    Answer in big blue box here:
    http://www.mysensors.org/build/serial_api

    25 bytes.



  • @johnr

    I'm taking my first steps with IR sender/receiver because I'm also looking for controlling my DAIKIN heatpump.
    I assembled IR receiver, IR sender and nano and loaded From the examples IR Sender/Receiver sketch.
    It works with the remote of my Samsung TV, which it recognises as NEC.
    Daikin is not recognized.
    My Panasonic TV remote is not recognized.
    My Telenet Set-Top box remote is not recognized.
    I guess there is a IRlib for Panasonic, right ?

    Thx, guys !



  • Nice to see that my little HeatpumpIR library made it all the way here πŸ™‚

    I'm also quite new to MySensors, I actually just started today, I've had all the necessary hardware on my table for some weeks now... My goal is to power a (physically) small MySensors device directly from the Panasonic heatpump, and hide everything within the indoor unit's covers, and have it fully controlled by Domoticz. There's quite a bit of work to do, as for example Domoticz does not have a suitable devuce type yet.

    And how about MySensors, I'm still quite a newbie on the messaging schema... Is there a schema which could be used to communicate all of these within the same message:

    • ON/OFF information (0 or 1)
    • Temperature information (integer from 8 to 30)
    • Fan speed information (integer from 0 to 5)
    • Mode information (COOL, HEAT etc. i.e. integer from 0 to 6)

    What comes to Daikin, it would probably be quite easy to add it into the HeatpumpIR code, provided that I could borrow the remote controller for a while. Or, if somebody else could decode the protocol.



  • ToniA,

    Where are you based? I maybe can send you my remote, if I am sure to get it back πŸ˜‰
    I think it will be a challenge to send all the information with only 25 bytes.



  • In live in Finland...

    I now have the HeatpumpIR working together with Domoticz, so that I can also define which commands to send from Domoticz. And yes, 24 bits is plenty enough πŸ™‚

    https://github.com/ToniA/arduino-heatpumpir/tree/master/examples/MySensorsNode

    @johnr, do you happen to have an infrared receiver module? If you do, I could assist you in decoding the protocol. This is how I for example got the Mitsubishi protocol decoded, I've never had a Mitsubishi remote controller myself...


  • Admin

    Wow, great job @ToniA

    Would you consider creating a pull request with the example and HeatpumpIR library when you feel finished?



  • @hek, I created pull request #211. I think it's good enough, the challenges are really on the Domoticz side.


  • Admin

    Thanks, I'll take a look!



  • I finally managed to get rid of all compiler warnings πŸ™‚ I must say I like your CI build system, I'm also running Jenkins at work, actually running the build system on Jenkins is my primary job at the moment...

    So the heatpump IR sender node is now one of the examples on the MySensors 'development' branch.


  • Admin

    Thanks for the work you've put into the HeatpumpIR library,

    All creds go to @Anticimex who did the setup of the headless Arduino IDE builder in Jenkins. Messy business to get it right πŸ˜‰

    But it is really nice to get intant compiler feedback on changes and pull requests for different platforms and boards.



  • ToniA, I can collect the Daikin remote from my cabin during next week. I have the following IR-reciever, is it enough to decode it per your instructions?

    http://www.ebay.com/itm/380746925201?rmvSB=true



  • Yes, I think it would work. I have used this piece of software to decode the bits from the remote.

    If you have any heatpump/AC remotes at hand, you could try it out already now. It should also work with TV remotes etc. The only thing is that you might need to adjust the limits it's using to tell the one's and zero's apart.



  • Hi Toni,

    inally I was able to fetch the Dakikin remote from my cabin. What type of software did you say you use to decode the remote?



  • Quite a co-incidence, I just finished decoding the Sharp/IVT infrared protocol, and pushed my decoder changes into Github:

    https://github.com/ToniA/Raw-IR-decoder-for-Arduino

    This is the hardware you'd need, just about any Arduino would do, I'm using both Duemilanove and Mega: https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/arduino_irreceiver.png

    If you get the hex sequences and timings out, I can assist with the rest. We can discuss the detail over email (take a look at my Github profile...).





  • Interesting... I took a look at mharizanov's work, and I think I might have a decoder for the protocol here: https://github.com/ToniA/Raw-IR-decoder-for-Arduino

    Would you try if this correctly decodes the protocol? I would also appreciate some full outputs of successful decode, together with the explanation of the state the remote control shows after the button press.

    If the decoder is correct, creating a Daikin module for the HeatpumpIR library will be a piece of cake πŸ™‚



  • mharizanov's version of Daikin was different, the protocol now seems to have one extra frame which seems to carry the wall clock time.

    The HeatpumpIR library now has the initial (untested) Daikin support.



  • Hello,

    I'm trying to build a sensor node to control a Panasonic AirCon and I'm having trouble (using the latest MySensors and Heatpump-IR libs).
    Whenever the node tries to send IR it restarts. I tried switching RF24's CE and CS pins in case the timers conflict and tried to reduce sram usage as much as I could to no avail.

    I'm using a nano and RF24 wireless modules. The hardware works ok with other sketches (for example a simple relay ON/OFF).

    Here's the sketch:

    #include <Arduino.h>
    #include <MySensor.h>  
    #include <MyTransportNRF24.h>
    #include <SPI.h>
    #include <Timer.h>
    #include <avr/pgmspace.h>
    #include <PanasonicHeatpumpIR.h>
    
    
    #define ACW2_CHILD 2           // Id of the AC Warm 2 hours child
    #define ACW6_CHILD 3           // Id of the AC Warm 6 hours child
    
    
    
    MyTransportNRF24 radio(7, 8, RF24_PA_MAX);
    
    MySensor gw(radio);
    
    MyMessage acw2Msg(ACW2_CHILD, V_LIGHT);
    MyMessage acw6Msg(ACW6_CHILD, V_LIGHT);
    
    IRSender irsender(9);
    PanasonicNKEHeatpumpIR *ACIR;
    
    Timer t;
    
    boolean ac_state = false;
    
    
    void setup() {
    
    
      // Initialize library and add callback for incoming messages
      gw.begin(incomingMessage, AUTO, true);
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present( ACW2_CHILD, S_LIGHT );
      gw.present( ACW6_CHILD, S_LIGHT );
      gw.sendSketchInfo("AC", "1");
    
      
    }
    
    void loop() {
      // MySensors Process
      gw.process();
    
      
    
      // Timer Process
      t.update();
    
    }
    
    void incomingMessage(const MyMessage &message) {
    
      if (message.isAck()) {
             Serial.println(F("This is an ack from gateway"));
          }
          
      if (message.type == V_LIGHT) {
        boolean state = message.getBool();
        
        if (message.sensor == ACW2_CHILD) {
          
          if(state){
            Serial.println(F("--- received ACW2 - ON"));
         schedule_auto(6600000);
         //schedule_auto(6000);      
          }
          else
          {
            Serial.println(F("--- received ACW2 - OFF"));
            ac_off();
          }
          
        }
        
        if (message.sensor == ACW6_CHILD) {
          Serial.println(F("--- received ACW6"));
           if(state){
         schedule_quiet(21000000);      
             }
          else
          {
            ac_off();
          }
         }
        }
    }
    
    
    void schedule_auto(int dur) {
    
       Serial.println(F("--- sending auto"));
       ACIR->send(irsender, POWER_ON, MODE_HEAT, FAN_AUTO, 26, VDIR_MIDDLE, HDIR_AUTO);
       t.after(dur,ac_off);
       ac_state = true;
      
    }
    
    void schedule_quiet(int dur) {
    
       
       Serial.println(F("--- sending quiet"));
       ACIR->send(irsender, POWER_ON, MODE_HEAT, FAN_1, 25, VDIR_MIDDLE, HDIR_AUTO);
       t.after(dur,ac_off);
       ac_state = true;
      
    }
    
    void ac_off() {
      Serial.println(F("--- trying off"));
      if (ac_state) 
      {
        Serial.println(F("--- sending off"));
      ACIR->send(irsender, POWER_OFF, MODE_HEAT, FAN_1, 25, VDIR_MIDDLE, HDIR_AUTO);
    
      ac_state = false;
      gw.send(acw2Msg.set(false), true);
      gw.send(acw6Msg.set(false), true);
      }
     
    }
    
    

    Here's the Serial output:

    send: 2-2-0-0 s=255,c=0,t=18,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 2-2-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    read: 0-0-2 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    repeater started, id=2, parent=0, distance=1
    send: 2-2-0-0 s=2,c=0,t=3,pt=0,l=0,sg=0,st=ok:
    send: 2-2-0-0 s=3,c=0,t=3,pt=0,l=0,sg=0,st=ok:
    send: 2-2-0-0 s=255,c=3,t=11,pt=0,l=2,sg=0,st=ok:AC
    send: 2-2-0-0 s=255,c=3,t=12,pt=0,l=1,sg=0,st=ok:1
    read: 0-0-2 s=2,c=1,t=2,pt=0,l=1,sg=0:0
    send: 2-2-0-0 s=2,c=1,t=2,pt=0,l=1,sg=0,st=ok:0
    --- received ACW2 - OFF
    --- trying off
    read: 0-0-2 s=2,c=1,t=2,pt=0,l=1,sg=0:1
    send: 2-2-0-0 s=2,c=1,t=2,pt=0,l=1,sg=0,st=ok:1
    --- resend: 2-2-0-0 s=255,c=0,t=18,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 2-2-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    read: 0-0-2 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    repeater started, id=2, parent=0, distance=1
    send: 2-2-0-0 s=2,c=0,t=3,pt=0,l=0,sg=0,st=ok:
    send: 2-2-0-0 s=3,c=0,t=3,pt=0,l=0,sg=0,st=ok:
    send: 2-2-0-0 s=255,c=3,t=11,pt=0,l=2,sg=0,st=ok:AC
    send: 2-2-0-0 s=255,c=3,t=12,pt=0,l=1,sg=0,st=ok:1
    

    the node restarted at " --- resend" ... it should be "---received"...

    Am I missing something?



  • Hi,

    Great news ! πŸ˜ƒ
    I've tested the DaikinHeatpumpIR library and I can report that it works with my Daikin Heatpump, type RXS25G2V1B
    FVXS25FV1B
    the remote is ARC452A1

    I'm really happy that it works and would like to say thank you to the dev's !
    Finally I will be able to start some real energy saving by controlling the Daikin heatpump based on conditions like presence, outside temp, (google)-calendar, and heath generated from a second central heating system (allowing me to choose most economic heathing source).

    I already have a Nano based sensor node (near the Daikin unit) for PIR motion detection and DHT22 temp/humidity, so hopefully I can manage to integrate the simple ON/OFF via IR into the same sketch.
    If not, another dedicated node will be needed.
    @ ToniA, do you expect problems when integrating this into the same Mysensors sketch as PIR + DHT22 ?

    Bye,
    DirkB



  • @Panos-Toumpaniaris said:

    Am I missing something?

    Yes you are πŸ˜ƒ

    You just have an uninitialized pointer to PanasonicNKEHeatpumpIR, while you should have this instead:

    PanasonicNKEHeatpumpIR *ACIR = new PanasonicNKEHeatpumpIR();
    


  • @DirkB19 said:

    @ ToniA, do you expect problems when integrating this into the same Mysensors sketch as PIR + DHT22 ?

    It should be fine. Just make sure that if you have any interrupt handlers (PIR?), make sure they execute fast so that they don't mess up the timings. It's probably not a very good idea to disable interrupts while sending the IR, as the IR sending takes several hundreds of milliseconds.



  • @ToniA said:

    @Panos-Toumpaniaris said:

    Am I missing something?

    Yes you are πŸ˜ƒ

    You just have an uninitialized pointer to PanasonicNKEHeatpumpIR, while you should have this instead:

    PanasonicNKEHeatpumpIR *ACIR = new PanasonicNKEHeatpumpIR();
    

    Sorry I didn't answer sooner.. I was having too much fun with my working node!
    I just forgot a constructor and no matter how many times I went through my code I couldn't see it!
    Thanks so much Toni!

    One down 30 more nodes to go!



  • Just got my Sensebenders this week. I can confirm that the HeatpumpIR library works also on the Sensebender πŸ™‚ Nice...



  • @ToniA
    Hey, thanks for all the work you have put down. I have had some other projects going the last year so have not really put down more time on this.

    How is it working with the sensebender? Are you using it on batteries?
    Any ide about battery usage?



  • I just got it running on Sensebender today, on my desk. The problem is that this is not a 'sensor', but an 'actuator'. So it needs to listen to the radio all the time. I believe it would not run on batteries for too long.

    I was asking about how to power the Sensebender in another thread, but didn't yet get any real answers. So let's try once more:

    What kind of schema should I use to power the Sensebender (with NRF24), provided that I have +5V DC available, and I have a bunch of different capacitors and 'LE33ACZ 5V-3.3V Step Down Regulators'?



  • Hello
    It would be nice to make it run on batteries, maybe with 10 seconds sleep, and then wake up only to check with gateway if there is a new command and then sleep again.

    I am building a pir sensor now based on 3*aa batteris running on 4,5 volt.I will ust use an LE33 step down directly after the battery pack to provide power to both sensebender+radio+pir. Dont know if that is the optimal way to do it but it should work



  • I have my heatpump mysensor working, and hooked up to Openhab.

    Arduino code here:

    #include <MySensor.h>
    #include <SPI.h>
    #include <Arduino.h>
    
    #include <PanasonicCKPHeatpumpIR.h>
    #include <PanasonicHeatpumpIR.h>
    
    #define POWER_ID 0
    #define MODE_ID 1
    #define FAN_ID 2
    #define TEMP_ID 3
    #define VDIR_ID 4
    #define HDIR_ID 5
    
    
    MySensor gw;
    MyMessage powerMsg(POWER_ID, V_STATUS); 
    MyMessage modeMsg(MODE_ID, V_HVAC_FLOW_STATE);
    MyMessage fanMsg(FAN_ID, V_PERCENTAGE);
    MyMessage tempMsg(TEMP_ID, V_TEMP);
    MyMessage vdirMsg(VDIR_ID, V_VAR1); 
    MyMessage hdirMsg(HDIR_ID, V_VAR2); 
    
    IRSenderPWM irSender(3);       // IR led on Arduino digital pin 3, using Arduino PWM
    
    HeatpumpIR *heatpumpIR = new PanasonicNKEHeatpumpIR();
    
    //Some global variables to hold the states
    int POWER_STATE;
    int TEMP_STATE;
    int FAN_STATE;
    int MODE_STATE;
    
    void setup()  
    {  
      gw.begin(incomingMessage, AUTO, false);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Heatpump", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(POWER_ID, S_BINARY);
      gw.present(MODE_ID, S_HVAC);
      gw.present(FAN_ID, S_HVAC);
      gw.present(TEMP_ID, S_HVAC);
      gw.present(VDIR_ID, S_CUSTOM);
      gw.present(HDIR_ID, S_CUSTOM);
         
      // Load our values on start
      POWER_STATE = gw.loadState(POWER_ID);
      TEMP_STATE = gw.loadState(TEMP_ID);
      FAN_STATE = gw.loadState(FAN_ID);
      MODE_STATE = gw.loadState(MODE_ID);
      
      sendHeatpumpCommand();
    }
    
    void loop() {
      gw.process();
    } 
    
    void handlePowerMessage(bool newState) {
      if (newState) {
        POWER_STATE = POWER_ON;
      }
      else {
        POWER_STATE = POWER_OFF;
      }
      gw.saveState(POWER_ID, newState);
    }
    
    void handleModeMessge(int newMode) {
      switch(newMode) {    
        case 0:
          MODE_STATE = MODE_HEAT; break;
        case 1:
          MODE_STATE = MODE_COOL; break;
        case 2:
          MODE_STATE = MODE_AUTO; break;
        case 3:
          MODE_STATE = MODE_FAN; break;
         case 4:
          MODE_STATE = MODE_DRY; break;
      }
      MODE_STATE = newMode;
      gw.saveState(MODE_ID, newMode);
    }
    
    void handleFanMessage(int newFan) {
      if (newFan > 5) newFan=5;
      switch(newFan) {
        case 0:
          FAN_STATE = FAN_AUTO; break;
        case 1:
          FAN_STATE = FAN_1; break;
        case 2:
          FAN_STATE = FAN_2; break;
        case 3:
          FAN_STATE = FAN_3; break;
        case 4:
          FAN_STATE = FAN_4; break;
        case 5:
          FAN_STATE = FAN_5; break;
        default:
          FAN_STATE = FAN_AUTO; break;
      }
      FAN_STATE = newFan;
      gw.saveState(FAN_ID, newFan);
    }
    
    void handleTempMessage(int newTemp) {
      TEMP_STATE = newTemp;
      gw.saveState(TEMP_ID, newTemp);
    }
    
    void sendHeatpumpCommand() {
      Serial.println("Power = " + (String)POWER_STATE);
      Serial.println("Mode = " + (String)MODE_STATE);
      Serial.println("Fan = " + (String)FAN_STATE);
      Serial.println("Temp = " + (String)TEMP_STATE);
      heatpumpIR->send(irSender, POWER_STATE, MODE_STATE, FAN_STATE, TEMP_STATE, VDIR_AUTO, HDIR_AUTO);
    }
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
       Serial.print("Incoming change for sensor:");
       Serial.print(message.sensor);
       Serial.print(", New status: ");
       Serial.println(message.getBool());
    
       switch(message.sensor) {
        case POWER_ID: {
          bool newState = message.getBool();
          handlePowerMessage(newState);
          break;
        }
        case MODE_ID: {
          int newMode = message.getInt();
          handleModeMessge(newMode);
          break;
        }
        case FAN_ID: {
          int newFan = message.getInt();
          handleFanMessage(newFan);
          break;
        }
        case TEMP_ID: {
          int newTemp = message.getInt();
          handleTempMessage(newTemp);
          break;
        }
       }
      sendHeatpumpCommand();
    }
    

    Openhab items

    Switch	Power_HeatPump	"Heatpump on/off" <aircon>
    Number	Mode_HeatPump	"Heatpump mode"
    Number	Fan_HeatPump	"Heatpump fan" <airing>
    Number	Temp_HeatPump	"Heatpump temperature [%d C]"	<temperature>
    String	VDir_HeatPump	"vertical"
    String	HDir_HeatPump	"horizontal"
    

    Openhab sitemap

    sitemap heatpump label="Heatpump" {
      Frame {
        Switch item=Power_HeatPump
        Selection item=Mode_HeatPump mappings=[0="heat", 1="cool", 2="auto", 3="fan", 4="dry"]
        Selection item=Fan_HeatPump mappings=[0="auto", 1="Level 1", 2="Level 2", 3="Level 3", 4="Level 4", 5="Level 5"]
        Setpoint item=Temp_HeatPump minValue=10 maxValue=30 step=1
        Text item=VDir_HeatPump
        Text item=HDir_HeatPump
      }
    }
    

    Openhab rules

    val org.eclipse.xtext.xbase.lib.Functions$Function4 numberOperation = [
        org.openhab.core.library.items.NumberItem numberItem, 
        org.openhab.core.library.items.StringItem arduinoItem, 
        String arduinoDevMap,
        Integer subType|
        logInfo("number", "Sending number message to mysensors node")
        var Integer state = numberItem.state
        logInfo("mysensors", "Function: numberOperation >> "+arduinoDevMap + "1;1;" + subType + ";" + state )
        arduinoItem.sendCommand(arduinoDevMap + "1;0;" + subType + ";" + state + "\n")
    ]
    
    //switch function
    val org.eclipse.xtext.xbase.lib.Functions$Function4 switchOperation = [
        org.openhab.core.library.items.SwitchItem relayItem, 
        org.openhab.core.library.items.StringItem arduinoItem, 
        String arduinoDevMap,
        Integer subType|
        logInfo("switch", "Sending switch message to mysensors node")
        
        var Integer state = 0
        if (relayItem.state == OFF) {
            state = 0 
        }
        else {
            state = 1
        }
        logInfo("mysensors", "Function: switchOperation >> "+arduinoDevMap + "1;1;" + subType + ";" + state )
        arduinoItem.sendCommand(arduinoDevMap + "1;0;" + subType + ";" + state + "\n")
    ]
    
    
    
    
    rule "Heatpump on"
    when
        Item Power_HeatPump received command
    then
        switchOperation.apply(Power_HeatPump, MySensors_Gateway, sensorToItemsMap.get("Power_HeatPump"),  V_STATUS)         
    end 
    
    rule "Heatpump mode"
    when
        Item Mode_HeatPump received update
    then
        numberOperation.apply(Mode_HeatPump, MySensors_Gateway, sensorToItemsMap.get("Mode_HeatPump"),  V_VAR1)         
    end 
    
    
    rule "Heatpump temp"
    when
        Item Temp_HeatPump received command
    then
        numberOperation.apply(Temp_HeatPump, MySensors_Gateway, sensorToItemsMap.get("Temp_HeatPump"),  V_TEMP)         
    end 
    
    rule "heatpump fan"
    when
        Item Fan_HeatPump received command
    then
        numberOperation.apply(Fan_HeatPump, MySensors_Gateway, sensorToItemsMap.get("Fan_HeatPump"),  V_PERCENTAGE)         
    end 
    


  • @ToniA Hi, do you have a guide on how to set up Domoticz with this example? I understand enough about mysensors and domoticz to be dangerous but i dont get how Domoticz can send the right command....



  • Take a look at this topic on the Domoticz forum: http://www.domoticz.com/forum/viewtopic.php?f=34&t=8751



  • @SGi
    Hi,
    I have created the wiki:
    https://www.domoticz.com/wiki/AC_/_heatpumpIR

    Everything is based in Toni's great effort πŸ™‚
    I also first used the mysensors Arduino, but since I am still using "old" mysensors ver 1.5.4 (And currently I don't have time to upgrade to latest and greatest, which support text based commands)
    Then I have taken same approach as Toni and use Wemos D1 Mini Pro that uses HTTP or MQTT wifi



  • @ToniA

    Thanks for the library it's great. I can also confirm that it works with Fujitsu remote AR-REB1E out of the box.

    Trying to integrate this into HomeAssistant and just do not know where to start. Is there any example how to post a whole string of commands for the air cond via mysensors-MQTT?



  • So nobody is using it this with MQTT gateway?


  • Mod

    @bjacobse if I have a new Daikin heat pump with a newer remote that is not in the library, I guess I'm out of luck, right?



  • @moskovskiy82
    hi, I'm not using the MQTT with mysensors
    I think you should direct your questions to a HomeAssistant forum.
    My setup uses Wemos D1 Mini Pro and Domoticz



  • @gohan
    Please use the github for heatpump to ask you question, as I assume that Toni mostly is checking that. It seems that there 2 different Daikin heatpumps supported

    https://github.com/ToniA/arduino-heatpumpir



  • @bjacobse Can you elaborate a little more on how you wired things up?
    Also how you combined the libs and compiled everything for easyESP?
    Have a sonoff with easyESP and docs are not that clear how to that stuff



  • @moskovskiy82
    I took 5v from the heatpump, mine is an IVT, I took it from the Ir receive, soldered 2wires, one GND and on for 5V and drilled a hole on the plastic casing, and then I had power for the Wemos D1 Mini Pro module.
    Then 100 Ohm resister in series with the Irda LED 940nm Ir LED, connected to GPio16/D0 on the Wemos module.

    Downlaod the ESPEASYT files + download Tonis heatpump /P115 lib and put it in same Arduino IDE, compile it all together

    http://www.domoticz.com/wiki/AC_/_heatpumpIR



  • I want to make heatpumpIR, but after trying to send the signal using simple.ino sketch to my Sharp A/C nothing happened. Confused where to start ....



  • @Ispandy
    did you look at the previous comment?
    to make it easy for you, then don't use mysensors with Arduino for this, it's too difficult to setup, but instead use the Wemos and ESPEASY using your WIFI

    http://www.domoticz.com/wiki/AC_/_heatpumpIR



  • @bjacobse There is nothing difficult in setting it up. Just connect the irda to the 3rd PWM leg



  • @moskovskiy82
    I certainly agree, I assume your comment actually was meant to Ispandy πŸ˜‰


 

399
Online

7.5k
Users

8.4k
Topics

90.4k
Posts