Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Arduino-IR-Light-Switch
/*
Infrared Light Switch
by kDuin @ arduino.cc forums
Arduino IDE 022
30-01-2012
*/
/*
* IRremote: IRrecvDump - dump details of IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/
#include <IRremote.h>
// INPUTS OUTPUTS
#define WALLBUTTON_PIN 8
#define LED_GREEN 7 /**/
#define LED_RED 6 /**/
#define RELAY_PIN 4
#define IR_RECEIVER_PIN 3
//MODES
#define MODE_STANDBY 0
#define MODE_SWITCH_LIGHT 1
#define MODE_DELAYED_OFF 2
#define MODE_DELAYED_OFF_BY_IR 3
//LED_MODES
#define LED_MODE_RED 1
#define LED_MODE_GREEN 2
#define LED_MODE_RED_BLINK 3
//OTHER
#define DELAY_OFF_TIME 30 /*delay seconds*/
#define BLINK_INTERVAL (unsigned long) 500 /* = ms */
#define BLINK_INTERVAL_FAST (unsigned long) 200 /* = ms */
#define WALLBUTTON_TRESHOLD_DURATION (unsigned long) 1000 /*min. millisec for sleep-timer activate*/
#define WALLBUTTON_DEBOUNCE_TIME (unsigned long) 20 /*millisec*/
int light_state = false;
int current_mode = MODE_STANDBY;
int last_mode = MODE_STANDBY;
int current_led_mode = LED_MODE_RED;
int last_led_mode = LED_MODE_RED;
unsigned long time = millis();
int led_mode = LED_MODE_RED;
/***************** LG REMOTE CODES ***************/
#define KEY_POWER 0x20DF10EF
#define KEY_OK 0x20DF22DD
#define KEY_LEFT 0x20DFE01F
#define KEY_RIGHT 0x20DF609F
#define KEY_UP 0x20DF02FD
#define KEY_DOWN 0x20DF827D
#define KEY_VOL_UP 0x20DF40BF
#define KEY_VOL_DOWN 0x20DFC03F
#define KEY_MUTE 0x20DF906F
#define KEY_PROG_UP 0x20DF00FF
#define KEY_PROG_DOWN 0x20DF807F
#define KEY_MENU 0x20DFC23D
#define KEY_0 0x20DF08F7
#define KEY_1 0x20DF8877
#define KEY_2 0x20DF48B7
#define KEY_3 0x20DFC837
#define KEY_4 0x20DF28D7
#define KEY_5 0x20DFA857
#define KEY_6 0x20DF6897
#define KEY_7 0x20DFE817
#define KEY_8 0x20DF18E7
#define KEY_9 0x20DF9867
long KEY_codes[] = {0x20DF10EF, 0x20DF22DD, 0x20DFE01F, 0x20DF609F, 0x20DF02FD, 0x20DF827D, 0x20DF40BF, 0x20DFC03F, 0x20DF906F, 0x20DF00FF, 0x20DF807F, 0x20DFC23D, 0x20DF08F7, 0x20DF8877, 0x20DF48B7, 0x20DFC837, 0x20DF28D7, 0x20DFA857, 0x20DF6897, 0x20DFE817, 0x20DF18E7, 0x20DF9867, 0xF50D, 0xF525};
String KEY_buttons[] = {"POWER", "OK", "LEFT", "RIGHT", "UP", "DOWN", "VOL_UP", "VOL_DOWN", "MUTE", "PROG_UP", "PROG_DOWN", "MENU", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "JVC_OK", "JVC_SHUFFLE"};
int KEY_array_size = (sizeof(KEY_codes)/sizeof(long));
#define KEY_JVC_OK 0xF50D
#define KEY_JVC_SHUFFLE 0xF525
/*********************************************/
/*********************************************/
int ChangeMode(int new_mode)
{
last_mode = current_mode;
current_mode = new_mode;
return current_mode;
}
int ChangeLedMode(int new_mode)
{
last_led_mode = current_led_mode;
if(new_mode == -1)
{
//change led depending on light_state
if(light_state == false)
{
current_led_mode = LED_MODE_RED;
}
else
{
current_led_mode = LED_MODE_GREEN;
}
}
else
{
current_led_mode = new_mode;
}
return current_led_mode;
}
String TranslateCode(long code)
{
String giveback = "";
/*
long codes[] = {0x20DF10EF, 0x20DF22DD, 0x20DFE01F, 0x20DF609F, 0x20DF02FD, 0x20DF827D, 0x20DF40BF, 0x20DFC03F, 0x20DF906F, 0x20DF00FF, 0x20DF807F, 0x20DFC23D, 0x20DF08F7, 0x20DF8877, 0x20DF48B7, 0x20DFC837, 0x20DF28D7, 0x20DFA857, 0x20DF6897, 0x20DFE817, 0x20DF18E7, 0x20DF9867};
String buttons[] = {"POWER", "OK", "LEFT", "RIGHT", "UP", "DOWN", "VOL_UP", "VOL_DOWN", "MUTE", "PROG_UP", "PROG_DOWN", "MENU", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int array_size = (sizeof(codes)/sizeof(long));
*/
//check if code id in
for(int xi = 0; xi < KEY_array_size; xi++ )
{
if(code == KEY_codes[xi])
{
return KEY_buttons[xi];
}
}
return "UNKNOWN";
}
boolean CheckKeyPressedValid(long code)
{
for(int xi = 0; xi < KEY_array_size; xi++ )
{
if(code == KEY_codes[xi])
{
return true;
}
}
// else
return false;
}
boolean SwitchLight(int change_l = -1) // -1 = SWITCH // 0 (FALSE) = off // 1 (TRUE) = on
{
if(change_l == -1)
{
light_state = !light_state;
}
else if(change_l == true || change_l == 1)
{
light_state = true;
}
else if(change_l == false || change_l == 0)
{
light_state = false;
}
else
{
light_state = false;
}
digitalWrite(RELAY_PIN, light_state);
return light_state;
}
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
// decode_results *results = (decode_results *)v
void dump(decode_results *results) {
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.println("Could not decode message");
}
else {
if (results->decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, HEX);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, HEX);
}
Serial.print(" ");
}
Serial.println("");
}
//#####################################################################################################
//#####################################################################################################
//#####################################################################################################
unsigned long wb_start_pressed = 0;
unsigned long wb_pressed_duration = 0;
int RECV_PIN = IR_RECEIVER_PIN;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(LED_GREEN, OUTPUT);
// digitalWrite(LED_GREEN, HIGH);
pinMode(LED_RED, OUTPUT);
// digitalWrite(LED_RED, HIGH);
pinMode(RELAY_PIN, OUTPUT);
// digitalWrite(RELAY_PIN, HIGH);
pinMode(WALLBUTTON_PIN, INPUT);
digitalWrite(WALLBUTTON_PIN, HIGH); //internal pullup, LOW = PRESSED
irrecv.enableIRIn(); // Start the receiver
SwitchLight(false); // set light off at start
} // END SETUP
//#####################################################################################################
//#####################################################################################################
//#####################################################################################################
unsigned long blink_start_time = millis();
unsigned long blink_start_time_fast = millis();
unsigned long delayed_off_start_time = millis();
void loop()
{
time = millis();
long ir_key_pressed = 0;
if (irrecv.decode(&results))
{
if(CheckKeyPressedValid(results.value) == true)
{
ir_key_pressed = results.value;
// Serial.println(TranslateCode(ir_key_pressed));
}
else
{
ir_key_pressed = 0;
}
// dump(&results); // SERIAL.PRINT THE CODES
irrecv.resume(); // Receive the next value
}
if(ir_key_pressed == 0)
{
// NO IR KEY PRESSED, CHECK IF WALL-SWITCH IS PRESSED
//++++++++++++++++ START WALLBUTTON +++++++++++++++++++
wb_pressed_duration = 0;
wb_start_pressed = 0;
blink_start_time_fast = 0;
while(digitalRead(WALLBUTTON_PIN) == LOW) //low = pressed
{
if(wb_start_pressed == 0)
{
wb_start_pressed = millis();
}
else
{
wb_pressed_duration = millis() - wb_start_pressed;
blink_start_time_fast = millis();
if(wb_pressed_duration >= WALLBUTTON_TRESHOLD_DURATION && light_state == true && current_mode != MODE_DELAYED_OFF)
{
unsigned long blinking_duration_fast = millis() - blink_start_time ;
boolean blink_fast_onoffstate = false;
if( ((blinking_duration_fast / BLINK_INTERVAL_FAST) % 2) == 0) //check if nr of current interval is uneven or even number //ungerade oder grade
{
blink_fast_onoffstate = false;
}
else
{
blink_fast_onoffstate = true;
}
digitalWrite(LED_RED, blink_fast_onoffstate);
digitalWrite(LED_GREEN, !blink_fast_onoffstate);
}
}
}
if(wb_pressed_duration > WALLBUTTON_DEBOUNCE_TIME)
{
if(wb_pressed_duration < WALLBUTTON_TRESHOLD_DURATION)
{
ChangeMode(MODE_SWITCH_LIGHT);
}
else
{
ChangeMode(MODE_DELAYED_OFF);
}
}
//++++++++++++++++++ END WALLBUTTON +++++++++++++++++++++
}
else
{
// IR PROCESSING
Serial.println(ir_key_pressed, HEX);
Serial.println(KEY_OK , HEX);
if(ir_key_pressed == KEY_OK || ir_key_pressed == KEY_JVC_OK )
{
// OK KEY PRESSED
ChangeMode(MODE_SWITCH_LIGHT);
}
else if(ir_key_pressed == KEY_MUTE || ir_key_pressed == KEY_JVC_SHUFFLE )
{
ChangeMode(MODE_DELAYED_OFF);
}
}
//+++++++++++++++++ END INPUT (IR/BUTTON) EVALUATION +++++++++++++
if(last_mode == MODE_DELAYED_OFF && current_mode == MODE_SWITCH_LIGHT) //aboard delayed off
{
ChangeMode(MODE_STANDBY);
}
switch(current_mode)
{
case MODE_STANDBY:
// DO NOTHING
ChangeLedMode(-1);
break;
case MODE_SWITCH_LIGHT:
SwitchLight();
ChangeLedMode(-1); // -1 = CHANGE BY LIGHT_STATE
ChangeMode(MODE_STANDBY);
break;
case MODE_DELAYED_OFF:
if(light_state == true)
{
if(current_mode != last_mode)
{
delayed_off_start_time = time;
ChangeLedMode(LED_MODE_RED_BLINK);
}
else
{
if((time - delayed_off_start_time) <= (unsigned long)(DELAY_OFF_TIME * 1000))
{
// blink...
}
else //ended
{
ChangeMode(MODE_SWITCH_LIGHT);
}
}
}
else
{
ChangeMode(MODE_STANDBY);
}
break;
}
switch(current_led_mode)
{
case LED_MODE_RED:
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, LOW);
break;
case LED_MODE_GREEN:
digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, HIGH);
break;
case LED_MODE_RED_BLINK:
if(last_led_mode != current_led_mode)
{
// first run in this blink cycle, initialise blink time variable
blink_start_time = millis();
}
else
{
//blinking
unsigned long blinking_duration = time - blink_start_time ;
boolean blink_onoffstate = false;
if( ((blinking_duration / BLINK_INTERVAL) % 2) == 0) //check if nr of current interval is uneven or even number //ungerade oder grade
{
blink_onoffstate = false;
}
else
{
blink_onoffstate = true;
}
digitalWrite(LED_RED, blink_onoffstate);
digitalWrite(LED_GREEN, !blink_onoffstate);
}
break;
}
last_mode = current_mode;
last_led_mode = current_led_mode;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment