Created
February 2, 2012 20:47
-
-
Save anonymous/1725670 to your computer and use it in GitHub Desktop.
Arduino-IR-Light-Switch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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