Adding IR control to Computer Monitor

Now for the code controlling the whole thing:

/**
 * 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. :slight_smile: