Skip to content

Instantly share code, notes, and snippets.

@orbitinstasis
Created September 24, 2017 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orbitinstasis/edb93341abe565f88863ddd999043690 to your computer and use it in GitHub Desktop.
Save orbitinstasis/edb93341abe565f88863ddd999043690 to your computer and use it in GitHub Desktop.
/**
MCU replacement for audio selector ARDUINO NANO
2017 Ben Kazemi @ Orbitronics
*/
/**
############################################ INCLUDES
*/
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <LowPower.h>
#include <Bounce2.h>
#include <EEPROM.h>
#include <IRremote.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
// 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
/**
############################################ VARIABLES
*/
IRrecv irrecv(IR_IN);
decode_results results;
unsigned long lastCode = IR_REPEAT;
unsigned long previousSleep = 0;
unsigned long previousVolCapture = 0;
unsigned long currentMillis = 0;
boolean is_holding_vol = 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};
/**
############################################ SETUP
*/
void setup() {
power_adc_disable(); // ADC converter
power_usart0_disable();// Serial (USART)
power_timer1_disable(); // Timer 1
power_twi_disable(); // TWI (I2C)
// Serial.begin(9600);
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);
irrecv.enableIRIn();
currentMillis = millis();
previousVolCapture = millis();
previousSleep = millis();
}
/**
############################################ FUNCTIONS
*/
void test()
{
boolean power_led_tmp = digitalRead(POWER_LED);
boolean sleep_led_tmp = digitalRead(SLEEP_LED);
digitalWrite(POWER_LED, LOW);
digitalWrite(SLEEP_LED, LOW);
delay(1500);
digitalWrite(POWER_LED, power_led_tmp);
digitalWrite(SLEEP_LED, sleep_led_tmp);
}
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();
}
}
/**
############################################ MAIN LOOP
*/
void loop() {
if (irrecv.decode(&results)) //this checks to see if a code has been received
{
boolean is_hold = false;
if (results.value == IR_REPEAT) // if repeat command (button held down)
{
is_hold = true;
results.value = lastCode; // replace IR_REPEAT with last good code
}
if (results.value == IR_POWER && !is_hold)
{
lastCode = results.value;
ir_power_pressed = true;
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
}
if (results.value == IR_MUTE && is_on && !is_hold)
{
lastCode = results.value;
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);
}
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
}
if (results.value == IR_INPUT && is_on && !is_hold)
{
lastCode = results.value;
ir_selector_pressed = true;
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
}
if (results.value == IR_BRIGHT_POS && is_on && !is_hold)
{
lastCode = results.value;
move_motor(true, 2000);
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
}
if (results.value == IR_BRIGHT_NEG && is_on && !is_hold)
{
lastCode = results.value;
move_motor(false, 2000);
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
}
if (results.value == IR_VOL_POS && is_on )
{
lastCode = results.value;
move_motor(true, 0);
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
previousVolCapture = millis();
}
if (results.value == IR_VOL_NEG && is_on )
{
lastCode = results.value;
move_motor(false, 0);
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
previousVolCapture = millis();
}
irrecv.resume(); //receive the next value
}
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);
LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
// Serial.print("selection_value at EEPROM after writing: "); Serial.println(EEPROM.read(EEPROM_ADDR));
selector(selection_value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment