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

  • InduinoX: Interfacing with LCD
    After my quick Hello World app , I became a bit more adventurous and decided to interface with the LCD screen that was part of the basic ki...
  • 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 ...
  • Dell Recalls Batteries
    Ahh the news could not have come at a better time. I was having problems with the battery that came with my Dell Inspiron 9300. Just 7 days...
  • XBMC / Boxee remote control android app
    I have been writing a few android apps over weekends at home and during 20% time at Google. However I never actually released any of them in...
  • Elisa problems marshalling MediaUri
    The short version If you are having problems with elisa not playing your local media files (see https://code.fluendo.com/elisa/trac/ticket/9...
  • nVidia ION for HTPC
    This is an exciting time for buying HTPC devices. They come in really small sizes, they are efficient and yet can playback 1080p video and b...
  • Purchase experience with Probot
    I have recently posted my purchase experience with Simple Labs . This post is the continuation of that. That same day I ordered these compon...
  • IR remotes
    As part of my  home automation project , I also wanted to control my home entertainment system. The controller can be a web interface or an ...
  • gtkdocize not found
    If you are ever configuring an app and see the message "gtkdocize not found" in Gentoo, then you need to emerge gtk-doc. I had som...
  • Testing AdSense and Getting Things Done
    Working in Google and not having an AdSense account is not cool. So I created an account and added the AdSense page element. Looks good. Alt...

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