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  
 }