Go Down

Topic: Adding IR control to Computer Monitor (Read 5 times) previous topic - next topic

ryantollefson

Here you can see how the IR sensor looks from the outside. 

Next you can see how the board looks with everything wired up inside the monitor.

If you look closely at the closeup of the buttons, you can see the IR receiver on the right side of the monitor (sorry for the not great picture).

Finally, you can see the whole thing done, and mounted to the wall.

ryantollefson

Now for the code controlling the whole thing:

Code: [Select]
/**
* Add a remote control to an ASUS Monitor
* Uses Power & Volume buttons from a standard Sony TV remote
*/

#include <EEPROM.h>

//CONSTANTS
#define btnPower   149
#define btnMute    148
#define btnDown    147
#define btnUp      146
#define rate       4
#define start_bit  2000                //Start bit threshold (Microseconds)
#define bin_1      1000                //Binary 1 threshold (Microseconds)
#define bin_0      400                //Binary 0 threshold (Microseconds)
#define ir_pin     2                //Sensor pin 1 wired through a 220 ohm resistor
#define led_pin    13                //"Ready to Recieve" flag, not needed but nice
#define debug      0                 //Serial connection must be started to debug


//VARIABLES
long timer = -5000;
int i      = 0;                    //general purpose counter
int wait = 20;


void setup() {
  pinMode(6, OUTPUT); //Push button when Volume-down detected
  pinMode(7, OUTPUT); //Push button when Volume-up detected
  pinMode(8, OUTPUT); //Push when Power detected
  pinMode(led_pin, OUTPUT);          //This shows when we're ready to recieve
  pinMode(ir_pin, INPUT);
  digitalWrite(led_pin, LOW);          //not ready yet
  timer = -5000; // used for volume up command
}

void loop() {
  //Fetch the key 
  int key = getIRKey();
 
   switch (key) {     
    case btnPower:
      digitalWrite(8, HIGH);
      delay (500); //Debounce switch
      digitalWrite(8, LOW);
      timer = -5000;
      break;
     
    case btnDown:
      digitalWrite(6, HIGH);
      delay(wait);
      digitalWrite(6, LOW);
      timer = millis(); //reset timer to now
      break;   
     
    case btnUp:
      if ((millis() - timer) >= 3500){ // activate volume instead of default brightness setting for vol + button.
        digitalWrite(6, HIGH);
        delay(wait);
        digitalWrite(6, LOW);
        delay(wait);
      }
      digitalWrite(7, HIGH);
      delay(wait);
      digitalWrite(7, LOW);
      timer = millis(); //reset timer to now
      break;
   
    default:
      digitalWrite(8, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
  }
}


int getIRKey() {
  int data[12];
  digitalWrite(led_pin, HIGH);         //Ok, i'm ready to recieve 
 
  while(pulseIn(ir_pin, LOW) < 2200) {
    //Wait for a start bit
    return -1; //clear out old codes
  }
 
  for(i=0;i<11;i++){
    data[i] = pulseIn(ir_pin, LOW);   //Start measuring bits, I only want low pulses
  }
 
  digitalWrite(led_pin, LOW);

  if(debug == 1) {
    //Serial.println("-----");
  }
 
  for(int i=0;i<11;i++) {          //Parse them
   
    if (debug == 1) {
      //Serial.println(data[i]);
    }
   
    if(data[i] > bin_1) {          //is it a 1?
      data[i] = 1;
    } else {
      if(data[i] > bin_0) {        //is it a 0?
        data[i] = 0;
      } else {
        data[i] = 2;              //Flag the data as invalid; I don't know what it is!
      }
    }
   
  }

  for(i=0;i<11;i++) {              //Pre-check data for errors
    if(data[i] > 1) {
      return -1;                //Return -1 on invalid data
    }
  }

  int result = 0;
  int seed = 1;
  for(int i=0;i<11;i++) {      //Convert bits to integer
    if(data[i] == 1) {
      result += seed;
    }
    seed = seed * 2;
  }
  return result;             //Return key number
}


One tricky part for this code is that the monitor uses the same buttons for both volume and brightness.  If you press the Vol (+) button first, it will do brightness, not volume (goofy design if you ask me).  What I did to counter this, is if more than a few seconds have gone by, and you press the Vol (+) button on the remote, the Arduino will send one Vol (-) command before sending the Vol (+) commands - this is enough to get the monitor into volume mode first before increasing volume.

This code was modified from the link referenced in the first post.  Thanks to all of the resources listed on top - they were all very helpful.

The monitor now works just as if it were a Sony TV (well at least for Power, Volume Up, and Volume Down).  The wife is very happy.  :)

dwilson43

This makes me want to turn my old monitor into a TV

Go Up