Infrared Sensor Module

Infrared sensor module is one of the most basic sensor modules that is really interesting for curious makers and DIYers. An IR sensor is an electronic instrument that scans IR signals in specific frequency ranges defined by standards. It then converts them to an electric signals on its output pin that is called signal or data pin. Most common usage of infrared signals is to transmit data over the air on short distances (typically few meters). Almost all home electronics devices like TVs or DVD players use infrared for their remote control.

Infrared communication protocol

Each signal represents a specific code. Electric signals can be converted back to the actual data/code that sender has sent. When you press a button on your TV remote control, it generates a signal corresponding to the button code (e.g. On/Off, Volume Up, etc.) and sends it for a receiver (in this case your TV). Both sender and receiver agreed on a set of codes so that receiver knows what to do based on each code. The way a code should be modulated (modeled) as a signal is defined in different standard and each sensor manufacturer normally tries to produce a product compatible with them so that it could be used in different devices. One of the most known standard protocols is from NEC. You can find a brief history of IR protocols on Wikipedia under Consumer IR title.

How does an infrared sensor look like?

IR sensors are available on different packages. Here you can see some typical packaging for an IR receiver.

They are also available as infrared sensor modules or breakout board. Such modules normally incorporate one of the sensors mentioned above with a nice breadboard friendly package together with an LED that would flash when the sensor detects a signal. By doing so you would notice if any data is being transferred. I highly suggest starting with one of these modules.

Note: if you have a raw IR sensor, nothing would change, except that you should check the datasheet of the sensor to make sure you’re wiring it correctly because otherwise you may have a beautiful blue smoke with a smell that would last for an hour.

Where to buy an infrared sensor module?

Infrared sensor modules are available on most local electronics shops. You can also try to buy them at Amazon or buy them cheaper on eBay or AliExpress. If you’re a beginner and want to experiment more with Arduino Uno, it would be better to think about buying a kit. A Kit is a collection of all common sensor modules that you may need in near future. They are  compatible with almost all major platforms like Arduino, Raspberry Pi, ESP8266 or ESP32.

Infrared sensor pinout

As can be seen in the above pictures, an infrared sensor has 3 pins: Vcc, GND and Data. You should connect the Vcc to a 3.3v or 5v power supply and the GND to the ground. Sender sends data as burst of on-off signals in the frequency range of 30 Khz to 56 Khz range (depending on the sensor/receiver type or brand). When infrared sensor is powered via Vcc and GND, it scans the specific frequency range that it’s designed for so it doesn’t get interfered by other infrared sources (e.g. sunlight or heat sources). As soon as it detects the signal from sender, it starts demodulating that and converts it to a square wave that you can receive on the Data pin.

Remember that you can use any sort of remote controller like TV or DVD player remote or buy a cheap remote control for your DIY project.

Connecting infrared sensor module to Arduino Uno

Setting up IR sensor connection to Arduino is very simple. Beside VCC and GND pin, the sensor has only one output pin that should be connected to one of digital pins of the Arduino. In this case we connected to pin 13.

You can see the setup of both a raw infrared sensor and an infrared sensor module in the pictures below. As can be seen on pictures, the position of the VCC and GND pins on the sensor module is the opposite of the raw sensor. However it may not be the case for all modules, so as mentioned in previous step, in case of using the raw sensor, check the datasheet first.

Find the code corresponding to each key on the remote

In order to program Arduino to do something when you press a key on the remote, you should first have the code corresponding to that key. The key code is a number normally in hexadecimal format. Each remote controller has its own set of key codes while it’s possible that two controllers share the same code for different purposes. Having different key codes along with using different frequency ranges, ensures that two remote controllers of different devices would not have interference. That’s why when you change your TV channel, your DVD player doesn’t react at all.

To detect the codes for your IR remote, you have to first run a simple sketch that tries to read the code from sensor when you press a key and sends that via the serial port to your computer where you can access it using Serial Monitor tools of Arduino IDE. This is what the following sketch does. It would be better to press every button in order see the code and write down the list of codes somewhere so that you would not need to run this code again in the future. The list of key codes you see as a table in the picture are actually codes corresponding to the remote control you see on pictures.

Note: Don’t get afraid if you see a code like FFFFFF somewhere in between. It means you have pressed and hold a button for a while. We’ll get back into it later on. For now just ignore them and focus on other codes.


/**
 * Copyright (c) 2018 ohmdox.com
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
 
//  Include following libraries to access IR sensor
#include <IRremote.h>
#include <IRremoteInt.h>

const int BLU_LED_PIN = 2;
const int GRN_LED_PIN = 3;
const int YEL_LED_PIN = 4;
const int RED_LED_PIN = 5;

int RECV_PIN = 13;          //  The digital pin that the signal pin of the sensor is connected to
IRrecv receiver(RECV_PIN);  //  Create a new receiver object that would decode signals to key codes
decode_results results;     //  A varuable that would be used by receiver to put the key code into

void setup() {

  //  Setup the pins connected to LEDs as output pin
  pinMode(BLU_LED_PIN, OUTPUT);
  pinMode(GRN_LED_PIN, OUTPUT);
  pinMode(YEL_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);

  receiver.enableIRIn();    //  Enable receiver so that it would start processing infrared signals
}

//  These variables keep the state of LEDs. 'false' means given LED is off and 'true' means it's on
bool isBlueOn = false;
bool isGreenOn = false;
bool isYellowOn = false;
bool isRedOn = false;

void loop() {
  if (receiver.decode(&results)) {            //  Decode the button code and put it in "results" variable
    
    if (results.value == 0xFF6897) {          //  Key '1' is pressed which belongs to the blue LED
      if (isBlueOn == true) {                 //  Blue LED is on, turn it off and set update corresponding state variable
        digitalWrite(BLU_LED_PIN, LOW);
        isBlueOn = false;
      } else {                                //  Blue LED is off, turn it on and set update corresponding state variable
        digitalWrite(BLU_LED_PIN, HIGH);
        isBlueOn = true;
      }
    }
    if (results.value == 0xFF9867) {          //  Key '2' is pressed which belongs to the green LED
      if (isGreenOn == true) {                //  Green LED is on, turn it off and set update corresponding state variable
        digitalWrite(GRN_LED_PIN, LOW);
        isGreenOn = false;
      } else {                                //  Green LED is off, turn it on and set update corresponding state variable
        digitalWrite(GRN_LED_PIN, HIGH);
        isGreenOn = true;
      }
    }
    if (results.value == 0xFFB04F) {          //  Key '3' is pressed which belongs to the yellow LED
      if (isYellowOn == true) {               //  Yellow LED is on, turn it off and set update corresponding state variable
        digitalWrite(YEL_LED_PIN, LOW);
        isYellowOn = false;
      } else {                                //  Yellow LED is off, turn it on and set update corresponding state variable
        digitalWrite(YEL_LED_PIN, HIGH);
        isYellowOn = true;
      }
    }
    if (results.value == 0xFF30CF) {          //  Key '4' is pressed which belongs to the red LED
      if (isRedOn == true) {                  //  Red LED is on, turn it off and set update corresponding state variable
        digitalWrite(RED_LED_PIN, LOW);
        isRedOn = false;
      } else {                                //  Red LED is off, turn it on and set update corresponding state variable
        digitalWrite(RED_LED_PIN, HIGH);
        isRedOn = true;
      }
    }
    receiver.resume();                        //  Continue listening for new signals
  }
}

Infrared software library

In order to read the data from the sensor, you don’t need to process the low level incoming signals. You can just use the IRemote library. You can see that it’s included at the beginning of all sketches in this document.

Sample Project: Controlling LEDs using an infrared remote

Now that we have the code of each button, it’s time to focus on the way we can use them. Normally you use the IR remote to send commands to Arduino to do something like turning on or off a lamp or display something on an LCD/OLED screen. Here we try to demonstrate the process using a simple circuit consists of 4 LEDs in different colors. We want to turn each one of them on or off by a dedicated button of the IR remote. As you can see on the schematic, you have to connect the Arduino in the following way to LEDs and sensor:

Arduino GND 
IR sensor GND.
Arduino VCCIR sensor VCC
Arduino 13IR sensor signal output
Arduino 2Anode of the blue LED (shorter pin of the blue LED)
Arduino 3Anode of the green LED (shorter pin of the green LED)
Arduino 4Anode of the yellow LED (shorter pin of the yellow LED)
Arduino 5Anode of the red LED (shorter pin of the red LED)
Arduino GNDCathode of all LEDs via a 220 ohm resistor (longer pin of the LEDs)

/**
 * Copyright (c) 2018 ohmdox.com
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
 
//  Include following libraries to access IR sensor
#include <IRremote.h>
#include <IRremoteInt.h>

const int BLU_LED_PIN = 2;
const int GRN_LED_PIN = 3;
const int YEL_LED_PIN = 4;
const int RED_LED_PIN = 5;

int RECV_PIN = 13;          //  The digital pin that the signal pin of the sensor is connected to
IRrecv receiver(RECV_PIN);  //  Create a new receiver object that would decode signals to key codes
decode_results results;     //  A varuable that would be used by receiver to put the key code into

void setup() {

  //  Setup the pins connected to LEDs as output pin
  pinMode(BLU_LED_PIN, OUTPUT);
  pinMode(GRN_LED_PIN, OUTPUT);
  pinMode(YEL_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);

  receiver.enableIRIn();    //  Enable receiver so that it would start processing infrared signals
}

//  These variables keep the state of LEDs. 'false' means given LED is off and 'true' means it's on
bool isBlueOn = false;
bool isGreenOn = false;
bool isYellowOn = false;
bool isRedOn = false;

void loop() {
  if (receiver.decode(&results)) {            //  Decode the button code and put it in "results" variable
    
    if (results.value == 0xFF6897) {          //  Key '1' is pressed which belongs to the blue LED
      if (isBlueOn == true) {                 //  Blue LED is on, turn it off and set update corresponding state variable
        digitalWrite(BLU_LED_PIN, LOW);
        isBlueOn = false;
      } else {                                //  Blue LED is off, turn it on and set update corresponding state variable
        digitalWrite(BLU_LED_PIN, HIGH);
        isBlueOn = true;
      }
    }
    if (results.value == 0xFF9867) {          //  Key '2' is pressed which belongs to the green LED
      if (isGreenOn == true) {                //  Green LED is on, turn it off and set update corresponding state variable
        digitalWrite(GRN_LED_PIN, LOW);
        isGreenOn = false;
      } else {                                //  Green LED is off, turn it on and set update corresponding state variable
        digitalWrite(GRN_LED_PIN, HIGH);
        isGreenOn = true;
      }
    }
    if (results.value == 0xFFB04F) {          //  Key '3' is pressed which belongs to the yellow LED
      if (isYellowOn == true) {               //  Yellow LED is on, turn it off and set update corresponding state variable
        digitalWrite(YEL_LED_PIN, LOW);
        isYellowOn = false;
      } else {                                //  Yellow LED is off, turn it on and set update corresponding state variable
        digitalWrite(YEL_LED_PIN, HIGH);
        isYellowOn = true;
      }
    }
    if (results.value == 0xFF30CF) {          //  Key '4' is pressed which belongs to the red LED
      if (isRedOn == true) {                  //  Red LED is on, turn it off and set update corresponding state variable
        digitalWrite(RED_LED_PIN, LOW);
        isRedOn = false;
      } else {                                //  Red LED is off, turn it on and set update corresponding state variable
        digitalWrite(RED_LED_PIN, HIGH);
        isRedOn = true;
      }
    }
    receiver.resume();                        //  Continue listening for new signals
  }
}

Troubleshooting infrared sensor module

While setting up your project and following the steps you may encounter many weird situations. Here is the list of some common errors that you may get when working with IR sensor.

Getting FFFFFF when pressing a key

When pressing a button you may notice that most of the time it reports a code like FFFFFF. This happens when you press a button and hold it for a while, even for a short period of time. The scenario is that when you press the button initially, IR remote sends the button code and as long as you hold the button, it repeats sending FFFFFF which means that user is still pressing the button reported recently. That would be OK. You can just omit them. The actual code is the one you got right before FFFFFF on the Serial Monitor.

IR Sensor doesn’t react at all and seems it’s getting warm!

Cut the power!!! If you’re sure that the key code logger sketch is correct, then the problem maybe due to the wrong setup of your wires. Most probably you’ve connected the Vcc and GND in a wrong way. It may have already burned your infrared sensor.

Sometimes the sensor detects a code that I’ve never seen before

This is one of the most common issues. It’s most likely due to one of the following reasons:

You’re not pointing your IR remote directly toward the sensor

This will lead to having some new codes (mostly longer codes) that you’ve never received before and normally doesn’t match with the length of the codes you already have. So remember to always point the remote towards your sensor.

You’re using a cheap IR remote (like the one we used in this tutorial)

Instead of using a cheap unpredictable remotes, you can try the same scenario using your TV or DVD Player remote control or an IR remote of any devices you have. They normally have a good signal/hardware quality (and of course are more expensive) and based on our experience, they normally work well even if you don’t point your remote directly toward the sensor.

How do I know if the code that is logged is not a garbage?

The codes are normally presented in hexadecimal format. If you convert them to the corresponding binary value, you’ll notice that the binary representation of the last byte is the negation of the byte comes before that. By knowing this, you can do this check in your code to make sure that the code you received is actually a valid one or not. As an example, if you got FF7A85 its binary representation would be as below:

1111 1111 0111 1010 1000 0101

From left to right, each batch of 4 digits are representation of a character in the original hexadecimal number. As you can see, the batch corresponding to 7 is 0111 and the batch corresponding to 8 is 1000 which is the exact negation of it. Negation means all 0s would be 1s and all 1s would be replaced by 0s. The same is true for the next one which is A (1010) and 5 (0101).

Please follow and like us:

You may also like...

Leave a Reply