Swap With Dell 9300

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Thursday, October 13, 2011

InduinoX: IR Emitter

Posted on 3:54 AM by Unknown
In my last post, I promised an arduino board based remote control. This is the post you have been waiting for. Now the InduinoX comes with an IR emitter too (don't you just love this board?)! The IR emitter is connected to analog pin 0. So you can start transmitting the remote signal you previously discovered.

Before we go too far, make sure you have read the primer on IR remotes. My TV remote sends out the signal in the sony protocol as observed from my gnuplots and oscilloscope. You know now that according to Sony protocol, a 1 is represented by 1200ms of high and 600ms of low, while a 0 is represented by 600ms of high and 600ms of low. Also the signal is to be prefixed with a header, which is 2400ms high signal followed by a 600ms of low. So lets write some code to send the header, 0 and 1 first.

#define HEADER_ON    2400
#define HEADER_OFF   600
#define BIT_1_ON     1200
#define BIT_1_OFF    600
#define BIT_0_ON     600
#define BIT_0_OFF    600

void sendHeader() {
  sendHigh(HEADER_ON);
  sendLow(HEADER_OFF);
}

void sendBit1() {
  sendHigh(BIT_1_ON);
  sendLow(BIT_1_OFF);
}

void sendBit0() {
  sendHigh(BIT_0_ON);
  sendLow(BIT_0_OFF);
}


So far, so good. Now you have to remember that the signal should be modulated with a 40 kHz signal. Which means a high should really be quick successions of high and low at 40 kHz. The time period of 40 kHz signal is 25 microseconds (1/40,000th of a second). So have to wiggle the IR LED low to high and from high to low every 12.5 ms. Which is why our sendHigh() and sendLow() look like this (note that on the InduinoX, the IR emitter is connected to analog pin 0):

#define IR_PIN A0

int cmdTime = 0;

void sendHigh(int time) {
  cmdTime += time;
  while (time > 0) {
    digitalWrite(IR_PIN, HIGH);  // sets the pin high
    delayMicroseconds(10);       // sleep for 13 us (3us delay for pin high)
    digitalWrite(IR_PIN, LOW);   // sets the pin low
    delayMicroseconds(9);        // sleep for 12 us (3 us delay for pin low)
    time -= 25;
  }
}

void sendLow(int time) {
  cmdTime += time;
  while (time > 0) {
    digitalWrite(IR_PIN, LOW);   // sets the pin low
    delayMicroseconds(10);       // sleep for 13 us (3us delay for pin low)
    digitalWrite(IR_PIN, LOW);   // sets the pin low
    delayMicroseconds(9);        // sleep for 12 us (3 us delay for pin low)
    time -= 25;
  }
}


Finally it is time to send the signal.

#define BITS         12

void sendCmdOnce(int cmd, int last) {
  cmdTime = 0;
  cli();  // Disable interrupts so our timings can be accurate
  sendHeader();
  for (int i = BITS - 1; i >= 0; i--) {
    if ((cmd & (1 << i)) == 0) {
      sendBit0();
    } else {
      sendBit1();
    }
  }
  sei();  // Enable interrupts
}


We are not done yet! Remember that sony protocol requires you to send the same signal at least 3 times every 45ms. Here is the code for that:

void sendCmd(int cmd) {
  for (int i = 0; i < 3; i++) {
    sendCmdOnce(cmd, i);
    delay(45 - cmdTime / 1000);
  }
}


Simple :).Now lets put all the code in proper order along with the setup() and loop() functions.

#define BITS         12
#define HEADER_ON    2400
#define HEADER_OFF   600
#define BIT_1_ON     1200
#define BIT_1_OFF    600
#define BIT_0_ON     600
#define BIT_0_OFF    600

#define IR_PIN A0

int cmdTime = 0;

void setup() {
  pinMode(IR_PIN, OUTPUT);
}

void loop() {
  sendCmd(0x490);
  delay(1000);
}

void sendCmd(int cmd) {
  for (int i = 0; i < 3; i++) {
    sendCmdOnce(cmd, i);
    delay(45 - cmdTime / 1000);
  }
}

void sendCmdOnce(int cmd, int last) {
  cmdTime = 0;
  cli();  // Disable interrupts so our timings can be accurate
  sendHeader();
  for (int i = BITS - 1; i >= 0; i--) {
    if ((cmd & (1 << i)) == 0) {
      sendBit0();
    } else {
      sendBit1();
    }
  }
  sei();  // Enable interrupts
}

void sendHeader() {
  sendHigh(HEADER_ON);
  sendLow(HEADER_OFF);
}

void sendBit1() {
  sendHigh(BIT_1_ON);
  sendLow(BIT_1_OFF);
}

void sendBit0() {
  sendHigh(BIT_0_ON);
  sendLow(BIT_0_OFF);
}

void sendHigh(int time) {
  cmdTime += time;
  while (time > 0) {
    digitalWrite(IR_PIN, HIGH);  // sets the pin high
    delayMicroseconds(10);       // sleep for 13 us (3us delay for pin high)
    digitalWrite(IR_PIN, LOW);   // sets the pin low
    delayMicroseconds(9);        // sleep for 12 us (3 us delay for pin low)
    time -= 25;
  }
}

void sendLow(int time) {
  cmdTime += time;
  while (time > 0) {
    digitalWrite(IR_PIN, LOW);   // sets the pin low
    delayMicroseconds(10);       // sleep for 13 us (3us delay for pin low)
    digitalWrite(IR_PIN, LOW);   // sets the pin low
    delayMicroseconds(9);        // sleep for 12 us (3 us delay for pin low)
    time -= 25;
  }
}


Please forgive my bad programming practices (global variables, confusing naming styles for my defines etc), I did it over a lazy Saturday ;). The setup() prepares the IR emitter to output. The loop() keeps sending the same volume up signal (0x490) over and over every second. So if you point the IR emitter to your TV you will see the volume go up every second. I was very excited when all this just worked! Just to make sure, I looked at the IR emitter PIN voltage on my oscilloscope and everything looks like it is in order.

Singal repeating every 45ms

Up close of 0x490 signal (inverted)

Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest
Posted in arduino, induinox, ir emitter, ir remote | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Installing Boxee on Gentoo: my experience
    You have probably heard of Boxee and Gentoo (come on). I wanted to give Boxee a try, because of all the movies and tv shows that I can watc...
  • This is my first stab at blogging!
    Heard the good news about the latest Intel Processor? I have been waiting for this processor for a long time. The conroe (for desktops) and ...
  • How I hacked mplayer to work on Motorola ROKR - Part 1
    Ever since I posted the cTunes video on youtube ( http://youtube.com/watch?v=coV06ChYWJo ), I have been getting a few requests for the app t...
  • InduinoX and wireless relays: Part I
    It has been a while since I received my wireless relay and I finally got some time this weekend to put them to good use. The connections we...
  • VirtualBox 1.6 is out
    The most usable (for me anyway) VirtualBox release for mac is out. I just downloaded 1.6.0 from VirtualBox.org . I was finally able to load ...
  • Looking to buy 8800GT
    How hard is it to buy a graphics card for your desktop? Easy right? Hardly! In my previous post I casually mentioned that my Dell E1705'...
  • Building a linux gaming PC: Update 1
    Today I received my 1GB memory, the upgrade I require to transform my media center desktop PC into a moderately powerful gaming PC. I am sti...
  • InduinoX: Blinking LEDs
    Having received my arduino and basic components kit earlier last week , I sat out to write my first arduino program. A hello world of sorts...
  • Scopes and electronics
    An oscilloscope is very important for any electronic enthusiast. Recently I have been trying to send IR remote codes from an arduino board ...
  • My HTPC
    I have my eye on a new HTPC, but what does my current one look like? Here it is. The desktop PC that acts as my apache, mysql, samba, vnc, n...

Categories

  • 555 timer
  • arduino
  • delay circuit
  • electronics
  • gentoo
  • home automation
  • induinox
  • ir emitter
  • ir receiver
  • ir remote
  • kubuntu
  • lcd
  • ldr
  • leds
  • lucid lynx
  • oscilloscope
  • picoscope
  • probots
  • receiver
  • relay
  • relays
  • scope
  • sensors
  • simple labs
  • sony remote protocol
  • transmitter
  • virtualbox
  • virtualization
  • wireless relay

Blog Archive

  • ▼  2011 (12)
    • ►  December (1)
    • ►  November (1)
    • ▼  October (6)
      • InduinoX and wireless relays: Part I
      • Scopes and electronics
      • InduinoX: IR Emitter
      • InduinoX: IR receiver
      • IR remotes
      • InduinoX: Interfacing with the LDR
    • ►  September (4)
  • ►  2010 (5)
    • ►  May (1)
    • ►  March (1)
    • ►  January (3)
  • ►  2009 (10)
    • ►  December (5)
    • ►  November (3)
    • ►  May (1)
    • ►  April (1)
  • ►  2008 (29)
    • ►  August (1)
    • ►  June (1)
    • ►  May (4)
    • ►  April (1)
    • ►  March (1)
    • ►  February (10)
    • ►  January (11)
  • ►  2007 (7)
    • ►  May (5)
    • ►  April (1)
    • ►  March (1)
  • ►  2006 (8)
    • ►  November (1)
    • ►  October (3)
    • ►  September (2)
    • ►  August (2)
Powered by Blogger.

About Me

Unknown
View my complete profile