bclose

58 – Infrared sensors

Objectives

 

 

    • Demystify infrared light.
    • Introduce infrared sensors (IR).
    • Learn how to use a IR remote control with your Arduino .
    • Example sketchs.
    • The switch-case statement.
 

Bill of materials

Arduino UNO

 Arduino UNO or equivalent.

Breadboard
Jumper wires

 Una breadbroad plus some jumper wires.

 Infrared sensor
Infrared sensor in a breakout board

An AX1838HS IR sensor,  stand alone or in a breakout board.

 

 

INFRARED REMOTE CONTROLS

 

We are so used to infrared remote controls that we don’t give time over to think about them. They are nowadays familiar to us, although they would have seemed magic to our grandparents.

Today it seems normal that electronic equipment, televisions, stereos, air conditioners, respond to our instructions without having to get up from the sofa, but this has not always been the case, moreover, these kind of controls have become popular not so long ago.
We have heard that they operate by using infrared rays and not much more. I wonder how many people would answer correctly to what infrared rays are and which principle of operation is behind a remote control.

To focus some ideas, let’s start by saying that the electromagnetic waves are characterized mainly by their frequency or what is the same, the inverse of this, that is, the wavelength.

They are similar to sound waves. Those that have a lower frequency are called infrasounds, and after them come the sound waves, of course. A little above we find the ultrasounds (surprising names, which basically means below and above what you hear).

In the electromagnetic spectrum, we find first radio waves and microwaves. Then as you see in this image, we can see the infrared zone (below red), the spectrum of visible light with the familiar colours (which are just one way our brain perceives the light frequencies) and then the ultraviolet (above violet).

Further up the scale we find the X-ray (when the German scientist Roentgen discovered this kind of radiation in the late nineteenth, he had no idea of what it was, so it seemed a good idea to call them X-rays, or unknown, and we still continue with this joke) and finally the gamma or cosmic rays.

Electromagnetic spectrum

The amount of radiation energy increases rapidly with frequency, that is why X-rays and gamma rays are very harmful to living beings.

One way to describe the infrared rays would be a light with a different wavelength, that we are not able not see, but nevertheless light.

A little-known curiosity is that the camera of your mobile phone or tablet is able to see and show the IR radiation of your remote controls.

Infrared light is suitable for remote controls because:

 
  • Uses a light frequency that makes no harm in living tissues. It has less impact than visible light.
  • As we often watch TV in the dark, we do not see it when using the remote control.
  • Its range is relatively short, but we do not usually watch TV or have the stereo beyond 2 or 3 meters away.
 

So it is practical, simple and cheap (what the manufacturers like), but it also has drawbacks.

The main drawback is that anything with a certain temperature, including us, emits infrared radiation. That is why IR cameras can show people or animals clearly in the dark (as you can see in action or war movies).

And this could interfere with the IR remote control, as well as things like heating, sun and other hot items. So the solution to avoid this is to modulate the signal with a carrier.

The basic idea is to send a train of stable waves (the carrier) and mix it with the information you want to send (the signal). This same principle is used with radio and almost any radio signal that is sent through the air.

We have found this gif image in the subprojects site and I think it is ideal to show the process of modulation and transmission.

IR signal

The emitter is a simple transistor that controls an infrared LED diode, very similar to the normal LEDs diodes we have used so far, but this time designed to emit light in a colour that we are not able to see.

A simple processor in the remote control takes care of the signal generation and mixing with the carrier to ensure that our TV does not receive spurious commands.

 
  • The process of mixing a signal with a carrier is called modulation.
  • The reverse process, that is, to extract the signal from an RF wave and obtain a clean signal is called demodulation.
 

The receiver is a little more complex because the IR emission standards for remote controls, appeared like mushrooms after a storm and each manufacturer presented its own standard.

At the end the industry ended up designing receivers capable of receiving and demodulating almost anything, and as they are sold like cupcakes (because we love to keep our ass glued to the sofa) they are so cheap, besides a technological marvel.

A current typical IR receiver includes the receiver, amplifier-demodulator and ready for use. You can not imagine the amount of electronics that is included in this innocent looking little piece.

 

IR SENSORS

A typical IR receiver, is the AX-1838HS, which costs a few euros and is relatively easy to find in two ways: stand alone and mounted in a breakout board (to be easily connected to our Duinos). In its data sheet you can find this diagram:
AX-1838HS pinout and data sheet

 

Infrared sensorInfrared sensor in a breakout board

The wiring diagram is again trivial, as the AX-1838HS only has 3 pins: Vcc, GND and signal. As we will use an interrupt to read the signal is essential to connect the signal pin to the Arduino pin 2 (Interruption 0) or pin 3 (Interruption 1).

We are going to connect it to pin 2, as can be seen in the code and examples.

 

THE CONTROL PROGRAM

 

So that they can be used in a comfortable way, we will download a library that will make our life easier. Of the several available we liked the one from Hood Nico, for several reasons.

 
  • It is light and very fast to decode IR signals and besides uses very little memory.
  • Although it does not decode everything, it accepts NEC and Panasonic standards and compatibles. It also has a “do your best” mode that seems to work pretty well, what gives us a 85% chance to recognize your remote control.
  • It uses interruptions, which makes it very light and fast . This way we can see a good example of using them.
  • It is of the few able to decode simultaneous signals of several different remote controls, each using a different protocol.
 

First we have to download the IRLremote.zip library, and then install it following the usual procedure we saw in previous chapters.

IRLremote.zip

Once done, we must import the library:

#include "IRLremote.h"

And then we initialize it:

IRLbegin<IR_ALL>(interruptIR);

Let’s start with an example that the author recommends in order to recognize the remote control we use. You can load the following example IRLremote \ ReceiveInterrupt:

#include "IRLremote.h"
const int interruptIR = 0;                 // Arduino interruption 0: Pin 2

uint8_t IRProtocol = 0;                    // Variables to receive data
uint16_t IRAddress = 0;
uint32_t IRCommand = 0;

void setup()
   {     Serial.begin(115200);             // Pay attention to baud rate 
         Serial.println("Startup");
         IRLbegin<IR_ALL>(interruptIR);
   }
void loop()
   { 
         uint8_t oldSREG = SREG;           // Stop interruptions
         cli();
         if (IRProtocol)                   // If it recognizes the protocol
            {
                 Serial.print("Protocol:");
                 Serial.println(IRProtocol);
                 Serial.print("Address:");
                 Serial.println(IRAddress, HEX);
                 Serial.print("Command:");
                 Serial.println(IRCommand, HEX);
                 IRProtocol = 0;
            }
         SREG = oldSREG;
    }

void IREvent(uint8_t protocol, uint16_t address, uint32_t command)
    {
        IRProtocol = protocol;             // We store the values and come back
        IRAddress = address;
        IRCommand = command;
    }

This program simply tries to read your remote control and send that information to the console. Make sure you set the baud rate at 115200:

Recepcion de codigos infrarrojos

As you see the interruption service routine simply shows the values of the protocol that the library kindly he acknowledges on the fly. These values are:

 
  • It informs about the signal model that our remote control uses. Right now it recognizes four protocols and the author seeks the cooperation of users, to increase the number of available protocols within the library. Currently they are:
    • IR_NO_PROTOCOL ,  0
    • IR_USER, 1
    • IR_ALL,  2
    • IR_NEC, 3.
    • IR_PANASONIC,  4
  • Address of your remote control. Each remote control has a address that identifies it. You could use more than one remote control and they will be recognized separately.
  • The command or which button is pressed on the remote control. Each button has a different code and these codes will be used in your programs to launch different actions, depending on the pressed button.
 

We have tried 5 different IR remote controls (we have many junk) and 4 were recognized correctly at first: Panasonic, Sony, LG and Keyes.

The one that was not recognized was an old remote control from a Schneider TV that we didn’t know where it came from.

 
  • We should mention that if you have an old CRT TV, a video recorder or something like this that you no longer use, throw the appliance if you want but keep the remote control because chances are that it can be recognized by your Arduino.
  • In addition your old junk, having remote control, include this IR receivers, so they can be disassembled and reused for your stuff. (I recommend disassembling only the old and useless gadgets, not those who are working…).
 

And in this sketch is already implicit everything you need to use an IR remote control in your projects. The rest of the chapter is simply an example of how to manage these keystrokes with a switch statement, that is a C++ statement that we had not ever used.

We will assemble a prototype with Arduino and 4 coloured LED diodes to turn them one at a time or all at once, using the IR remote control.

 

SCHEMATIC AND WIRING DIAGRAMS

 

The schematic is quite simple:

Chapter 52, schematic diagram

And the wiring diagram is harder to draw than to assemble:

 

Chapter 52, wiring diagram

 

THE CONTROL PROGRAM

 

At the beginning of this chapter we saw that we received instructions from the remote control (I hope so) and on the console was shown the value of the protocol, its address and which command corresponded to the button pressed. These commands are what you need for your sketch to start working.

 
  • If you have more than one remote control and want to use them, you’ll have to also control the address of each remote control.
 

First you have to run the previous sketch to record the codes that correspond to each key of your remote control, and write a table. You don’t have to write all keys for now, but at least those that we are going to use.

The results from the LG remote control were the following:

UpDownLeftRightOK0x02FD0x827D0xE01F0x609F0x22DD

And using these values we can write the control program. We will use the switch-case statement, which is very comfortable when you have to check many values and take some action in response to a variable. The basic idea is like this:

switch (IRCommand)
   {   case 0x02FD:
           Serial.println("Up");
           digitalWrite(8, HIGH);
           break;
case 0x827D:
           Serial.println("Down");
           digitalWrite(9, HIGH);
           break;
case 0xE01F:
           Serial.println("Left");
           digitalWrite(10, HIGH);
           break;
case 0x609F:
           Serial.println("Right");
           digitalWrite(11, HIGH); 
           break;
case 0x22DD:
           Serial.println("OK");
           for (int k =0 ; k <12 ; k++)
                digitalWrite(k, LOW);
            break;
}

The switch statement analyzes the variable whose value determines what action to take, in this case which button was pressed. And then a case clause is set for each possible value. Note that all case clauses end with a colon. Then come the statements to be executed and the cause clause ends with a break statement. The break statement ends the switch-case statement and prevents the execution of other case clauses.

We have written on purpose a Serial.println() so you can see that you can write several statements without using a block of code, because it is already implicit in the case.

You can include a default clause at the end, just in case you want an action to be executed if the value of the variable does not match any other case specified above.

Here you have a example sketch:

Sketch 58.1
#include "IRLremote.h"
const int interruptIR = 0;

uint8_t IRProtocol = 0;  // Variables to receive the data
uint16_t IRAddress = 0;
uint32_t IRCommand = 0;

void setup() 
   {    Serial.begin(115200);          // Pay attention to baud rate
        for (int i = 8 ; i<12 ; i++)
        pinMode(i, OUTPUT);

        IRLbegin<IR_ALL>(interruptIR);
   }

The only new thing up here, has been to define as output the pins from 8 to 11:

void loop()
   {    uint8_t oldSREG = SREG;  // Stop the interruptions
        cli();
        if (IRProtocol)
          {  
              switch (IRCommand) // Here we have the switch-case statement
                  { case 0x02FD:
                        Serial.println("Up");
                        digitalWrite(8, HIGH);
                        break;
                    case 0x827D:
                        Serial.println("Down");
                        digitalWrite(9, HIGH);
                        break;
                    case 0xE01F:
                         Serial.println("Left");
                         digitalWrite(10, HIGH);
                         break;
                    case 0x609F:
                         Serial.println("Right");
                         digitalWrite(11, HIGH);
                         break;
                    case 0x22DD:
                         Serial.println("OK");
                         for (int k =0 ; k <12 ; k++) 
                              digitalWrite(k, LOW);
                         break;
                  }
              IRProtocol = 0;
          }
       SREG = oldSREG; 
    }
void IREvent(uint8_t protocol, uint16_t address, uint32_t command)
   {
        IRProtocol = protocol;  // Recogemos los valores
        IRAddress = address;
        IRCommand = command;
   }

The switch clause is very useful to avoid nested if-else statements that make you lose the thread. Imagine that you have to check all the possible keys of a remote control.

Finally and before finishing, we should comment that the author of the library recommended that if we are to use a single command, we must replace the following line:

IRLbegin<IR_ALL>(interruptIR);

by one that matches our model because this way we will save memory and speed in decoding the signals. In our case, as the protocol is 3, IR_NEC, we would use:

IRLbegin<IR_NEC >(interruptIR);

 

 

 

Summary

 

 

    • We have a clearer picture of what infrared light is.
    • We have introduced the AX-1838HS, IR remote control’s sensor.
    • We have seen we can use the remote controls we have at hand and that our Arduino is able to read most of them.
    • We have seen the switch-case statement.
 

 

 

 

 

No Comments

Give a Reply