Posts Tagged ‘infrared’

Arduino, Ir and X10 Video

I made this short video to complete my previous post.

Arduino and Infrared … (Part 3)

That post is due for a long time. I’ll continue with the infrared project and add control of X10 devices in your house. Don’t know what X10 is? Click here to learn more.

Arduino, IR and X10

Arduino, IR and X10

The code in this post is not much different than the code presented on part 2 of this series. In addition to controlling red, green and yellow LEDs, we will control your home appliances. To do so, you will need two new parts, the X10 transmitter and an X10 appliance receiver. Simply Google “X10 devices” to find stores selling these in your area.

You connect to the X10 transmitter using a standard telephone cable. Make sure you use a 4 wires cable. Many phones are sold with two wire cables. Keep one connector to connect to the transmitter and strip the wires on the other end to connect to your circuit.

Telephone cable

Telephone cable

In our example, the match between the colors of the telephone cable wires and the modem pin numbers is the following:

#1 => Black
#2 => Red
#3 => Green
#4 => Yellow=4

X10 Modem connector

X10 Modem connector

The complete circuit should be wired as following. The black wire (pin #1) should be connected to a pull-up 10K resistor and the red wire (pin #2) to the ground. The yellow wire (pin #4) must be connected to the output signal pin of the Arduino board. Finally, the green wire (pin #3) of the modem is not connected.

Arduino, IR and X1 Circuit

Arduino, IR and X1 Circuit

Additions to this project code are the calls to the X10 library. Following are the differences with the code of the previous project. You can download the complete project on my Github account: https://github.com/pchretien/ir_x10

#include <x10.h>
#include <x10constants.h>

...

#define ZC_PIN 2
#define DATA_PIN 3
#define X10_REPEAT 3

...

x10 myHouse = x10(ZC_PIN, DATA_PIN);

...

void setup()
{
  ...
  // X10 Controller
  myHouse.write(A, ALL_UNITS_OFF,3);
}

...

void loop()
{
    // POWER BUTTON 279939191
    // Toggle red LED and X10 device when POWER button command is received
    if( code == 279939191 && bit_position > 0)
    {
      myHouse.write(A, UNIT_1, X10_REPEAT);    

      red_led_state ^= 1;
      if(red_led_state)
      {
        myHouse.write(A, ON, X10_REPEAT);
        digitalWrite(RED_LED, HIGH);
      }
      else
      {
        myHouse.write(A, OFF, X10_REPEAT);
        digitalWrite(RED_LED, LOW);
      }
    }
}

...

You can download the X10 library at the following location:
http://www.arduino.cc/en/Tutorial/X10

Arduino and Infrared … (Part 2)

ir arduino

Arduino and infrared (IR) remotes (Part 2)

In the first article of the series, I explained how to break the code of a standard infrared remote control. In this article, we will use these results to control real world devices. The so called “real world devices” are, at this point of the project, three LEDs. I’ll keep lamps and washing machines control for the next article about X-10 control.

The first step is to convert the pulses we receive into streams of bits. The remote we will use for this project is an old air conditioning remote control. Following are the results for the remote control protocol:

  • Threshold start pulse duration: 4000 micro seconds
  • Threshold “1″ bit pulse duration: 1500 micro seconds
  • Threshold ”0″ bit pulse duration: 400 micro seconds
  • Threshold repeat pulse duration: 2000 micro seconds
  • Bit stream length: 32 bits

These values are used to build binary streams to reconstruct the 32 bit commands emitted by the remote control. Once the code values are known, we can add behavior in our micro controller. The command code is built using X-Or operations with the bits received from the remote.

The power-on/power-off command of our remote control match the decimal number 279939191. When the button is pressed, the red LED is toggled on/off. The green LED is turned off during the time the Arduino is processing a command. If a new command is sent while the green LED is off, the program wont be able to catch it. Finally, the yellow led is flashes ON for 50 milliseconds every time a repeat command is received.

Using this code you can control about anything you want using an infrared remote control. In the next article we will control lamps through X-10 power line protocol.

Philippe Chrétien

#define DEBUG 0

#define IR_LED 7
#define GREEN_LED 6
#define RED_LED 5
#define YELLOW_LED 4

#define MAX 128
#define MICRO_STEP 10

#define IDLE_PULSE 10000
#define START_PULSE 4000
#define REPEAT_PULSE 2000
#define ONE_PULSE 1500
#define ZERO_PULSE 400

unsigned long pulses[MAX];
unsigned long code = 0;
int red_led_state = 0;

void setup()
{
  pinMode(IR_LED, INPUT);
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(YELLOW_LED, OUTPUT);
  digitalWrite(RED_LED, LOW);
  digitalWrite(GREEN_LED, HIGH);
  digitalWrite(YELLOW_LED, LOW);

  // For debug
  Serial.begin(115200);
}

void loop()
{
  // The IR receiver output is set HIGH until a signal comes in ...
  if( digitalRead(IR_LED) == LOW)
  {
    // No command can be received while the green LED is off
    digitalWrite(GREEN_LED, LOW);

    //Start receiving data ...
    int count = 0; // Number of pulses
    int exit = 0;
    while(!exit)
    {
      while( digitalRead(IR_LED) == LOW )
        delayMicroseconds(MICRO_STEP);

      // Store the time when the pulse begin
      unsigned long start = micros();
      int max_high = 0;
      while( digitalRead(IR_LED) == HIGH )
      {
        delayMicroseconds(MICRO_STEP);
        max_high += MICRO_STEP;
        if( max_high > IDLE_PULSE )
        {
          exit = 1;
          break;
        }
      }

      unsigned long duration = micros() - start;
      pulses[count++] = duration;
    }

    // Build code from pulses
    int repetitions = 0;
    int bit_position = 0;
    unsigned long bit = 2147483648; // 10000000000000000000000000000000 in binary
    unsigned long new_code = 0;
    for(int i=0; i<count; i++)
    {
      if(pulses[i] > IDLE_PULSE)
      {
        // Ignore very long pulses
        continue;
      }
      else if(pulses[i] > START_PULSE)
      {
        // Start pulse received ... start counting bits
        new_code = 0;
        bit_position = 0;
      }
      else if(pulses[i] > REPEAT_PULSE)
      {
        // Repetition command ... no bit pulses here.
        repetitions++;
      }
      else if(pulses[i] > ONE_PULSE)
      {
        // Receives "1"
        if(DEBUG)
          Serial.print("1");
        new_code |= bit >> bit_position++;
      }
      else if(pulses[i] > ZERO_PULSE)
      {
        // Receives "0"
        if(DEBUG)
          Serial.print("0");

        bit_position++;
      }
    }

    if( new_code )
    {
      // This was not a repeat command
      code = new_code;
    }

    // Display the code received and number of bits or, repetitions.
    if(DEBUG)
    {
      if( !new_code)
      {
        Serial.print("                                ");
      }

      Serial.print("     ");
      Serial.print(bit_position, DEC);
      Serial.print(" bits ");
      Serial.print(repetitions, DEC);
      Serial.print(" repetition(s) code = ");
      Serial.print(code, BIN);
      Serial.print(" (");
      Serial.print(code, DEC);
      Serial.print(")");
      Serial.println("");
    }

    // Flashes the yellow LED for every repeat commands
    if( repetitions > 0 )
    {
      for( int i=0; i<repetitions; i++)
      {
        digitalWrite(YELLOW_LED, HIGH);
        delay(50);
        digitalWrite(YELLOW_LED, LOW);
        delay(50);
      }
    }

    // Toggle red LED when power button command is received
    if( code == 279939191 && bit_position > 0)
    {
      red_led_state ^= 1;

      if(red_led_state)
        digitalWrite(RED_LED, HIGH);
      else
        digitalWrite(RED_LED, LOW);
    }

    // Ready to process an other command
    digitalWrite(GREEN_LED, HIGH);
  }
}

Arduino and Infrared (IR) Remotes

This Article is the first of a series on programming an Arduino micro controller to control X-10 devices using an infrared (IR) remote control. This is a relatively cheap project. To make the first part of this project you will need an Arduino micro-controller, an IR receiver and any IR remote control. The overall cost should not exceed $50.

Arduino and IR receiver

Arduino and IR receiver

First you need to crack the protocol of the IR remote control you picked up. You can pretty much use any IR remote control you have in your house - no complex circuit is required. If you purchased the ZX-IRM infrared receiver, you can connect it directly to your Arduino board. Otherwise, you will find plenty of information on the web on how to build an IR receiver.

Infrared communication is carried using pulses of infrared light. Most packets of data contain about 16 bits of data. The duration of the light pulse determines if the bit transferred is 0 or 1. The following program displays all light pulses received through the infrared (IR) receiver. This information will help you crack the protocol used by your remote control. Because of delays produced by the Serial communication with the Arduino board, there may be some inconsistencies in the data displayed. I recommend pressing more than once the remote key to get an accurate reading of the binary stream received.

These are the things you first have to look at when reading the program outputs:

  • The duration of the START pulse.
  • The duration of 0 and 1 pulses.
  • The presence and duration of a STOP/REPEAT pulse.
  • The length, in bits, of the data stream.
#define IR_LED 7
#define MAX 128
#define MICRO_STEP 10
#define IDLE_PULSE 10000

unsigned long pulses[MAX];

void setup()
{
  pinMode(IR_LED, INPUT);
  Serial.begin(115200);
}

void loop()
{
  // The IR receiver output is set HIGH until a signal comes in ...
  if( digitalRead(IR_LED) == LOW)
  {
    //Start receiving data ...
    int count = 0;
    int exit = 0;
    while(!exit)
    {
      while( digitalRead(IR_LED) == LOW )
        delayMicroseconds(MICRO_STEP);

      // Store the time when the pulse begin
      unsigned long start = micros();

      int max_high = 0;
      while( digitalRead(IR_LED) == HIGH )
      {
        delayMicroseconds(MICRO_STEP);
        max_high += MICRO_STEP;
        if( max_high > IDLE_PULSE )
        {
          exit = 1;
          break;
        }
      }

      unsigned long duration = micros() - start;
      pulses[count++] = duration;
    }

    for(int i=0; i<count; i++)
    {
      if(pulses[i] > IDLE_PULSE)
      {
        Serial.print("<");
        Serial.print(pulses[i], DEC);
        Serial.print(">|");
      }
      else
      {
        Serial.print(pulses[i], DEC);
        Serial.print("|");
      }
    }

    Serial.println(".");
  }
}

The start pulse is always the first and longest pulse of the stream. This pulse marks the starting point of the data stream. Subsequent to the start pulse are the data bits. There is no standard for this stream of bits but you will usually find about 8 to 16 bits of data.

Following the data stream, you should look for the stop pulse. The stop pulse is not mandatory and in most protocols, the stop pulse is used to signal command repetition. If the user maintains the remote button pressed, the stop pulse is sent repeatedly until the button is released. However, if there is no stop pulse, the data stream, starting with the start pulse, is repeatedly sent in its entirety when the remote button is maintained pressed.

Finally, you should look for the length of the data stream sent by the remote control every time a button is pressed. Most new remotes are using a fixed length data stream. You can easily determine the length of the stream by counting the number 0 and 1 pulses received for each command.

In the next article, I will put everything together and start writing code in order to use the remote control.

Philippe Chrétien