Created
September 24, 2017 00:23
-
-
Save orbitinstasis/0edbbf5d2aadc25d288194cbfc88fab5 to your computer and use it in GitHub Desktop.
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
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding | |
Version 1.5 June 2014 | |
Copyright 2014 by Chris Young http://cyborg5.com | |
Based on original example sketch for IRremote library | |
Version 0.11 September, 2009 | |
Copyright 2009 Ken Shirriff | |
http://www.righto.com/ | |
*/ | |
/* | |
IRrecord: records IR signals | |
An IR detector/demodulator must be connected to the input IR_IN. | |
Record a value by pointing your remote at the device | |
*/ | |
/** | |
* Retrofitted IR Sleep code | |
*/ | |
/** | |
############################################ INCLUDES | |
*/ | |
#include <avr/sleep.h> | |
#include <avr/power.h> | |
#include <IRLibDecodeBase.h> //We need both the coding and | |
#include <IRLib_P01_NEC.h> //Lowest numbered protocol 1st | |
#include <IRLibCombo.h> // After all protocols, include this | |
#include <IRLibRecv.h> | |
#include <Bounce2.h> | |
#include <EEPROM.h> | |
/** | |
############################################ DEFINES | |
*/ | |
//buttons | |
#define SELECTOR_BTN 7 | |
#define POWER_SWITCH 12 | |
#define AUTO_VOLUME A1 | |
//outputs | |
#define POWER_LED 8 | |
#define SLEEP_LED 10 | |
#define SEL_4 13 | |
#define SEL_3 6 | |
#define SEL_2 5 | |
#define SEL_1 4 | |
#define MOTOR_REPLACE1 3 | |
#define MOTOR_REPLACE2 A0 | |
#define HIGH_POWER_SWITCH A2 | |
#define IR_IN 11 | |
#define NA_1 9 | |
#define EEPROM_ADDR 0 | |
#define ALL_SELECTIONS_OFF 255 | |
#define BTN_DEBOUNCE_TIME 25 | |
#define BAUD_RATE 115200 | |
#define NO_ACTIVITY_TIMEOUT 2000 // milliseconds | |
// IR Codes | |
#define IR_POWER 0xBD807F | |
#define IR_INPUT 0xBD10EF | |
#define IR_MUTE 0xBD20DF | |
#define IR_VOL_POS 0xBDD02F | |
#define IR_VOL_NEG 0xBDF00F | |
#define IR_BRIGHT_POS 0xBD52AD | |
#define IR_BRIGHT_NEG 0xBD926D | |
#define IR_REPEAT 0xFFFFFFFF | |
#define IR_DISPLAY 0xBD40BF | |
#define IR_MODE 0xBDC03F | |
#define IR_SIZE 0xBD28D7 | |
#define IR_MENU 0xBD50AF | |
// All of the above automatically creates a universal decoder | |
// class called "IRdecode" and a universal sender class "IRsend" | |
// containing only the protocols you want. | |
// Now declare instances of the decoder and the sender. | |
IRrecv myReceiver(IR_IN); | |
IRdecode myDecoder; | |
unsigned long lastCode = IR_REPEAT; | |
unsigned long previousSleep = 0; | |
unsigned long previousVolCapture = 0; | |
unsigned long currentMillis = 0; | |
boolean is_hold = false; | |
boolean ir_power_pressed = false; | |
boolean ir_selector_pressed = false; | |
boolean ir_mute_pressed = false; | |
boolean is_on = false; | |
Bounce debouncer_selector = Bounce(); | |
Bounce debouncer_power = Bounce(); | |
uint8_t intput_pulled_up[] = {POWER_SWITCH, AUTO_VOLUME, SELECTOR_BTN}; | |
uint8_t outputs[] = {POWER_LED, SLEEP_LED, SEL_4, SEL_3, SEL_2, SEL_1, MOTOR_REPLACE1, MOTOR_REPLACE2, HIGH_POWER_SWITCH}; | |
uint8_t selection_value = 0; | |
uint8_t selections[] = {SEL_1, SEL_2, SEL_3, SEL_4}; | |
/* | |
Because this version of the library separated the receiver from the decoder, | |
technically you would not need to "store" the code outside the decoder object | |
for this overly simple example. All of the details would remain in the object. | |
However we are going to go ahead and store them just to show you how. | |
*/ | |
// Storage for the recorded code | |
uint8_t codeProtocol; // The type of code | |
uint32_t codeValue; // The data bits if type is not raw | |
uint8_t codeBits; // The length of the code in bits | |
// added by Nick Gammon | |
EMPTY_INTERRUPT (PCINT0_vect); | |
/** | |
############################################ ############################################ SETUP | |
*/ | |
void setup() | |
{ | |
power_adc_disable(); // ADC converter | |
power_usart0_disable();// Serial (USART) | |
power_timer1_disable(); // Timer 1 | |
power_twi_disable(); // TWI (I2C) | |
codeProtocol = UNKNOWN; | |
codeValue = 0; | |
Serial.begin(BAUD_RATE); | |
for (int i = 0; i < 3; i++) | |
{ | |
pinMode(intput_pulled_up[i], INPUT_PULLUP); | |
} | |
pinMode(IR_IN, INPUT); //CHECK IF THIS NEEDS TO BE PULLED UP | |
for (int i = 0; i < 9; i++) | |
{ | |
pinMode(outputs[i], OUTPUT); | |
digitalWrite(outputs[i], LOW); | |
} | |
digitalWrite(SLEEP_LED, HIGH); | |
digitalWrite(POWER_LED, LOW); | |
debouncer_selector.attach(SELECTOR_BTN); | |
debouncer_selector.interval(BTN_DEBOUNCE_TIME); | |
debouncer_power.attach(POWER_SWITCH); | |
debouncer_power.interval(BTN_DEBOUNCE_TIME); | |
uint8_t eeprom_read = EEPROM.read(EEPROM_ADDR); | |
delay(10); | |
// Serial.print("eeprom_read: "); Serial.println(eeprom_read); | |
if ((eeprom_read >= 0) || (eeprom_read <= 3)) | |
selection_value = eeprom_read; | |
else | |
selection_value = 0; | |
// Serial.print("selection_value at setup: "); Serial.println(selection_value); | |
myReceiver.enableIRIn(); | |
currentMillis = millis(); | |
previousVolCapture = millis(); | |
previousSleep = millis(); | |
myReceiver.enableIRIn(); // Start the receiver | |
} | |
/** | |
################################################################################################ MAIN LOOP | |
*/ | |
void loop() { | |
// added by Nick Gammon | |
static unsigned long lastActivity; // when we last woke | |
// sleep if no activity for a while | |
if (millis () - lastActivity >= NO_ACTIVITY_TIMEOUT && !is_hold) | |
{ | |
Serial.flush (); // wait for Serial to finish outputting | |
Serial.end (); // shut down Serial | |
noInterrupts (); // timed sequence coming up | |
// pin change interrupt for D11 | |
PCMSK0 |= bit (PCINT3); // want pin 11 | |
PCIFR |= bit (PCIF0); // clear any outstanding interrupts | |
PCICR |= bit (PCIE0); // enable pin change interrupts for D8 to D13 | |
set_sleep_mode (SLEEP_MODE_STANDBY); | |
sleep_enable(); | |
byte old_ADCSRA = ADCSRA; | |
// disable ADC to save power | |
ADCSRA = 0; | |
// power_all_disable (); // turn off various modules | |
interrupts (); | |
sleep_cpu (); | |
sleep_disable(); | |
power_all_enable (); // enable modules again | |
ADCSRA = old_ADCSRA; // re-enable ADC conversion | |
// Serial.begin(BAUD_RATE); | |
lastActivity = millis (); | |
} // end of no activity for a couple of seconds | |
if (myReceiver.getResults()) { | |
myDecoder.decode(); | |
processIrData(); | |
delay(50); | |
currentMillis = millis(); | |
if (currentMillis - previousVolCapture > 250) | |
{ | |
stop_motor(); | |
previousVolCapture = currentMillis; | |
} | |
debouncer_power.update(); | |
debouncer_selector.update(); | |
if (debouncer_power.rose() || ir_power_pressed) | |
{ | |
// Serial.print("selection_value at power press BEGIN: "); Serial.println(selection_value); | |
ir_power_pressed = false; | |
if (!is_on) | |
{ // POWER ON SLEEP OFF | |
is_on = true; | |
selector(selection_value); | |
digitalWrite(SLEEP_LED, LOW); | |
digitalWrite(HIGH_POWER_SWITCH, HIGH); | |
} | |
else | |
{ //SLEEP ON POWER OFF | |
is_on = false; | |
selector(ALL_SELECTIONS_OFF); | |
stop_motor(); | |
digitalWrite(SLEEP_LED, HIGH); | |
digitalWrite(HIGH_POWER_SWITCH, LOW); | |
} | |
// Serial.print("selection_value at power press END: "); Serial.println(selection_value); | |
} | |
if (debouncer_selector.rose() || ir_selector_pressed) | |
{ | |
// Serial.print("selection_value at start of button press: "); Serial.println(selection_value); | |
ir_selector_pressed = false; | |
if (is_on) | |
{ | |
if (selection_value >= 3) | |
{ | |
selection_value = 0; | |
} | |
else | |
selection_value++; | |
EEPROM.write(EEPROM_ADDR, selection_value); | |
// Serial.print("selection_value at EEPROM after writing: "); Serial.println(EEPROM.read(EEPROM_ADDR)); | |
selector(selection_value); | |
} | |
} | |
myReceiver.enableIRIn(); | |
} | |
} | |
/** | |
############################################ FUNCTIONS | |
*/ | |
void processIrData(void) { | |
codeProtocol = myDecoder.protocolNum; | |
if (myDecoder.value == REPEAT_CODE) { | |
// Serial.println(F("repeat.")); | |
is_hold = true; | |
codeValue = lastCode; // replace IR_REPEAT with last good code | |
} | |
else { | |
codeValue = myDecoder.value; | |
codeBits = myDecoder.bits; | |
if (codeValue == IR_POWER && !is_hold) | |
{ | |
lastCode = codeValue; | |
ir_power_pressed = true; | |
} | |
if (codeValue == IR_MUTE && is_on && !is_hold) | |
{ | |
lastCode = codeValue; | |
ir_mute_pressed = !ir_mute_pressed; | |
if (ir_mute_pressed) | |
{ | |
digitalWrite(POWER_LED, HIGH); | |
selector(ALL_SELECTIONS_OFF); | |
} | |
else | |
{ | |
digitalWrite(POWER_LED, LOW); | |
selector(selection_value); | |
} | |
} | |
if (codeValue == IR_INPUT && is_on && !is_hold) | |
{ | |
lastCode = codeValue; | |
ir_selector_pressed = true; | |
} | |
if (codeValue == IR_BRIGHT_POS && is_on && !is_hold) | |
{ | |
lastCode = codeValue; | |
move_motor(true, 2000); | |
} | |
if (codeValue == IR_BRIGHT_NEG && is_on && !is_hold) | |
{ | |
lastCode = codeValue; | |
move_motor(false, 2000); | |
} | |
if (codeValue == IR_VOL_POS && is_on ) | |
{ | |
lastCode = codeValue; | |
move_motor(true, 0); | |
previousVolCapture = millis(); | |
} | |
if (codeValue == IR_VOL_NEG && is_on ) | |
{ | |
lastCode = codeValue; | |
move_motor(false, 0); | |
previousVolCapture = millis(); | |
} | |
} | |
} | |
void stop_motor() | |
{ | |
digitalWrite(MOTOR_REPLACE1, LOW); | |
digitalWrite(MOTOR_REPLACE2, LOW); | |
} | |
void selector(uint8_t in) | |
{ | |
if (in == ALL_SELECTIONS_OFF) | |
{ | |
for (int i = 0; i < 4; i++) | |
{ | |
digitalWrite(selections[i], LOW); | |
} | |
} | |
else | |
{ | |
for (int i = 0; i < 4; i++) | |
{ | |
if (i == in) | |
digitalWrite(selections[i], HIGH); | |
else | |
digitalWrite(selections[i], LOW); | |
} | |
} | |
} | |
void move_motor(boolean isClockwise, int _time) // time in seconds | |
{ | |
if (isClockwise) | |
{ | |
digitalWrite(MOTOR_REPLACE1, LOW); | |
digitalWrite(MOTOR_REPLACE2, HIGH); | |
} | |
else | |
{ | |
digitalWrite(MOTOR_REPLACE1, HIGH); | |
digitalWrite(MOTOR_REPLACE2, LOW); | |
} | |
if (_time > 0) | |
{ | |
delay(_time); | |
stop_motor(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment