2018/02/25

Arduino - Switch celling light with TV remote (1/2)

 Preface

It must be happened to you before that in a very cold night watching TV or movie in bed and you were ready for bed. You turned off the TV or DVD player with remote control easily. However, for the celling light, you just had to get out of the bed to turn the light off. What a pain! 

After I searched the Internet, there are many examples out there suit for this purpose, such as IR receiver, relay module, and RGB LED shift hue and most of them have codes that I could utilize on this project.  

Quick Link

Material Needed

  • Arduino mini pro *1 
  • USB upload module *1 
  • Relay module (5V/10A/125V) * 1 
  • IR Receiver LED * 1 (Aixin AX-1838HS 38KHz * 1 / All 38KHz should work) 
  • RGB LED *2 
  • Resister 220 Om * 3
  • Few jump wires
  • Any TV or DVD remote you have at home
  • Breadboard * 1
It's not difficult to find these components on Amazon or eBay.

System Functionality

Assign two buttons on the remote to control the celling light. Remember to assign less frequently used buttons on the remote or you might accidentally activate the particular function on your appliances. :)
  • Button 1: Turn on/off
  • Button 2: Switch LED color hues (static or color shifting)

Schematic

This schematic is made with Fritzing. 
You can download it from its official website: www.fritzing.org


Connections

  • IR Receiver to Arduino pin 2
  • IR Receiver + to VCC
  • IR Receiver - to GND
  • Relay + to VCC
  • Relay - to GND
  • Relay to Arduino pin 8
  • RGB Red to Resistor to Arduino pin 3
  • RGB Green to Resistor to Arduino pin 5
  • RGB Blue to Resistor to Arduino pin 6

Check Remote IR code

You have to find out the remote button IR codes on your remotes and embed them in the source code below for this project to work.


For Example, my Sanyo TV remote has the following codes. As you can see, I have assigned two buttons for each feature to have a fall back plan.

  • Celling Light Switch function
    • Mute:irCode: 1CE318E7,  bits: 32  sanyoLight1
    • Channel minus :irCode: 1CE3D02F,  bits: 32  sanyoLight2
  • LED Switch function
    • Volume minus :irCode: 1CE3F00F,  bits: 32  sanyoLED1
    • CH View: irCode: 1CE352AD,  bits: 32 sanyoLED2

To find out the IR codes for you remote, please refer to my previous IR Repeater Tutorial (Part 2)

Source Code

/*
 * Author: Stonez56
 * IRRemote for bedroom lighting control 
 *   Light buttons: Switch lights through the 
 *            cycle - 3, 5, 2, off with 2 types of remote
 *   LED buttons: Switch display random color a, b, transistion, off
 */

#include <IRremote.h>

// Setting up pins
// Setup pin 8 for relay. 
//    For some reason, Pin 13 will cause relay to switch one time
//    when system powers on
const int relay1Pin = 8; 
const int redPin = 3;                    
const int greenPin = 5;
const int bluePin = 6;
const int irReceiverPin = 2;

// Milisecond to delay when shifting colors
int colorShiftTime[] = {20, 10, 1, 50}; 
int colorShiftTimeCounter = 0;

int myPins[] = {2, 4, 8, 3, 6};
int LEDstatus = 0;       // mode of LED or switch light
                    /*
                     * 0 = LED off
                     * 1 = LED orange
                     * 2 = LED color rotation
                     * 3 = Relay Light swtich
                     */

int relay1Status = 0; // Switch of the relay; either 1 or 0;


IRrecv irrecv(irReceiverPin);            
decode_results results;  // IR decode_results 

unsigned int rgbColour[3]; //RGB LED array

unsigned int preCode = 0x0;  //Previous remote code
unsigned int currentCode = 0x0; //Current remote code

/* Define remote codes  
Remote A (iBit Remote)
 Switch
  - (L/R) irCode: 609E09F6,  bits: 32 bitLigth1
  - Subtitle:irCode: 609E8877,  bits: 32  bitLight2
 LED Switch
  - Sound change irCode: 609E42BD,  bits: 32 bitLED1
  - Favorite channel:irCode: 609E728D,  bits: 32 bitLED2
  LED Color speed 
    - colorShiftTime: irCode: 

*/
 
const unsigned long bitLight1 = 0x609E09F6;
const unsigned long bitLight2 = 0x609E8877;
const unsigned long bitLED1 = 0x609E42BD;
const unsigned long bitLED2 = 0x609E728D; 
const unsigned long bitLEDspeed = 0x609EAA55;
/*
Remote B (Sanyo Remote)
 Switch
  - Mute:irCode: 1CE318E7,  bits: 32  sanyoLight1
  - Channel minus :irCode: 1CE3D02F,  bits: 32  sanyoLight2
 LED Switch
  - Volume minus :irCode: 1CE3F00F,  bits: 32  sanyoLED1
  - CH View: irCode: 1CE352AD,  bits: 32 sanyoLED2
  LED Color speed
    - colorShiftTime: irCode: 

*/
const unsigned long sanyoLight1 = 0x1CE318E7;
const unsigned long sanyoLight2 = 0x1CE3F00F;
const unsigned long sanyoLED1 = 0x1CE352AD;
const unsigned long sanyoLED2 = 0x1CE3D02F;
const unsigned long sanyoLEDspeed = 0x1CE350AF;

void setup()
{
  
  //////Serial.begin(9600);   
  irrecv.enableIRIn(); // enable IR pin
  pinMode(relay1Pin, OUTPUT);
  // Start off with the LED off.
  ledOff();
}

// Turn off LED
void ledOff(){
  rgbColour[0] = 255;
  rgbColour[1] = 255;
  rgbColour[2] = 255;  
  setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);

  preCode = currentCode;
  while(preCode == currentCode){
        currentCode = checkRemoteCode();
        // Check the code on Serial port
        Serial.print(rgbColour[0]); Serial.print(" | ");
        Serial.print(rgbColour[1]);  Serial.print(" | ");
        Serial.println(rgbColour[2]);
  }
}

/*
* Turn on LED to Orange color
*/
void ledOrange(){
  //LED color orange??
  rgbColour[0] = 65391;
  rgbColour[1] = 400;
  rgbColour[2] = 255;  
  setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);

  preCode = currentCode;
  while(preCode == currentCode){
        currentCode = checkRemoteCode();
  }

}


/*
 * Rotating RGB LED color
 */
void colorRotation(){
  // Start off with red.
  rgbColour[0] = 0;
  rgbColour[1] = 255;
  rgbColour[2] = 255;  

  preCode = currentCode;
 
  // Choose the colours to increment and decrement.
  for (int decColour = 0; decColour < 3; decColour += 1) {
    int incColour = decColour == 2 ? 0 : decColour + 1;
 
    // cross-fade the two colours.
    for(int i = 0; i < 255; i += 1) {
      rgbColour[decColour] -= 1;
      rgbColour[incColour] += 1;   

      setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
      delay(colorShiftTime[colorShiftTimeCounter]);
      currentCode = checkRemoteCode();

/*
      Serial.print(" R:");Serial.print(rgbColour[0]);
      Serial.print(" G:");Serial.print(rgbColour[1]);
      Serial.print(" B: ");Serial.println(rgbColour[2]); 
      */     
      //if accepted new remote codes,
      //     exit this function and back to the main loop;
      if(preCode != currentCode){
        return;
      }
    }
  }
} // End of LED color rotation


/* This turn on/off relay switch
 *
 */
void switchRelay(){
  relay1Status = 1 - relay1Status;   
   if(relay1Status == 0){
    digitalWrite(relay1Pin, HIGH);
    delay(500);
   }else{ 
    digitalWrite(relay1Pin, LOW);
    delay(500);
   }
}

/* Check remote code and return a mode to be changed
 *
 */
int checkRemoteCode(){
  if (irrecv.decode(&results)) { // Received IR code and decoded ok!
    // Print to Serial port for debug purposes
    Serial.print("Color shift time: ");
    Serial.print(colorShiftTime[colorShiftTimeCounter]);
    Serial.print("  irCode: ");           
    Serial.print(results.value, HEX);    // IR decode
    Serial.print(",  bits: ");          
    Serial.println(results.bits);        // IR codes
    
    irrecv.resume();                    // Continue to receive next IR code 
    if(results.bits == 32){ //only 32bit code will be evaluated
      switch(results.value){
        /*All these buttons switch lights */ 
        case bitLight1:
        case bitLight2:
        case sanyoLight1:
        case sanyoLight2:  
        case 0x992A2843: //Benq Remote Green button for test
             LEDstatus = 3; //switch relay;

          break;
        case bitLED1:
        case bitLED2:
        case sanyoLED1:
        case sanyoLED2:
              //Check LEDstatus and switch to next mode
              LEDstatus += 1;
              if(LEDstatus >= 3){ 
                  LEDstatus = 0; //LEDstatus only has 0,1,2 if == 3, reset it to 0;
              }
          break; 
        case bitLEDspeed:
        case sanyoLEDspeed:
              colorShiftTimeCounter++;
              if(colorShiftTimeCounter==4){ 
                  colorShiftTimeCounter=1; //only 4 elements, from 0~3
                }
              colorShiftTime[colorShiftTimeCounter];
          break;
        default:
          break;        
      } //switch
    } // check 32bits
  } //end of get a remote code

  return LEDstatus;
}

void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
 }

void loop(){
  switch(LEDstatus){
     case 0:
        ledOff();
        break;
     case 1:
        ledOrange();
        break;
     case 2:
        colorRotation();
        break;
     case 3:
        switchRelay();
        LEDstatus = 99;
        break;
     default: // set it up to do nothing, but wait the remote code to activate
         break;
  }
  //constanly check new remote code
  LEDstatus = checkRemoteCode();
  //////Serial.print("LEDstatus: ");Serial.println(LEDstatus);
} // end of loop

Here is the prototype in the photo below.



In next tutorial, I will show you the 2nd phase to put everything together and install the whole system in the celling light.  See you soon!


2 comments:

  1. Hi Stonez,

    Great post I must say :)

    ReplyDelete
    Replies
    1. Thanks, Frank. I hope it's useful for your own projects.

      Delete