InduinoX User Guide - Working with the IR LED

The IR Led is a unique idea we had when designing the InduinoX board. We thought if we can put bot the IR LED and TSOP side by side and make 2 boards face each other, we can build a simple basic IR based 2 way wireless communication system. In this edition, we will see how to generate sony signals on the IR led

The IR led is connected to PIN 14 (analog 0) of the InduinoX.

Understanding Frequency
The Sony SIRC protocol works at 40Khz...most remote controls work at their specific frequencies. TV remotes in India are generally between 32- 40Khz frequecny.

So whats this frequency all about?
40KHz means 40,000 Cycles in 1 second. Each Cycle represents a ON signal followed by a OFF signal. The signals could be of equal duration.

Heres another image of the Sony signals









If you look at the image, you can see the the 1.2ms high of the Logical '1' has further black lines with spaces in between. These correspond to the ON/OFF cycles. The space between these is what is called the frequency. The frequency of occurrence of a ON/OFF cycle is what it means.

So How do we generate it?
Lets do some calculation,
40,000 Cycles in 1 Sec or 1000 millisec or 1000 x 1000 microseconds
so each cycle if for a duration of 25microseconds.

We can produce this frequency if we can make a pin go high for 13 microseconds followed by low for 12 microseconds.

If we can do this for 2.4 milliseconds then we can generate a Startbit, if we can do this for 1.2 milliseconds then we can generate a Logical '1', and for 0.6 milliseconds, we can generate a Logical '0'.

Now that we know that each cycle will take 25 microseconds lets calcualte the number of cycles required for generating the 2.4 milliseconds start bit
2.4 milliseconds / 25microseconds => 2400 microseconds / 25microseconds => 96 cycles
1.2 milliseconds / 25microseconds => 1200 microseconds / 25microseconds => 48 cycles
0.6 milliseconds / 25microseconds => 600 microseconds / 25microseconds => 24 cycles

the delayMicroseconds() function of arduino can help us required delay in microseconds. So lets first create a pulse function.
 void pulseData(int no_of_cycles)  
 {  
  for(int i=0;i<no_of_cycles;i++)      
  {  
   digitalWrite(14,HIGH);  
   delayMicroseconds(13);  
   digitalWrite(14,LOW);  
   delayMicroseconds(12);  
  }  
  digitalWrite(14,LOW);  
  delayMicroseconds(600);// This delay is for the space between the signals 0.6 millseconds  
 }  
Now we have a function that can generate 40Khz signal cycles for a specified number of cycles.

Next we need a function that will convert a decimal value to binary, evaluate each bit and then call signal generation function accordingly.

Heres a function that takes any decimal value (upto 12 bits), converts it to binary and transmits the same.
 void dec_to_bin_transmit(int val)  
 {  
  int cnt = 0;  
  pulseData(96); // Sending the Startbit  
  while(cnt<12) // Execute this 12 times to send 12 bits of data  
  {  
  if(val>0) // Checking if the decimal value is non-zero  
  {  
   if(val%2 == 0) // Binary reminder check, if reminder is 1 then we need to send a logical '1'  
   {  
    pulseData(24);  
   }  
   else// Binary reminder check, if reminder is not 1 then we need to send a logical '0'  
   {  
    pulseData(48);  
   }  
   val = val / 2;  
  }  
  else // when the decimal value becomes zero, start sending zeroes for the remaining bits  
  {  
   pulseData(24);  
  }  
  cnt++;  
  }  
 }  
Note: This function is not optimal ;) there might be data loss. We will leave it to you to figure out how to optimise it.

Here's a simple program where the IR led transmits values from 0 to 1023. It transmits each value thrice.

 void setup()  
 {  
  pinMode(14,OUTPUT);  
 }  
 void loop()  
 {  
  for(int count=0; count<1023; count++)  
  {  
   for( int j=0;j<3;j++)  
   {  
   dec_to_bin_transmit(count);  
   delay(50);  
   }  
   delay(500);  
  }  
 }  
 void dec_to_bin_transmit(int val)  
 {  
  int cnt = 0;  
  pulseData(96); // Sending the Startbit  
  while(cnt<12) // Execute this 12 times to send 12 bits of data  
  {  
  if(val>0) // Checking if the decimal value is non-zero  
  {  
   if(val%2 == 0) // Binary reminder check, if reminder is 1 then we need to send a logical '1'  
   {  
    pulseData(24);  
   }  
   else// Binary reminder check, if reminder is not 1 then we need to send a logical '0'  
   {  
    pulseData(48);  
   }  
   val = val / 2;  
  }  
  else // when the decimal value becomes zero, start sending zeroes for the remaining bits  
  {  
   pulseData(24);  
  }  
  cnt++;  
  }  
 }  
 void pulseData(int no_of_cycles)  
 {  
  for(int i=0;i<no_of_cycles;i++)      
  {  
   digitalWrite(14,HIGH);  
   delayMicroseconds(13);  
   digitalWrite(14,LOW);  
   delayMicroseconds(12);  
  }  
  digitalWrite(14,LOW);  
  delayMicroseconds(600);// This delay is for the space between the signals 0.6 millseconds  
 }  

InduinoX User Guide - Working with TSOP IR Receiver - Part 2

We hope you had success with the first part of this write-up. If you have not read it, we suggest you go through it before reading ahead. InduinoX User Guide - Working with TSOP IR Receiver - Part 1

Now that we've used the library successfully, we will see how to code manually to receive from a Sony Remote. Later in the next part, we will see how to generate Sony Signals. Its advised that you read this and try this out completely before moving onto signal generation

Lets take a look at the sony signal train









Now Here's how we are going to go ahead with decoding
  1. Keep checking the TSOP pin (Pin 15) for a LOW pulse of duration in excess of 2ms, the moment you get such a signal proceed on to step 2
  2. Run a 'for' loop for 12 counts, during each iteration of the loop, get the current pulse duration using the pulseIn function. Check if the duration is greater than 1000ms (means its a '1') else its a '0'
  3. As soon as you detect a '1' or '0' add it to an appropriate binary to decimal conversion logic.


Here's the code, You can plug in the remote function into any of your programs, just remember to declare pin 15 as INPUT.
 void setup()  
 {  
  pinMode(15,INPUT); // TSOP is connected on the 15ht pin  
  Serial.begin(9600);  
 }  
 void loop()  
 {  
  int remote_val = remote();  
  if(remote_val>0)  
  {  
   Serial.println(remote_val);  
   delay(150); // A remote press will normally generate 3 signal trains. This is to avoid reading duplicates  
  }  
 }  
 int remote()  
 {  
  int value = 0;  
  int time = pulseIn(15,LOW);  
  if(time>2000) // Checking if the Start Bit has been received. Start Bit Duration is 2.4ms  
  {  
   for(int counter1=0;counter1<12;counter1++) // A loop to receive the next 12 bits  
   {  
    if(pulseIn(15,LOW)>1000) // checking the duration of each pulse, if it is a '1' then we use it in our binary to decimal conversion, '0's can be ignored.  
    {  
     value = value + (1<< counter1);// binary to decimail conversion. 1<< i is nothing but 2 raised to the power of i  
    }  
   }  
  }  
  return value;  
 }  

InduinoX User Guide - Working with TSOP IR Receiver

The TSOP SM0038 is an IR receiver on the InduinoX. The TSOP will help you to interface your TV remote with the InduinoX and in the Process learn the basics of Wireless Communication. The TSOP is connected to pin digital 15(Analog 1).

The TSOP outputs a constant HIGH signal when idle and as it receives data, it tends to invert the data. i.e when an IR LED is transmitting data onto the TSOP, everytime the IR led goes high, the TSOP will go LOW and vice versa. Remote control signals are often bytes of data that is encoded and transmitted by pulsing(switching ON & OFF the IR LED at a specific frequency) Most TV remote controls work at 32-40 Khz frequency and most receivers can receive this range. 

Heres a link to a nice write up on different remote control protocols. lets first take a look how the Sony Remote Control Protocol Works. We stick to Sony as it is the easiest one to get started with. Read this before proceeding 

Here's a basic outline of how the data is sent. Every time you press a button on a Sony remote control, it sends out a 13Bit data. The first bit is a start bit indicating there are 12 bits of data following it. The next 7 bits are the command bit which will vary depending upon the keys being pressed. The last 5 bits are the address bits which will the same for all buttons but vary for remote controls of different devices.

The black bars in the following image correspond to high signals (called marks) and the white spaces in between correspond to low signals (called spaces). The duration of the 'marks' varies according to the bit being transmitted. It is 2.4ms for the start bit, 1.2ms for HIGH bit and 0.6ms for LOW bit. The duration of the 'spaces' is a constant 0.6ms. Every mark is followed by a space. Any data can be converted to binary format and transmitted in this manner. In fact this is the basic form of all types of serial communication.


Technique to decode this signal train, would be to constantly monitor the TSOP pin[Digital 15] for its normal state and the moment it produces a low signal, measure the duration of the low signal. If the measured duration of the low signal is around 2ms then measure and store the duration for the next 12 bits of the incoming data. After storing the data, evaluate the duration and based on the duration convert the data to decimal / hexadecimal and use it in your application.

The duration of a signal on an input pin of the arduino can be measured using the pulseIn function. Read more about this function here

There is an interesting IR remote library that can help you read different remotes without any difficulty. It can also generate different remote signals. However currently it can generate these signals only on the 3rd pin of the Arduino / InduinoX (PWM pin). Incase you want to use this library to generate remote control signals, we advise that you put the jumpers of the RGB LED OFF and connect a wire between the 3rd pin and the Analog 0 of the InduinoX. The IR LED on the InduinoX is connected to Analog 0(a.k.a digital 14)

You can download the IR remote library and other libraries, sample codes for the InduinoX here -> Click Here to Download InduinoX Sample Codes & Required Libraries[Right Click & use Save As]


How to use Libraries in Arduino - An Overview
To use any library you download, unzip the downloaded file and copy its contents to the libraries folder inside your arduino directory. You can check the library by opening the arduino ide and going to Sketch -> Import Library Option, if your library is in the proper location, it will show up here. Next if there is an example provided with the library (it will be inside a folder called example inside the base folder of the library) it will show up under the libraries name in the File->Examples Menu. You should reopen Arduino for the library to show up.


Once you install the IRremote, You can try the example program, IRrecvDemo. This program will give you a serial output of the HEX code for each value corresponding to each button on a remote. We will be using the decimal value in our next program. To get the decimal value, just do the following modification

replace this line
Serial.println(results.value, HEX);
with
Serial.println(results.value);

Ensure the TSOP jumper is ON!

Here's a video of a simple project - A remote control interface for our Binary Counter.


Here's the source code for the same
 /*   
  This sketch increases a 3 bit number every time '+' button is pressed and decreases the value when '-' button is pressed on the remote.It shows the output on 3 LEDs in Binary Format   
  */  
 #include <IRremote.h>  
 int RECV_PIN = 15;  
 IRrecv irrecv(RECV_PIN);  
 decode_results results;  
 int i = 0;  
 void setup()  
 {  
  pinMode(11,OUTPUT);   // declare LED pins as output pins  
  pinMode(12,OUTPUT);  
  pinMode(13,OUTPUT);  
  pinMode(7,INPUT);// Declare the 7th pin as a input pin. We will use the button on the 7th pin  
  digitalWrite(7,HIGH);  
  irrecv.enableIRIn(); // Start the Remote receiver  
  Serial.begin(9600);  
 }  
 void loop()  
 {  
  if (irrecv.decode(&results)) {  
   Serial.println(results.value);  
   switch(results.value)  // if the '+' button is pressed  
   {  
   case 2320:   
    i=0;   
    break;// 2320 is the value for '0'  
   case 16:   
    i=1;   
    break;// 16 is the value for '1'  
   case 2064:   
    i=2;   
    break;// 2064 is the value for '2'  
   case 1040:   
    i=3;   
    break;// 1040 is the value for '3'  
   case 3088:   
    i=4;   
    break;// 3088 is the value for '4'  
   case 528:   
    i=5;   
    break;// 528 is the value for '5'  
   case 2576:   
    i=6;   
    break;// 2576 is the value for '6'  
   case 1552:   
    i=7;   
    break;// 1552 is the value for '7'  
   case 1168: // this is the value for the increment button  
    if(i<7)        // if counter value is less than 7 or 3 bits  
     i++;        // increment counter value  
    else           
     i=0;  
    break;  
   case 3216: // this is the value for the decrement button  
    if(i>0)        // if counter value is greater than 0 or 3 bits  
     i--;        // decrement counter value  
    else           
     i=7;        // reset counter to 7  
     break;  
   }  
   int a=i%2;      // calculate LSB   
   int b=i/2 %2;     // calculate middle bit  
   int c=i/4 %2;     // calculate MSB   
   digitalWrite(11,c);  // write MSB  
   digitalWrite(12,b);  // write middle bit  
   digitalWrite(13,a);  // write LSB  
   while(digitalRead(7)==0);  // wait till button is released to avoid incrementing the counter again  
   delay(300);         // small delay to avoid debounce  
   irrecv.resume(); // Receive the next value  
  }  
 }  

InduinoX User Guide - Working with RTC DS1307

The DS1307 on the InduinoX is meant to let you explore I2C communication on the Arduino. We shall see how to work with the DS1307 by using a Library[Part 1] and then by using our code based on the Arduino Wire Library [Part 2]

I2C Communication
I2C is short form for 'Inter Integrated Circuit' I2C Communication is Communication Bus standard developed by Phillips for standardising Communication between Integrated Circuits. For Eg. In a circuit, there could be a number of ICs each offering specific functionality[RTC, Temperature Sensor, EEPROM, etc] and they can all communicate on a single I2C Bus and provide combined functionalities. Each device on the I2C Bus would have a unique address by which it can be addressed.

Here's an Interesting Introduction from NXP



I2C on Arduino
The I2C Bus uses 2 lines for Communication - SDA(Serial Data) & SCL (Serial Clock). On the InduinoX / Arduino, these are available on  SDA (Analog Input 4) & SCL (Analog Input 5). The I2C bus can be accessed using the 'Wire' Library of Arduino. First, lets try out a Library


How to use Libraries in Arduino - An Overview

To use any library you download, unzip the downloaded file and copy its contents to the libraries folder inside your arduino directory. You can check the library by opening the arduino ide and going to Sketch -> Import Library Option, if your library is in the proper location, it will show up here. Next if there is an example provided with the library (it will be inside a folder called example inside the base folder of the library) it will show up under the libraries name in the File->Examples Menu.


Using the RTC Library
There are a number of libraries available to work with the DS1307, the one from Ladyada is our library of choice for this example. You can download it from here  => RTC Library

Unzip the downloaded file and copy its contents to the libraries folder inside your arduino directory. Open the Arduino IDE [close and reopen it if you had it open!], Open File->Examples->RTClib->ds1307

Compile & Upload the program to your InduinoX and open the Serial monitor. Set the baud rate of the Serial monitor to '57600' and voila you see the time!

Now Lets Modify the code and Build a simple project - Timer Controlled LED. The LED on pin 13 will  switch ON at a specific time and switch OFF at another specific Time.

Here's a Video the project in action


Here's the code for the project
 /*  
 Switches ON and OFF a LED at a Preset Time of Hour based on RTC  
  */  
 #include <Wire.h>  
 #include "RTClib.h"  
 RTC_DS1307 RTC;  
 #define ON_HOUR 13// Hour of the On Time  
 #define ON_MIN 0// Minute of the On Time  
 #define OFF_HOUR 13// Hour of the Off Time  
 #define OFF_MIN 1// Minute of the Off Time  
 void setup()  
 {  
  Serial.begin(9600);  
  pinMode(13,OUTPUT); // Pin of the LED to be Switched ON / OFF  
  Wire.begin();  
  RTC.begin();  
  RTC.adjust(DateTime("DEC 31 2011","12:59:45")); // Setting the time to a fixed value. If you want to use the system time comment this line and use the option below  
  // following line sets the RTC to the date & time this sketch was compiled  
  // RTC.adjust(DateTime(__DATE__, __TIME__)); //uncomment this line to set time to system time  
 }  
 void loop()  
 {  
  DateTime now = RTC.now();// Getting the current Time and storing it into a DateTime object  
  if(now.hour()==ON_HOUR && now.minute()==ON_MIN)  
   digitalWrite(13,HIGH);  
  if(now.hour()==OFF_HOUR && now.minute()==OFF_MIN)  
   digitalWrite(13,LOW);  
  Serial.print(now.year(), DEC);  
  Serial.print('/');  
  Serial.print(now.month(), DEC);  
  Serial.print('/');  
  Serial.print(now.day(), DEC);  
  Serial.print(' ');  
  Serial.print(now.hour(), DEC);  
  Serial.print(':');  
  Serial.print(now.minute(), DEC);  
  Serial.print(':');  
  Serial.print(now.second(), DEC);  
  Serial.println();  
  delay(1000);  
 }  




InduinoX User Guide - Programming the Arduino Booloader

The InduinoX was designed with FTDI bitbang mode in mind and there are Pinouts from the FTDI for the same. We will here focus only on how to wire the InduinoX to achieve the BitBang Method described at the following link

http://www.geocities.jp/arduino_diecimila/bootloader/index_old_en.html#mega8_328

You can download Serjtag from the above link and use the commands from the same.

Check this video for the wiring

Things to know

Where to find Fuse Settings for arduino?
The fuse settings for different microcontrollers used in different configurations are available in the boards.txt file in your arduino install. You can find this file here
Your Arduino Directory > Hardware > arduino > boards.txt

Where to find the Bootloader for arduino?
Your Arduino Directory > Hardware > arduino >bootloaders
All the bootloaders have their own directories, so choose the One you want.

Keep us posted on how it goes, mail us on info|at|simplelabs|dot|co|dot|in