libelium
  • rss
  • flickr
  • instagram
  • twitter
  • facebook
  • youtube

Control your Infrared Devices from the Internet with
IR Remote (Arduino UNO / Raspberry Pi Compatible)

Manage HVAC Devices such as air-conditioning, heating, ventilation and thermostats from the Cloud

IR Remote is a small shield that allows you to record any infrared command sent by a remote control and resend it from the Internet. It works connected to Arduino and Raspberry Pi, and let us to control any HVAC system including heating, ventilation, air-conditioning and thermostats from the Cloud.

We offer 6 different wireless interfaces to connect Arduino and Raspberry Pi to the Internet: WiFi, 3G, GPRS, Bluetooth and 802.15.4 / ZigBee.

With IR Remote you can easily control our home HVAC system from a laptop, a webserver or even from your smartphone. The shield is compatible with both Arduino UNO and Raspberry Pi so you can choose your favourite platform to automate your home.

IR Remote Shield over Arduino (left) Raspberry Pi with the connection bridge (right)

HVAC applications

Your home's HVAC system includes a number of heating, cooling, and ventilation components controlled with infrared technology that all work together to make your indoor living spaces more comfortable. IR Remote shield allows control these devices through Internet.

Features

  • 38KHz Infrared technology
  • Infrared remote control device
  • Easy HVAC (heating, ventilation, and air conditioning systems) IR Remote control
  • Copy and resend IR signals
  • Provide remote control capability to your project.
  • Compatible with several UART communication protocols (Wifi, 3G, ZigBee,GPRS, Bluetooth)
  • Compatible with Arduino UNO and Raspberry Pi
  • Programmable hardware interface: 2 LEDs (blue and orange) / 2 push-buttons

IMPORTANT: IR Remote has been developed and programmed in order to work with Arduino UNO. It is Hardware Compatible with most Arduino boards, but there are no available tested codes. Raspberry Pi also support this hardware, although due to kernel priorities IR module does not work correctly with ArduiPi.

NOTE: If you are interested in Wireless Sensor Networks (WSN), M2M and the Internet of Things (IoT) projects check our new open source sensor platform: Waspmote which counts with more than 70 sensors available to use and a low consumption mode of just 0.7uA to ensure years of battery life. Know more at:

Get the IR Remote Kits

Article Index

  1. Features
  2. Infrared technology
  3. Main application: HVAC IR Remote control
  4. More IR applications
  5. Others applications
  6. Links and documentation source
  7. Get the IR Remote Kits

1. Features

1.1 Electrical features

The IR Remote shield use IR333_A 38Khz infrared emitter diode and TSOP38238 receiver module.

The power supply is from Arduino UNO or Raspberry Pi 5V voltage source of ICSP connector.

  • Power Supply: 5V
  • Compatible with Raspberry Pi GPIO
  • Interface: Digital
  • Modulate Frequency: 38Khz

Download the IR components datasheets:

Download the IR Remote schematics: Download

IR Remote diagram

IR Remote PCB

1.2 Extra hardware features

IR Remote shield has some extra hardware features usable with infrared technology. Use some of the digital I/O with a basic circuit:

  • Two programmable digital inputs: PUSH-BUTTONS connected to digital pins 4 and 5

    We can read pin state and use it to send or copy IR command.

  • Two programmable digital outputs: LEDs (orange and blue colour) connected to digital pins 6 and 7

    We can turn an LED on/off when the shield receive a IR command.

IR Remote over Arduino UNO

Click here to get Arduino UNO

IR Remote over Raspberry Pi

In order to connect the IR Remote to Raspberry Pi an adaptor shield is needed.

Click here to know more about the Raspberry Pi to Arduino Shields Connection board

2. Infrared technology

The technology known as IrDA (Infrared Data Association), is developed by HP, IBM and SHARP in 1993 and is based on light rays moving in the infrared spectrum (Invisible to human eyes).

Infrared technology is awesome. IR devices can be used for remote control and even basic remote data communication. Using infrared transmitters and receivers (usually LEDs) can comunicate two devices with direct line of vision.

Have you ever needed a cheap way to activate something from across the room? Infrared is still the cheapest way to wireless control device.

On this tutorial, we will show how to use IR Remote as an IR sender and receiver with ArduinoUNO/Raspberry Pi.

How to know if our device works with infrared technology

Using your mobile phone, you can see infrared radiation. Visible light and infrared are both forms of electromagnetic radiation but with different wavelengths. Visible light has a wavelength of between 400nm and 700nm. We can only “see” the EM radiation in this range. At 700nm and longer, we enter the realm of infrared radiation.

The lack of infrared filter is one reason photographs taken on mobile phones don’t look as good as those taken on proper digital cameras but it also provides us with an opportunity to use our mobiles to “see” in infrared.

On your phone, start the Camera app, and point the camera at the LED on one IR Remote control device.

As you look at the phone screen, press some buttons on the device. For example, a TV remote control. Your eye can't see the IR light, but now you will see the IR light appear in the viewfinder as a bright white light.

This method can verify that the module is working properly as emitter.

2.1 IR Sensor (receiver)

IR detectors are little microchips with a photocell that are tuned to listen to infrared light. They are almost always used for remote control detection. IR Remote use TSOP38238 infrared receiver and it can be used to read the signals from common IR remote controls. It is useful for receiving consumer remote control IR signals.

The TSOP1238 is an Infrared signal receiver which can be powered from 2.5 V to 5.5 V. This receiver is ready to be connected to a micro-controller and is capable of receiving signals at 38Khz, the same frequency that use several infrared devices. We used a receiver centered at 38kHz, but it will work over a larger range of frequencies at a reduced distance. You can use from about 35 KHz to 41 KHz but the sensitivity will drop off.

This circuit is recommended by the datasheet:

The IR sensor has just three pins: signal, Vcc and GND. The sensor connects to pin 2 to record the code allowing use interrupt feature in Arduino UNO and Raspberry so we can detect the start of IR activity.

The sensor pinout is indicated on the datasheet: TSOP38238

2.2 IR Diode (emitter)

The Infrared Emitter is used to transmit infrared signals. An infrared LED or emitter is used to transmit signals. An infrared LED is like any other LED, with its color centered around 940nm. We can use the emitter not only to transmit data or commands, but also to emulate remotes to control your home appliance. Along with an IR receiver they can be used for remote control and even basic remote data communication.

The transmitter is connected to digital PWM pin 3. The PWM makes it easy to create infrared pulses at frequencies visible to IR receivers. The circuitry is simple: an IR LED is connected to pin 3 to transmit the code.

The LED features are indicated on the datasheet: IR333_A

3. Main application: HVAC IR Remote control

We use infrared technology every day but... is too much effort to press the buttons! Surely are there better ways to control a device? Can we turn off our air conditioning in the supermarket? The main IR Remote application is to capture the IR sequences and then using the ArduinoUNO/Raspberry Pi send them using different inputs (buttons, wireless signals...).

The main purposes of a Heating, Ventilation, and Air-Conditioning (HVAC) system are to help maintain good indoor air quality through adequate ventilation with filtration and provide thermal comfort. HVAC systems are among the largest energy consumers in homes. Whether you wish to improve the efficiency of your existing heating and cooling systems or are considering upgrading to a new system, IR Remote shield is the best option.

One of the first steps you should consider in your facility before upgrading your heating and cooling system is to reduce your load (i.e. how much heating and cooling you actually use). Using IR Remote shield your facility's load allows existing systems to operate less frequently. We can control ventilation to improve occupant comfort and save energy.

IR Remote shield is a simple hack easy and cheap to use. This shield includes everything you need to start playing around with HVAC IR Remote control systems.

NOTE: Unfortunately there are almost as many infrared protocols as devices that use them. Some manufacturers encode their infrared signals privately so it may not be possible to copy their IR codes easily.

3.1 IR Remote on Arduino UNO

Record and playback IR signals

It is very easy to use this shield. However, if you want to integrate IR Remote shield into an existing infrared remote system, then you need to identify the protocol in use. The first step is to capture that protocol. Here are some guidelines on how to start.

The sketch provides a simple example of how to receive and re-send a IR code:

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

#define IRpin_PIN PIND
#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0;

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing
uint8_t sendpulse = 0; // Index for send pulses

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(9600);
}

void loop(void) {
   // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  // Read the state of the "Receive" push-button value
  buttonState2 = digitalRead(buttonPin2);
 
if (buttonState1 == HIGH) {   
    Serial.println("Sending IR signal");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    }

 if ((buttonState2==HIGH) || (currentpulse != 0)){
   
   if (buttonState2==HIGH){
    Serial.println("Ready to decode IR!");
    digitalWrite(blueLedPin, HIGH); 
    delay(200);
    digitalWrite(blueLedPin, LOW); 
    delay(200);
   }

  uint16_t highpulse, lowpulse; // Temporary storage timing
  highpulse = lowpulse = 0; // Start out with no pulse length
  
    while (IRpin_PIN & (1 << IRpin)) {
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
  
 }
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived:");
  for (uint8_t i = 0; i < currentpulse; i++) {
  
    if (i != 0){
    Serial.print("delayMicroseconds(");
    Serial.print(pulses[i][0] * RESOLUTION);
    Serial.println(");");
    }
    Serial.print("pulseIR(");
    Serial.print(pulses[i][1] * RESOLUTION);
    Serial.println(");");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
*/ 
}

// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {

  for (uint8_t i = 0; i < sendpulse; i++) {
  
    if (i != 0){
    delayMicroseconds(pulses[i][0] * RESOLUTION);
    }
    
    pulseIR(pulses[i][1] * RESOLUTION);
  }
}

To copy a IR code, simply point your remote control in front of the IR Remote shield connected in Ardunio (for example) and press the button on the remote control you want to copy. Use "Receive" button on the module to copy the code and "Send" button to re-send it.

When you press the "Receive" button, the blue LED on the other shield should blink. In this moment the module is waiting IR signal. When IR Remote shield just copy IR code, the orange LED blink too. Now we process the codes slightly and put them in an array.

Once a IR code has been copied, you can use "Send" button to re-send many times as we want. The orange LED indicates that the message has been sent.

NOTE: In order to work with Arduino MEGA you'll need to change in our codes to PINE not PIND and IRpin 4 for digital 2 on the mega. You should use the following mod for use with the Mega 2560:

/*
    //#define IRpin_PIN      PIND
    //#define IRpin          2
   
    // Using Arduino MEGA 
    #define IRpin_PIN PINE
    #define IRpin 4 

}

How to receive

IR Remote shield uses an infrared receiver connected to digital input pin 2.

We cant use normal digitalread() function because it is so slow to read the fast IR signal. So we must use special reading procedures. With this method we can easily read codes.

If you upload next code and open serial monitor while pointing a remote control and pressing the ON button you will get the IR code. You can copy it and use it in other programs. Do not copy the first delay [delayMicroseconds(#)] because it is the time spent to detect the IR code.

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

#define IRpin_PIN PIND
#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0;

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(9600);
}

void loop(void) {
  // Read the state of the "Receive" push-button value
  buttonState2 = digitalRead(buttonPin2);
 
 if ((buttonState2==HIGH) || (currentpulse != 0)){
   
   if (buttonState2==HIGH){
    Serial.println("Ready to decode IR!");
    digitalWrite(blueLedPin, HIGH); 
    delay(200);
    digitalWrite(blueLedPin, LOW); 
    delay(200);
   }

  uint16_t highpulse, lowpulse; // Temporary storage timing
  highpulse = lowpulse = 0; // Start out with no pulse length
  
    while (IRpin_PIN & (1 << IRpin)) {
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
  
 }
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived:");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print("delayMicroseconds(");
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.println(");");
    Serial.print("pulseIR(");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(");");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
*/ 


}
How to send

IR Remote shield uses an infrared LED connected to output pin 3 to send a IR code. The module turn on and off the LED very fast in the proper code sequence.

We can also send hand-copied IR code, putting it in the section indicated in the program.

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int buttonState1 = 0;  

void setup()   {                
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);
  // Initialize the IR digital pin as an output
  pinMode(IRledPin, OUTPUT);      
  // Set uart baudrate
  Serial.begin(9600);
}
 
void loop()   {
  // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  
  if (buttonState1 == HIGH) {   
    Serial.println("Sending IR signal");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    }
}
 
// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {

/**************************
 * COPY YOUR IR CODE HERE *
 * ************************/

}

NOTE: Some devices need to receive the code duplicate, so you have to send it two times.

3.2 IR Remote on Raspberry Pi

NOTE: Operating with IR commands requires an strict timing control. On Raspberry pi there are many user space applications running at the same time and the kernel scheduler must deal with all of them. For this reason the IR user space applications are not as reliable as on arduino.

IR Remote board requires the arduPi library.

Creating a program that uses the library is as simple as putting your code in this template where it says "your arduino code here"

Compiling programs can be done with the following comnmand:

g++ -lrt -lpthread arduPi.cpp myapp.cpp -o myapp

Executing your program is as simple as doing:

sudo ./myapp

Here are some application examples:

Buttons and leds test application:

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

#include "arduPi.h"

int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0; 

void setup() {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
}

void loop(){
  // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  printf("%d\n",buttonState1);
  // Read the state of the "Send" push-button value
  buttonState2 = digitalRead(buttonPin2);
  printf("%d\n",buttonState2);

  if (buttonState1 == HIGH) {     
    // Turn LED on:    
    digitalWrite(orangeLedPin, HIGH);  
  } 
  else {
    // Turn LED off:
    digitalWrite(orangeLedPin, LOW); 
  }

  if (buttonState2 == HIGH) {     
    // Turn LED on:    
    digitalWrite(blueLedPin, HIGH);  
  } 
  else {
    // Turn LED off:
    digitalWrite(blueLedPin, LOW); 
  }
}

int main (){
	setup();
	while(1) loop();
	return 0;
}

Copy application:

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

#include "arduPi.h"

#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0;

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing

void printpulses(void);

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
}

void loop(void) {
  // Read the state of the "Receive" push-button value
  buttonState2 = digitalRead(buttonPin2);
 
 if ((buttonState2==HIGH) || (currentpulse != 0)){
   
   if (buttonState2==HIGH){
    fprintf(stderr,"Ready to decode IR!\n");
    digitalWrite(blueLedPin, HIGH); 
    delay(200);
    digitalWrite(blueLedPin, LOW); 
    delay(200);
   }

  uint16_t highpulse, lowpulse; // Temporary storage timing
  highpulse = lowpulse = 0; // Start out with no pulse length
  
    while (digitalRead(IRpin)) {
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (!digitalRead(IRpin)) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
  
 }
}

void printpulses(void) {
  printf("\n\r\n\rReceived:\n");
  for (uint8_t i = 0; i < currentpulse; i++) {
    if (i != 0){
    printf("delayMicroseconds(");
    printf("%d",pulses[i][0] * RESOLUTION);
    printf(");\n");
	}
    printf("pulseIR(");
    printf("%d",pulses[i][1] * RESOLUTION);
    printf(");\n");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
*/ 
}

int main(){
	setup();
	while(1){
		loop();
	}
	return 0;
}

Send application:

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

#include "arduPi.h"

void SendIRCode();

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int buttonState1 = 0;  

void setup()   {                
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);
  // Initialize the IR digital pin as an output
  pinMode(IRledPin, OUTPUT);      
  // Set uart baudrate
  Serial.begin(9600);
}
 
void loop()   {
  // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  
  if (buttonState1 == HIGH) {   
   printf("Sending IR signal\n");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    }
}
 
// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 

  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   
   /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   delayMicroseconds(10);         
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   
   /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   delayMicroseconds(10);         
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 

}
 
void SendIRCode() {

/****************************************************
 * COPY THE CODE GENERATED BY COPY APPLICATION HERE *
 ****************************************************/

}

int main (){
	setup();
	while (1) loop();
	return 0;
}

Copy and send application:

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

#include "arduPi.h"

void SendIRCode();
void printpulses(void);

#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0;

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing
uint8_t sendpulse = 0; // Index for send pulses

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(9600);
}

void loop(void) {
   // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  // Read the state of the "Receive" push-button value
  buttonState2 = digitalRead(buttonPin2);
 
if (buttonState1 == HIGH) {   
    printf("Sending IR signal\n");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    }

 if ((buttonState2==HIGH) || (currentpulse != 0)){
   
   if (buttonState2==HIGH){
    printf("Ready to decode IR!\n");
    digitalWrite(blueLedPin, HIGH); 
    delay(200);
    digitalWrite(blueLedPin, LOW); 
    delay(200);
   }

  uint16_t highpulse, lowpulse; // Temporary storage timing
  highpulse = lowpulse = 0; // Start out with no pulse length
  
    while (digitalRead(IRpin)) {
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (! digitalRead(IRpin)) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
  
 }
}

void printpulses(void) {
  printf("\n\r\n\rReceived:\n");
  for (uint8_t i = 0; i < currentpulse; i++) {
  
    if (i != 0){
    printf("delayMicroseconds(");
    printf("%d",pulses[i][0] * RESOLUTION);
    printf(");\n");
    }
    printf("pulseIR(");
    printf("%d",pulses[i][1] * RESOLUTION);
    printf(");\n");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  printf("int IRsignal[] = {\n");
  printf("// ON, OFF (in 10's of microseconds)\n");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    printf("\t"); // tab
    printf(pulses[i][1] * RESOLUTION / 10, DEC);
    printf(", ");
    printf(pulses[i+1][0] * RESOLUTION / 10, DEC);
    printf(",\n");
  }
  printf("\t"); // tab
  printf(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  printf(", 0};");
*/ 
}

// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   
   /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   delayMicroseconds(10);
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   
   /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   delayMicroseconds(10);
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
}
 
void SendIRCode() {

  for (uint8_t i = 0; i < sendpulse; i++) {
  
    if (i != 0){
    delayMicroseconds(pulses[i][0] * RESOLUTION);
    }
    
    pulseIR(pulses[i][1] * RESOLUTION);
  }
}

int main(){
	setup();
	while (1) loop();
	return 0;
}

3.3 Control air conditioning and heating systems through Internet via WiFi

The simplicity of the procedure enables us to combine with different wireless communications protocols. Only we must copy IR codes and use them in our main program.

Thanks to many communications modules can send data over several transmission protocols.

We will use the wifi module Roving RN-171. This module fits in the XBee socket of our Communication Shield and allows to connect your ArduinoUNO/RasberryPi shield to a WiFi network.

The messages that come from the WIFI module are quite big, for this reason, if you want to debug your program and check those messages, go to /.../arduino-0022/hardware/arduino/cores/arduino and modify HardwareSerial.cpp then make SERIAL_BUFFER_SIZE value set to 512.

This sketch provides a simple example of how to re-send a IR code using WiFi module:

/*
 *  IR Remote for Arduino UNO and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int buttonState1 = 0;  

int val = 0;
char recv[128];
uint8_t cont = 0;

void setup()   {                
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);
  // Initialize the IR digital pin as an output
  pinMode(IRledPin, OUTPUT);      
  // Set uart baudrate
  Serial.begin(9600);
  
   while (Serial.available()>0) {}
    // Enters in command mode
    Serial.print("$$$"); check();
    // Sets DHCP and UDPprotocol
    Serial.print("set ip dhcp 1\r"); check();
    Serial.print("set ip protocol 1\r"); check();
    // Configures the way to join the network AP
    Serial.print("set wlan join 0\r"); check();
    Serial.print("join AndroidAPr"); check();

    Serial.print("set i h 192.168.43.47\r"); delay(1000);

    Serial.print("set i r 2000\r"); check();
    Serial.print("set i l 2000\r"); check();
    Serial.print("exit\r"); check();
    // Envía un mensaje para decirle al ordenador que ya estás conectado y esperas contestación
    Serial.print("HOLA"); check(); 
}
 
void loop()   {
  // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  
  if (Serial.available()>0) { 
    val = Serial.read() ;
    //Serial.println(val);
  }
  
  if ((buttonState1 == HIGH) || (answer == 'A')) { 
    Serial.println("Sending IR signal");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    val = 0;
    }
}
 
// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {

/**************************
 * COPY YOUR IR CODE HERE *
 * ************************/

}

void check(){
  cont=0; delay(500);
  while (Serial.available()>0)
  {
     recv[cont]=Serial.read(); delay(10);
     cont++;
  }
  recv[cont]='\0';
  Serial.println(recv);
  Serial.flush(); delay(100);
}

In this video we see an example of application: HVAC video-example

Refer to Wifi tutorials (Arduino) (Raspberry) for more information.

3.4 Control air conditioning and heating systems through Internet via 3G / GPRS

GPRS Quadband Module for Arduino/Raspberry (SIM900) offers GPRS connection to your ArduinoUNO/RasberryPi board. You can send your data by SMS or do missed calls from your Arduino UNO to mobile devices... or to another ArduinoUNO/RasberryPi connected to this module.

The code example and the connection picture shown below are used to copy and re-send a IR code using GPRS module. A lost call activate the "send" function.

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

#define IRpin_PIN PIND
#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0;

int8_t answer;
int onModulePin= 8;    

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing
uint8_t sendpulse = 0; // Index for send pulses

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(115200);
  pinMode(onModulePin, OUTPUT);    
  power_on();
  delay(5000);
  while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 1000) || 
          sendATcommand("AT+CREG?", "+CREG: 0,5", 1000)) == 0 );
  sendATcommand("AT+CLIP=0", "OK", 1000);
}

void loop(void) {
   // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  // Read the state of the "Receive" push-button value
  buttonState2 = digitalRead(buttonPin2);
     
  answer = sendATcommand("", "RING", 1000);
 
if ((buttonState1 == HIGH) || (answer == 1)) {   
    Serial.println("Sending IR signal");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    }

 if ((buttonState2==HIGH) || (currentpulse != 0)){
   
   if (buttonState2==HIGH){
    Serial.println("Ready to decode IR!");
    digitalWrite(blueLedPin, HIGH); 
    delay(200);
    digitalWrite(blueLedPin, LOW); 
    delay(200);
   }

  uint16_t highpulse, lowpulse; // Temporary storage timing
  highpulse = lowpulse = 0; // Start out with no pulse length
  
    while (IRpin_PIN & (1 << IRpin)) {
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       // printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       // printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
  
 }
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived:");
  for (uint8_t i = 0; i < currentpulse; i++) {
  
    if (i != 0){
    Serial.print("delayMicroseconds(");
    Serial.print(pulses[i][0] * RESOLUTION);
    Serial.println(");");
    }
    Serial.print("pulseIR(");
    Serial.print(pulses[i][1] * RESOLUTION);
    Serial.println(");");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
*/ 
}

// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {

  for (uint8_t i = 0; i < sendpulse; i++) {
  
    if (i != 0){
    delayMicroseconds(pulses[i][0] * RESOLUTION);
    }
    
    pulseIR(pulses[i][1] * RESOLUTION);
  }
}

void power_on(){

    uint8_t answer=0;
    
    // checks if the module is started
    answer = sendATcommand("AT", "OK", 2000);
    if (answer == 0)
    {
        // power on pulse
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);
    
        // waits for an answer from the module
        while(answer == 0){     // Send AT every two seconds and wait for the answer
            answer = sendATcommand("AT", "OK", 2000);    
        }
    }
    
}

int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '\0', 100);    // Initialice the string
    
    delay(100);
    
    while( Serial.available() > 0) Serial.read();    // Clean the input buffer
    
    if (ATcommand[0] != '\0')
    {
        Serial.println(ATcommand);    // Send the AT command 
    }


    x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(Serial.available() != 0){    /* if there are data in the UART input buffer, 
                                           reads it and checks for the asnwer */
            response[x] = Serial.read();
            x++;
            if (strstr(response, expected_answer) != NULL)    
            // check if the desired answer (OK) is in the response of the module
            {
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));    
    // Waits for the asnwer with time out

    return answer;
}

The new 3G shield for ArduinoUNO/Raspberry enables the connectivity to high speed WCDMA and HSPA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new "Internet of Things" era.

The code example and the connection picture shown below are used to re-send a IR code using GPRS module. Data send through TCP connection activate the "send" function.

/*
 *  IR Remote for Arduino UNO and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int buttonState1 = 0;  

int8_t answer;
uint8_t x;
unsigned long previous;
int onModulePin= 8;

char aux_str[50];

char server[ ]="2.139.174.70";
char port[ ]="55556";
char TCP_message[200];
char TCP_order[ ]="Test";

void setup()   {                
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);
  // Initialize the IR digital pin as an output
  pinMode(IRledPin, OUTPUT);      
  // Set uart baudrate
  Serial.begin(115200);
  pinMode(onModulePin, OUTPUT);
  
  power_on();
  delay(3000);
  // sets the PIN code
  sendATcommand("AT+CPIN=****", "OK", 2000);
  delay(3000);
  while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || 
          sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
  // sets APN, user name and password
  sendATcommand("AT+CGSOCKCONT=1,\"IP\",\"movistar.es\"", "OK", 2000);
  sendATcommand("AT+CSOCKAUTH=1,1,\"movistar\",\"movistar\"", "OK", 2000);
}
 
void loop()   {
  
  sprintf(aux_str, "AT+NETOPEN=\"TCP\",%s", port);
  answer = sendATcommand(aux_str, "Network opened", 20000);
  
  if (answer == 1)
    {
        Serial.println("Network openned");
        sprintf(aux_str, "AT+TCPCONNECT=\"%s\",%s", server, port);
        answer = sendATcommand(aux_str, "Connect ok", 20000);
        
        if (answer == 1)
        {
            Serial.println("Socket openned. Waiting for data...");
            
            x = 0;
            answer = 0;
            previous = millis();        
            // this loop waits for data
            do{
                if(Serial.available() != 0){    /* if there are data in the UART input buffer,
                                                   reads it and checks for +IPD */
                    TCP_message[x] = Serial.read();
                    x++;
                    if (strstr(TCP_message, TCP_order) != NULL)    
                    // check if +IPD is in the response of the module
                    {
                        answer = 1;
                    }
                }
            }while((answer == 0) && ((millis() - previous) < 60000));    
            // Waits for the asnwer with time out
            
            if (answer == 1)
            {
                Serial.println("Order detected");   
                Serial.println("Sending IR signal");
                digitalWrite(orangeLedPin, HIGH); 
                delay(200);
                digitalWrite(orangeLedPin, LOW); 
                delay(200);
    
                SendIRCode();
                //delay(15);  // wait 15 milliseconds before sending it again
                //SendIRCode();  // repeat IR code if it is neccesary
 
                delay(5000);  // wait 5 seconds to resend the code            
            }
            else
            {
                Serial.println("Order not detected");
            }
        }
        else
        {
            Serial.println("Error openning the socket");    
        }
        sendATcommand("AT+NETCLOSE", "OK", 20000);
    }
    else
    {
        Serial.println("Error openning the nertwork");    
    }
  
}
 
// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {

/**************************
 * COPY YOUR IR CODE HERE *
 * ************************/

}

void power_on(){

    uint8_t answer=0;
    
    // checks if the module is started
    answer = sendATcommand("AT", "OK", 2000);
    if (answer == 0)
    {
        // power on pulse
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);
    
        // waits for an answer from the module
        while(answer == 0){     // Send AT every two seconds and wait for the answer
            answer = sendATcommand("AT", "OK", 2000);    
        }
    }
    
}


int8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '\0', 100);    // Initialize the string
    
    delay(100);
    
    while( Serial.available() > 0) Serial.read();    // Clean the input buffer
    
    Serial.println(ATcommand);    // Send the AT command 


    x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(Serial.available() != 0){    /* if there are data in the UART input buffer,
                                           reads it and checks for the asnwer */
            response[x] = Serial.read();
            x++;
            if (strstr(response, expected_answer1) != NULL)    
            // check if the desired answer is in the response of the module
            {
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));    
    // Waits for the asnwer with time out

    return answer;
}

Refer to GPRS tutorials (Arduino) (Raspberry) for more information.

Refer to 3G tutorials (Arduino) (Raspberry) for more information.

NOTE: You have to connect the 3G/GPRS pin 2 to the Arduino UNO digital pin 8 using one small wire. Arduino UNO use this pin to switch on the 3G/GPRS module.

3.5 Control air conditioning and heating systems through 802.15.4 / ZigBee

The Arduino Xbee shield allows your ArduinoUNO/RasberryPi board to communicate wirelessly using Zigbee.

/*
 *  IR Remote for Arduino UNO and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

#define IRpin_PIN PIND
#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

char val = 0;
int buttonState1 = 0;        
int buttonState2 = 0;

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing
uint8_t sendpulse = 0; // Index for send pulses

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(9600);
}

void loop(void) {
   // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  // Read the state of the "Receive" push-button value
  buttonState2 = digitalRead(buttonPin2);
  
  if (Serial.available()>0) { 
    val = Serial.read() ;
    //Serial.println(val);
  }
 
if ((buttonState1 == HIGH) || (val == 'A')) {    
    Serial.println("Sending IR signal");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    val=0;
    }

 if ((buttonState2==HIGH) || (currentpulse != 0)){
   
   if (buttonState2==HIGH){
    Serial.println("Ready to decode IR!");
    digitalWrite(blueLedPin, HIGH); 
    delay(200);
    digitalWrite(blueLedPin, LOW); 
    delay(200);
   }

  uint16_t highpulse, lowpulse; // Temporary storage timing
  highpulse = lowpulse = 0; // Start out with no pulse length
  
    while (IRpin_PIN & (1 << IRpin)) {
     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);

     // If the pulse is too long, we 'timed out' - either nothing
     // was received or the code is finished, so print what
     // we've grabbed so far, and then reset
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
  
  // same as above
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     delayMicroseconds(RESOLUTION);
     if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       sendpulse=currentpulse;
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
  
 }
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived:");
  for (uint8_t i = 0; i < currentpulse; i++) {
  
    if (i != 0){
    Serial.print("delayMicroseconds(");
    Serial.print(pulses[i][0] * RESOLUTION);
    Serial.println(");");
    }
    Serial.print("pulseIR(");
    Serial.print(pulses[i][1] * RESOLUTION);
    Serial.println(");");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
*/ 
}

// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {

  for (uint8_t i = 0; i < sendpulse; i++) {
  
    if (i != 0){
    delayMicroseconds(pulses[i][0] * RESOLUTION);
    }
    
    pulseIR(pulses[i][1] * RESOLUTION);
  }
}

Refer to XBee tutorials (Arduino) (Raspberry) for more information.

3.6 Control air conditioning and heating systems through Bluetooth

Bluetooth Modules for ArduinoUNO/Raspberry are able to be plugged into the XBee Shield and get a serial communication between the computer and an ArduinoUNO/RasberryPi board through Bluetooth protocol.

Bluetooth module PRO for Arduino UNO supports Serial Port Profile (SPP) to exchange data with other devices. This profile allows to create connections to another device using the same profile (p2p connection). It sends data to the specified device. This device is the one which the connection has been created to.

We can send hand-copied IR code putting it in the section indicated in the program, using a Bluetooth module. The command used to carry out a device discovery is “INQUIRY {timeout}”. Timeout can be a number between 1 and 48 and it will determine time spent searching for devices. The module will answer with a list of discovered devices and if Arduino UNO detects our phone, send the IR command.

The Arduino UNO code used in this program is presented next:

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!

#define IRpin_PIN PIND
#define IRpin 2

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000

// Timing resolution 
#define RESOLUTION 20

int IRledPin =  3;      // IR emitter LED connected to digital pin 3
int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int8_t answer;
int BTstate = 0;
int buttonState1 = 0;        
int buttonState2 = 0;

// Store up to 100 pulse pairs 
uint16_t pulses[100][2]; // Pair is high and low pulse
uint8_t currentpulse = 0; // Index for pulses we're storing
uint8_t sendpulse = 0; // Index for send pulses

void setup(void) {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(38400);
}

void loop(void) {
  
  // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  delay(100);
  answer = sendATcommand("inquiry 5", "5a020c", 1000);
  answer = sendATcommand("inquiry 5 ", "5a020c", 5000); //Check bluetooth devices every 20 second
 
  //Serial.println(answer);
  
if ((buttonState1 == HIGH) || (answer == 1)) {    
    Serial.println("Sending IR signal");
    digitalWrite(orangeLedPin, HIGH); 
    delay(200);
    digitalWrite(orangeLedPin, LOW); 
    delay(200);
    
    SendIRCode();
    //delay(15);  // wait 15 milliseconds before sending it again
    //SendIRCode();  // repeat IR code if it is neccesary
 
    delay(5000);  // wait 5 seconds to resend the code
    }
}

void printpulses(void) {
  Serial.println("\n\r\n\rReceived:");
  for (uint8_t i = 0; i < currentpulse; i++) {
  
    if (i != 0){
    Serial.print("delayMicroseconds(");
    Serial.print(pulses[i][0] * RESOLUTION);
    Serial.println(");");
    }
    Serial.print("pulseIR(");
    Serial.print(pulses[i][1] * RESOLUTION);
    Serial.println(");");
  }
  delay(1000);
  digitalWrite(orangeLedPin, HIGH); 
  delay(200);
  digitalWrite(orangeLedPin, LOW); 
  delay(200);
  
/*  // Print it in a 'array' format
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
*/ 
}

// This procedure sends a 38KHz pulse to the IRledPin for a certain # of microseconds.
void pulseIR(long microsecs) {
 
  cli();  // Turn off any background interrupts
 
  while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
   digitalWrite(IRledPin, LOW);   // 3 microseconds
   delayMicroseconds(10);         /* hang out for 10 microseconds, 
                                     you can also change this to 9 if its not working */
 
   // So 26 microseconds altogether
   microsecs -= 26;
  }
 
  sei();  // Turn them back on
}
 
void SendIRCode() {
  
/**************************
 * COPY YOUR IR CODE HERE *
 * ************************/

}

int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '\0', 100);    // Initialice the string
    
    delay(100);
    
    while( Serial.available() > 0) Serial.read();    // Clean the input buffer
    
    if (ATcommand[0] != '\0')
    {
        Serial.println(ATcommand);    // Send the AT command 
    }


    x = 0;
    previous = millis();

    // this loop waits for the answer
    do{
        if(Serial.available() != 0){    
        // if there are data in the UART input buffer, reads it and checks for the asnwer
            response[x] = Serial.read();
            x++;
            if (strstr(response, expected_answer) != NULL)    /* check if the desired answer (OK)
                                                               is in the response of the module */
            {
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout)); 
    // Waits for the asnwer with time out
    Serial.println(response);
    return answer;
}

Refer to Bluetooth tutorials (Arduino) (Raspberry) for more information.

4. More IR applications

There are many others different IR remote controls. There are the typical TV and Stereo remotes.

All of these may have different encoding methods and number of physical buttons, and different codes received when a button is pressed.

IR Remote shield lets a great number of possible applications.

4.1 Nikon cameras control (intervalometer)

An intervalometer is a device that sends out a signal at regular intervals. When hooked up to a camera, they can be used to take time lapse images, bracket exposure lengths and precisely time long exposure images. Luckily the cameras, Nikon especially, tend to have a IR trigger.

IR Remote shield is your solution if you was searching a way to automatically trigger your camera , and make time lapse photography.

We can use some dedicated library or use the copy method on the activation code for the camera.

NOTE: The library described on this page was originally written for an extremely old version of the Arduino software. This version works with Arduino 18: Nikon Remote library. Download and unzip in your libraries directory to use.

4.2 IR Remote control library

There is a library for arduino with many features that will allow us to work with a lot of infrared devices. This IR remote library lets you both send and receive IR remote codes in multiple protocols. It supports NEC, Sony SIRC, Philips RC5, Philips RC6, and raw protocols. If you want additional protocols, they are straightforward to add. The library can even be used to record codes from your remote and re-transmit them, as a minimal universal remote.

Download IR Remote library

If you download the library and then unzip it to your Arduino/Libaries directory (older versions, I think its Arduino/hardware/libaries). The library assumes that your phototransistor/ IR receiver is on digital pin 11 and your IR diode is on digital pin 3. Typically you want a IR receiver with a 38Khz range. We should change the IR receiver sensor to the pin 3 in the code.

This infrared remote library consists of two parts: IRsend transmits IR remote packets, while IRrecv receives and decodes an IR message. IRsend uses an infrared LED connected to output pin 3. To send a message, call the send method for the desired protocol with the data to send and the number of bits to send.

The library supports multiple IR protocols, each with its own slight complications:

  • Sony codes can be recorded and played back directly. The button must be held down long enough to transmit a couple times, as Sony devices typically require more than one transmission.
  • The common NEC protocol is complicated by its "repeat code". If you hold down a button, the remote transmits the code once followed by multiple transmissions of special repeat code.
  • The RC5 and RC6 protocols handle repeated transmissions differently. They use two separate codes for each function, differing in a "toggle bit".

More info: IR Remote library

NEC Infrared Transmission Protocol

In this case we will focus on the NEC protocol used in TV universal remotes.

The NEC IR transmission protocol uses pulse distance encoding of the message bits. Each pulse burst is 562.5µs in length, at a carrier frequency of 38kHz (26.3µs). Logical bits are transmitted as follows:

  • Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
  • Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms

We can copy our television signals or control our project using a universal remote.

5. Other applications

5.1 IR Remote digital I/O

IR Remote shield has several digital inputs and outputs available for use in the program. Its main function is to copy and re-send IR codes but can be configured for other functions.

Loading the following program can check correct operation.

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */

int orangeLedPin =  7;  // Orange LED connected to digital pin 7
int buttonPin1 = 4;     // "Send" push-button connected to digital pin 4
int blueLedPin =  6;    // Blue LED connected to digital pin 6
int buttonPin2 = 5;     // "Receive" push-button connected to digital pin 5

int buttonState1 = 0;        
int buttonState2 = 0; 

void setup() {
  // Initialize the Orange LED pin as an output
  pinMode(orangeLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin1, INPUT);  
  // Initialize the Orange LED pin as an output
  pinMode(blueLedPin, OUTPUT);      
  // Initialize the "Send" push-button pin as an input
  pinMode(buttonPin2, INPUT);
  // Set uart baudrate
  Serial.begin(9600);
}

void loop(){
  // Read the state of the "Send" push-button value
  buttonState1 = digitalRead(buttonPin1);
  Serial.println(buttonState1);
  // Read the state of the "Send" push-button value
  buttonState2 = digitalRead(buttonPin2);
  Serial.println(buttonState2);

  if (buttonState1 == HIGH) {     
    // Turn LED on:    
    digitalWrite(orangeLedPin, HIGH);  
  } 
  else {
    // Turn LED off:
    digitalWrite(orangeLedPin, LOW); 
  }

  if (buttonState2 == HIGH) {     
    // Turn LED on:    
    digitalWrite(blueLedPin, HIGH);  
  } 
  else {
    // Turn LED off:
    digitalWrite(blueLedPin, LOW); 
  }
}

5.2 Control your projects with infrared technology

We can use small TV remote control to control our projects through infrared signals. For example:

Infrared Keychain Remote Control

IR Remote Control

Control the LED state is a simple example of application. This can then be applied to more difficult projects. This is especially good for remote control of a small robot, using the arrow buttons.

/*
 *  IR Remote for Arduino and Raspberry Pi
 *
 *  Copyright (C) 2013 Libelium Comunicaciones Distribuidas S.L.
 *  http://www.libelium.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *
 *  Version 0.1
 *  Author: Luis Martin
 */
 
#include <IRremote.h>

int RECV_PIN = 2;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  // Set uart baudrate
  Serial.begin(9600);
  irrecv.enableIRIn();  // Start the receiver
  pinMode(13,OUTPUT);
}
void loop() {
  if (irrecv.decode(&results)) {
   int readValue = results.value;
   Serial.println(readValue, HEX);
   // If remote control button pressed, turn on the led.
   if(readValue == 0x80C){ 
     digitalWrite(13,HIGH); 
   }
   // If remote control button pressed, turn off the led.
   if(readValue == 0xC){
     digitalWrite(13,LOW); 
   }  
   irrecv.resume(); // Resume receiver
  }
}

NOTE: Most handheld remotes are shipped with a small clear plastic piece in the battery compartment that must be removed to activate it. You can usually just pull it out.

5.3 Add IR Remote control feature

What happens if we have a device that does not have infrared technology? A IR Socket is suitable for any electronic device you want to control by infrared signals.

How to use

Plug the IR socket into a main external or wall socket, and put the IR receiver in the suitable location that can receive the signal from remote control. Point the remote control at IR receiver and send any code that you want to use it to control IR socket on the remote control once then the IR socket LED will flash quickly and OFF.That means code is set. Re-send the selected code on the remote control once,the IR socket works.Push once the power is ON and push again the power is OFF.

Clearing codes

In off situation, press ON/OFF switch on the socket continuously for 3 seconds ,when the LED flashes from quickly to once per second,that means clearing code is successful.You can set the other code again.

Typical features
  • Voltage: 240Vac~ 50Hz
  • Rating: Max. 3000W
  • Frequency: 433.92MHz
  • ON/OFF indication: LED
  • Remote range: >20m
  • Code setting: Self-teach in

6. Links and documentation source

7. Get the IR Remote Kits