Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. IR Sensor only reading every other button press

IR Sensor only reading every other button press

Scheduled Pinned Locked Moved Development
7 Posts 2 Posters 72 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kiesel
    wrote on last edited by
    #1

    Hi,

    I am trying to pass IR data from my TV remote to my controller (Home Assistant) for later processing.

    I am using a TSOP38238 receiver connected to D3 on an arduino pro mini. The pro mini is using two other sensors (lux and temp/humidity) connected via i2c which are pulled every 90 seconds by the arduino. For brevity I'll omit their code, let me know if you need to see it anyway.

    The arduino sleeps and is woken up by an interrupt if the IR-sensor receives data. The weird thing is though: The arduino wakes up on every signal from the TV remote (LG TV) but only receives every other signal.

    Here is the output of the serial monitor:

    20:20:55.561 ->  
    20:20:55.561 ->  __  __       ____
    20:20:55.595 -> |  \/  |_   _/ ___|  ___ _ __  ___  ___  _ __ ___
    20:20:55.595 -> | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __|
    20:20:55.595 -> | |  | | |_| |___| |  __/ | | \__ \  _  | |  \__ \
    20:20:55.595 -> |_|  |_|\__, |____/ \___|_| |_|___/\___/|_|  |___/
    20:20:55.595 ->         |___/                      2.4.0-alpha
    20:20:55.595 -> 
    20:21:01.036 -> Tempsensor started
    20:21:01.036 -> UPDATE_INTERVAL:90000
    20:21:06.079 -> wake_reason=1
    20:21:06.079 -> IR Processing done--------------------
    20:21:08.369 -> wake_reason=1
    20:21:08.369 -> 20DF4EB
    20:21:08.468 -> IR Processing done--------------------
    20:21:10.525 -> wake_reason=1
    20:21:10.525 -> IR Processing done--------------------
    20:21:11.686 -> wake_reason=1
    20:21:11.686 -> 20DF8E7
    20:21:11.819 -> IR Processing done--------------------
    20:21:13.379 -> wake_reason=1
    20:21:13.379 -> IR Processing done--------------------
    20:21:14.607 -> wake_reason=1
    20:21:14.607 -> 20DFC63
    20:21:14.706 -> IR Processing done--------------------
    20:21:16.033 -> wake_reason=1
    20:21:16.033 -> IR Processing done--------------------
    20:21:16.929 -> wake_reason=1
    20:21:16.929 -> 20DF867
    20:21:17.029 -> IR Processing done--------------------
    
    

    I pressed four different buttons on the remote, each one twice.

    Here is the code, please let me know what I am doing wrong:

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Yveaux
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a Si7021 sensor.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humiditySi7021
     * 
     */
    
    // Enable debug prints
    //#define MY_DEBUG
    
    #define MY_OWN_DEBUG
    
    #ifndef MY_OWN_DEBUG //disable serial in production compile, potentially saves few uA in sleep mode
         #define MY_DISABLED_SERIAL
    #endif
    
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    #define MY_IS_RFM69HW
    #define MY_RFM69_NEW_DRIVER
    
    
    #define MY_NODE_ID 3
    #include <MySensors.h>
    
    // IR specific setup  
    #include <IRremote.h>
    int RECV_PIN     = 3;
    IRrecv            irrecv(RECV_PIN);
    decode_results    ircode;
    const char * TYPE2STRING[] = {
        "UNKONWN",
        "RC5",
        "RC6",
        "NEC",
        "Sony",
        "Panasonic",
        "JVC",
        "SAMSUNG",
        "Whynter",
        "AIWA RC T501",
        "LG",
        "Sanyo",
        "Mitsubishi",
        "Dish",
        "Sharp",
        "Denon"
    };
    #define Type2String(x)   TYPE2STRING[x < 0 ? 0 : x]
    #define AddrTxt          F(" addres: 0x")
    #define ValueTxt         F(" value: 0x")
    #define NATxt            F(" - not implemented/found")
    unsigned long last_value;
    // IR specific setup end
    
    #define CHILD_ID_HUM  0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_LUX  2
    #define CHILD_ID_IR 3
    
    #define SKETCH_NAME "mysensors_wohnzimmer_main"
    #define SKETCH_MAJOR_VER "1"
    #define SKETCH_MINOR_VER "0"
    
    static bool metric = true;
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    
    float lastHum = 0;
    float lastTemp = 0;
    int lastLux = 0;
    
    
    // Sleep time between sensor updates (in milliseconds)
    static const unsigned long UPDATE_INTERVAL = 90000;
    
    #include <SI7021.h>
    #include <BH1750.h>
    
    static SI7021 tempsensor;
    BH1750 lightmeter;
    
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgLux(CHILD_ID_LUX, V_LEVEL);
    MyMessage msgIrRecord(CHILD_ID_IR, V_IR_RECEIVE); 
    
    
    
    void presentation()  
    { 
     // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
    
      present(CHILD_ID_HUM, S_HUM);
       present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_LUX, S_LIGHT_LEVEL);
      present(CHILD_ID_IR, S_IR);
    }
    
    void setup()
    {
      //Serial.begin(9600);
      //Serial.print("Starting: ");
      while (not tempsensor.begin())
      {
        Serial.println(F("Temperaturesensor not detected!"));
        delay(5000);
      }
        #ifdef MY_OWN_DEBUG
        Serial.println("Tempsensor started");
      #endif
      lightmeter.begin();
      #ifdef MY_OWN_DEBUG
        Serial.print("UPDATE_INTERVAL:");Serial.println(UPDATE_INTERVAL);
      #endif
      irrecv.enableIRIn();
    }
    
    
    void loop(){
      int8_t wake_reason;
      sleep_bod_disable();//disable BOD  - saves~ 15uA
      wake_reason = smartSleep(RECV_PIN-2, CHANGE, UPDATE_INTERVAL);
      #ifdef MY_OWN_DEBUG
      Serial.print("wake_reason=");Serial.println(wake_reason);
      #endif
      if (wake_reason == 1){
        //woken up by interrupt on d3
        ir_received();
      }
      else{
        //woken by update_interval
        update_interval();
      }
    
    
    }
    
    void ir_received(){
        if (irrecv.decode(&ircode)) {
    
          unsigned long ir_value = ircode.value;
          if (ir_value == REPEAT) //if repeat-code: send last code
          {
             ir_value = last_value;
          }
          else{ //if not: save new value as last value
            last_value = ir_value;
          }
          Serial.println(ir_value,HEX);
          delay(100);
          send(msgIrRecord.set(ir_value));
          irrecv.resume(); // Receive the next value
        }
        Serial.println("IR Processing done--------------------");
    }
    
    void update_interval()      
    {  
      //removed for brevity
    }
    
    
    
    skywatchS 1 Reply Last reply
    0
    • K kiesel

      Hi,

      I am trying to pass IR data from my TV remote to my controller (Home Assistant) for later processing.

      I am using a TSOP38238 receiver connected to D3 on an arduino pro mini. The pro mini is using two other sensors (lux and temp/humidity) connected via i2c which are pulled every 90 seconds by the arduino. For brevity I'll omit their code, let me know if you need to see it anyway.

      The arduino sleeps and is woken up by an interrupt if the IR-sensor receives data. The weird thing is though: The arduino wakes up on every signal from the TV remote (LG TV) but only receives every other signal.

      Here is the output of the serial monitor:

      20:20:55.561 ->  
      20:20:55.561 ->  __  __       ____
      20:20:55.595 -> |  \/  |_   _/ ___|  ___ _ __  ___  ___  _ __ ___
      20:20:55.595 -> | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __|
      20:20:55.595 -> | |  | | |_| |___| |  __/ | | \__ \  _  | |  \__ \
      20:20:55.595 -> |_|  |_|\__, |____/ \___|_| |_|___/\___/|_|  |___/
      20:20:55.595 ->         |___/                      2.4.0-alpha
      20:20:55.595 -> 
      20:21:01.036 -> Tempsensor started
      20:21:01.036 -> UPDATE_INTERVAL:90000
      20:21:06.079 -> wake_reason=1
      20:21:06.079 -> IR Processing done--------------------
      20:21:08.369 -> wake_reason=1
      20:21:08.369 -> 20DF4EB
      20:21:08.468 -> IR Processing done--------------------
      20:21:10.525 -> wake_reason=1
      20:21:10.525 -> IR Processing done--------------------
      20:21:11.686 -> wake_reason=1
      20:21:11.686 -> 20DF8E7
      20:21:11.819 -> IR Processing done--------------------
      20:21:13.379 -> wake_reason=1
      20:21:13.379 -> IR Processing done--------------------
      20:21:14.607 -> wake_reason=1
      20:21:14.607 -> 20DFC63
      20:21:14.706 -> IR Processing done--------------------
      20:21:16.033 -> wake_reason=1
      20:21:16.033 -> IR Processing done--------------------
      20:21:16.929 -> wake_reason=1
      20:21:16.929 -> 20DF867
      20:21:17.029 -> IR Processing done--------------------
      
      

      I pressed four different buttons on the remote, each one twice.

      Here is the code, please let me know what I am doing wrong:

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0: Yveaux
       * 
       * DESCRIPTION
       * This sketch provides an example of how to implement a humidity/temperature
       * sensor using a Si7021 sensor.
       *  
       * For more information, please visit:
       * http://www.mysensors.org/build/humiditySi7021
       * 
       */
      
      // Enable debug prints
      //#define MY_DEBUG
      
      #define MY_OWN_DEBUG
      
      #ifndef MY_OWN_DEBUG //disable serial in production compile, potentially saves few uA in sleep mode
           #define MY_DISABLED_SERIAL
      #endif
      
      
      // Enable and select radio type attached
      #define MY_RADIO_RFM69
      #define MY_IS_RFM69HW
      #define MY_RFM69_NEW_DRIVER
      
      
      #define MY_NODE_ID 3
      #include <MySensors.h>
      
      // IR specific setup  
      #include <IRremote.h>
      int RECV_PIN     = 3;
      IRrecv            irrecv(RECV_PIN);
      decode_results    ircode;
      const char * TYPE2STRING[] = {
          "UNKONWN",
          "RC5",
          "RC6",
          "NEC",
          "Sony",
          "Panasonic",
          "JVC",
          "SAMSUNG",
          "Whynter",
          "AIWA RC T501",
          "LG",
          "Sanyo",
          "Mitsubishi",
          "Dish",
          "Sharp",
          "Denon"
      };
      #define Type2String(x)   TYPE2STRING[x < 0 ? 0 : x]
      #define AddrTxt          F(" addres: 0x")
      #define ValueTxt         F(" value: 0x")
      #define NATxt            F(" - not implemented/found")
      unsigned long last_value;
      // IR specific setup end
      
      #define CHILD_ID_HUM  0
      #define CHILD_ID_TEMP 1
      #define CHILD_ID_LUX  2
      #define CHILD_ID_IR 3
      
      #define SKETCH_NAME "mysensors_wohnzimmer_main"
      #define SKETCH_MAJOR_VER "1"
      #define SKETCH_MINOR_VER "0"
      
      static bool metric = true;
      
      int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
      int oldBatteryPcnt = 0;
      
      float lastHum = 0;
      float lastTemp = 0;
      int lastLux = 0;
      
      
      // Sleep time between sensor updates (in milliseconds)
      static const unsigned long UPDATE_INTERVAL = 90000;
      
      #include <SI7021.h>
      #include <BH1750.h>
      
      static SI7021 tempsensor;
      BH1750 lightmeter;
      
      
      // Change to V_LIGHT if you use S_LIGHT in presentation below
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgLux(CHILD_ID_LUX, V_LEVEL);
      MyMessage msgIrRecord(CHILD_ID_IR, V_IR_RECEIVE); 
      
      
      
      void presentation()  
      { 
       // Send the sketch version information to the gateway and Controller
        sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
      
        present(CHILD_ID_HUM, S_HUM);
         present(CHILD_ID_TEMP, S_TEMP);
        present(CHILD_ID_LUX, S_LIGHT_LEVEL);
        present(CHILD_ID_IR, S_IR);
      }
      
      void setup()
      {
        //Serial.begin(9600);
        //Serial.print("Starting: ");
        while (not tempsensor.begin())
        {
          Serial.println(F("Temperaturesensor not detected!"));
          delay(5000);
        }
          #ifdef MY_OWN_DEBUG
          Serial.println("Tempsensor started");
        #endif
        lightmeter.begin();
        #ifdef MY_OWN_DEBUG
          Serial.print("UPDATE_INTERVAL:");Serial.println(UPDATE_INTERVAL);
        #endif
        irrecv.enableIRIn();
      }
      
      
      void loop(){
        int8_t wake_reason;
        sleep_bod_disable();//disable BOD  - saves~ 15uA
        wake_reason = smartSleep(RECV_PIN-2, CHANGE, UPDATE_INTERVAL);
        #ifdef MY_OWN_DEBUG
        Serial.print("wake_reason=");Serial.println(wake_reason);
        #endif
        if (wake_reason == 1){
          //woken up by interrupt on d3
          ir_received();
        }
        else{
          //woken by update_interval
          update_interval();
        }
      
      
      }
      
      void ir_received(){
          if (irrecv.decode(&ircode)) {
      
            unsigned long ir_value = ircode.value;
            if (ir_value == REPEAT) //if repeat-code: send last code
            {
               ir_value = last_value;
            }
            else{ //if not: save new value as last value
              last_value = ir_value;
            }
            Serial.println(ir_value,HEX);
            delay(100);
            send(msgIrRecord.set(ir_value));
            irrecv.resume(); // Receive the next value
          }
          Serial.println("IR Processing done--------------------");
      }
      
      void update_interval()      
      {  
        //removed for brevity
      }
      
      
      
      skywatchS Offline
      skywatchS Offline
      skywatch
      wrote on last edited by skywatch
      #2

      @kiesel Did you learn the codes yourself?

      Some remotes (panasonic for example) will send a different code each time the button is pressed. They do this by having 2 codes for each button.

      First time you press a button it sends code from the 'A' set and the next press of the button sends the 'B' set.

      So it may be the same for the remote you have. If so you need to learn both sets of IR code and then implement a check in your sketch (a simple if comparison should be enough).....

      I have also found that replacing irrecv.resume(); with irrecv.enableIRIn(); might help. Also to stop the reveive function when you have got a code, send a dummy ir message and then re-enable the ir reveiver as I just suggested.

      K 1 Reply Last reply
      0
      • skywatchS skywatch

        @kiesel Did you learn the codes yourself?

        Some remotes (panasonic for example) will send a different code each time the button is pressed. They do this by having 2 codes for each button.

        First time you press a button it sends code from the 'A' set and the next press of the button sends the 'B' set.

        So it may be the same for the remote you have. If so you need to learn both sets of IR code and then implement a check in your sketch (a simple if comparison should be enough).....

        I have also found that replacing irrecv.resume(); with irrecv.enableIRIn(); might help. Also to stop the reveive function when you have got a code, send a dummy ir message and then re-enable the ir reveiver as I just suggested.

        K Offline
        K Offline
        kiesel
        wrote on last edited by kiesel
        #3

        @skywatch

        I used the sketch "IRrecvDump" from the IRremote library to verify that only one code is sent per button press, so I don't think that's the problem.

        With that sketch the same code is written to the serial monitor every time I press the same button.

        The issue is that code uses polling and I want the arduino to sleep because it is a battery powered node.

        /edit: irrecv.enableIRIn(); didn't make a difference unfortunately.

        K 1 Reply Last reply
        0
        • K kiesel

          @skywatch

          I used the sketch "IRrecvDump" from the IRremote library to verify that only one code is sent per button press, so I don't think that's the problem.

          With that sketch the same code is written to the serial monitor every time I press the same button.

          The issue is that code uses polling and I want the arduino to sleep because it is a battery powered node.

          /edit: irrecv.enableIRIn(); didn't make a difference unfortunately.

          K Offline
          K Offline
          kiesel
          wrote on last edited by kiesel
          #4

          I think this is solved: It appears that the interrupt wakes the arduino who then queries the sensor before the full code is received. I added a

          delay(100); 
          

          to give it a bit more time to read the data.

          void ir_received(){
            delay(100);
              if (irrecv.decode(&ircode)) {
                //#ifdef MY_OWN_DEBUG
                //dump(&ircode);
                //#endif
                unsigned long ir_value = ircode.value;
                if (ir_value == REPEAT) //if repeat-code: send last code
                {
                   ir_value = last_value;
                }
                else{ //if not: save new value as last value
                  last_value = ir_value;
                }
                Serial.println(ir_value,HEX);
                
                send(msgIrRecord.set(ir_value));
                
              }
              //delay(100);
              irrecv.resume(); // Receive the next value
          
              Serial.println("IR Processing done--------------------");
          }
          

          If anybody has a better idea please let me know.

          skywatchS 1 Reply Last reply
          0
          • K kiesel

            I think this is solved: It appears that the interrupt wakes the arduino who then queries the sensor before the full code is received. I added a

            delay(100); 
            

            to give it a bit more time to read the data.

            void ir_received(){
              delay(100);
                if (irrecv.decode(&ircode)) {
                  //#ifdef MY_OWN_DEBUG
                  //dump(&ircode);
                  //#endif
                  unsigned long ir_value = ircode.value;
                  if (ir_value == REPEAT) //if repeat-code: send last code
                  {
                     ir_value = last_value;
                  }
                  else{ //if not: save new value as last value
                    last_value = ir_value;
                  }
                  Serial.println(ir_value,HEX);
                  
                  send(msgIrRecord.set(ir_value));
                  
                }
                //delay(100);
                irrecv.resume(); // Receive the next value
            
                Serial.println("IR Processing done--------------------");
            }
            

            If anybody has a better idea please let me know.

            skywatchS Offline
            skywatchS Offline
            skywatch
            wrote on last edited by
            #5

            @kiesel Good work on finding the issue. Delay will block the cpu from performing other tasks (maybe that is what you want). Usually in mysensors we use wait(100); instead.

            I have just finished my first IR send and receive node and have another 2 to build this weekend (hopefully).....

            K 1 Reply Last reply
            1
            • skywatchS skywatch

              @kiesel Good work on finding the issue. Delay will block the cpu from performing other tasks (maybe that is what you want). Usually in mysensors we use wait(100); instead.

              I have just finished my first IR send and receive node and have another 2 to build this weekend (hopefully).....

              K Offline
              K Offline
              kiesel
              wrote on last edited by
              #6

              @skywatch

              I didn't know that delay blocked, good to know, thanks. I have nothing that's supposed to run in the background so delay works for the time being :)

              Congrats on the node! Is the code available somewhere? I'd like to take a look. Always good to learn new stuff.

              skywatchS 1 Reply Last reply
              0
              • K kiesel

                @skywatch

                I didn't know that delay blocked, good to know, thanks. I have nothing that's supposed to run in the background so delay works for the time being :)

                Congrats on the node! Is the code available somewhere? I'd like to take a look. Always good to learn new stuff.

                skywatchS Offline
                skywatchS Offline
                skywatch
                wrote on last edited by
                #7

                @kiesel You are welcome! - We are all here to learn! :)

                As to my code, here is the thread with the problems I had and how I fixed them....

                https://forum.mysensors.org/topic/10936/vs838-ir-receiver-led-anyone-got-it-working-with-mys?_=1582743282787

                I am still tinkering around the edges and I expect a final version to be about a week away. It is mostly getting it all the way I want it now! ;)

                1 Reply Last reply
                1
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                20

                Online

                11.7k

                Users

                11.2k

                Topics

                113.1k

                Posts


                Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • MySensors
                • OpenHardware.io
                • Categories
                • Recent
                • Tags
                • Popular