Skip to content

Instantly share code, notes, and snippets.

@hughpyle
Created September 5, 2016 18:17
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 hughpyle/d4013d27f9b426fca082088b99b7288f to your computer and use it in GitHub Desktop.
Save hughpyle/d4013d27f9b426fca082088b99b7288f to your computer and use it in GitHub Desktop.
Teensy remote control for MiniDSP 2x4 HD
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <IRremoteInt.h>
/* This is a special-purpose infrared "remote control" to control vokume and channel selecion for the MiniDSP */
/* Hardware: Teensy 3.x, two rotary hex encoders (I used 25LB22-H), and a generic IR LED */
int UP = 1;
int DOWN = -1;
int NONE = 0;
bool stopped = 1;
int oldDirection = NONE;
int oldVolume = 0;
int oldPreset = 0;
IRsend irsend;
/* Pins */
/* Note: correct the IR LED to output pin 5 (Teensy 3) or 10 (Teensy 2) */
const int SRC_PIN_0 = 0;
const int SRC_PIN_1 = 1;
const int SRC_PIN_2 = 2;
const int SRC_PIN_3 = 3;
const int VOL_PIN_0 = 21;
const int VOL_PIN_1 = 20;
const int VOL_PIN_2 = 19;
const int VOL_PIN_3 = 18;
/* Some actual preset codes. Or you could use random values instead.
These are from hk3370 at http://www.righto.com/2009/11/controlling-your-stereo-over-web-with.html
*/
const uint32_t NEC_SOURCE_0 = 0x010e43bc;
const uint32_t NEC_SOURCE_1 = 0x010e23dc;
const uint32_t NEC_SOURCE_2 = 0x010e41be;
const uint32_t NEC_SOURCE_3 = 0x010e817e;
const uint32_t NEC_VOL_UP = 0x010ee31c;
const uint32_t NEC_VOL_DOWN = 0x010e13ec;
uint32_t PRESETS[] = {NEC_SOURCE_0, NEC_SOURCE_1, NEC_SOURCE_2, NEC_SOURCE_3};
void setup() {
/* nothing */
Serial.begin(9600);
pinMode(SRC_PIN_0, INPUT_PULLUP);
pinMode(SRC_PIN_1, INPUT_PULLUP);
pinMode(SRC_PIN_2, INPUT_PULLUP);
pinMode(SRC_PIN_3, INPUT_PULLUP);
pinMode(VOL_PIN_0, INPUT_PULLUP);
pinMode(VOL_PIN_1, INPUT_PULLUP);
pinMode(VOL_PIN_2, INPUT_PULLUP);
pinMode(VOL_PIN_3, INPUT_PULLUP);
}
/* Get the raw value from the volume input. Counter value 0 to 16. */
int getVolumeSetting() {
int vol = 0;
vol = (vol << 1) | digitalRead(VOL_PIN_0);
vol = (vol << 1) | digitalRead(VOL_PIN_1);
vol = (vol << 1) | digitalRead(VOL_PIN_2);
vol = (vol << 1) | digitalRead(VOL_PIN_3);
return vol;
}
/* Get the raw value from the sources input. Counter value 0 to 16. */
int getSourceSetting() {
int pre = 0;
pre = (pre << 1) | digitalRead(SRC_PIN_0);
pre = (pre << 1) | digitalRead(SRC_PIN_1);
pre = (pre << 1) | digitalRead(SRC_PIN_2);
pre = (pre << 1) | digitalRead(SRC_PIN_3);
return pre;
}
void loop() {
doStuff();
delay(100);
}
void doStuff() {
int v = getVolumeSetting();
int p = getSourceSetting();
/* If nothing has changed, there's nothing to do */
if( v==oldVolume && p==oldPreset ) {
stopped = true;
return;
}
/* If the preset has changed: handle it */
if( p != oldPreset ) {
Serial.print("Source has changed to ");
Serial.println(p, DEC);
sendPreset(p);
stopped = false;
return;
}
if( v != oldVolume ) {
Serial.print("Volume has changed to ");
Serial.println(v, DEC);
sendVolume(v);
stopped = false;
return;
}
}
void sendPreset(int p) {
/* The preset 'p' is from 0x0 to 0xF
* But it really only controls three inputs, so send (p % 3)
*/
/* Send the code for the selected preset. */
irsend.sendNEC(PRESETS[p % 0x03], 32);
/* Send twice. Helps with 'learn mode' but also for more reliability. */
delay(100);
irsend.sendNEC(PRESETS[p % 0x03], 32);
oldPreset = p;
/* Reset the direction memory for the volume spinner */
oldDirection = NONE;
}
void sendVolume(int v) {
/* Determine whether the volume went up or down. */
int direction = NONE;
if( v > oldVolume ) {
if( v-oldVolume >= 7 ) {
direction = DOWN;
} else {
direction = UP;
}
} else {
if( oldVolume-v >= 7 ) {
direction = UP;
} else {
direction = DOWN;
}
}
/* Did the volume change, in the same direction, twice in a row?
* If so, we're "spinning the wheel".
* Don't send "up" or "down", instead send "repeat".
*/
/*
if(direction == oldDirection && !stopped) {
Serial.println("repeat");
sendNECRepeat();
} else
*/
/* Send multiple volume steps at once, the control is too fine otherwise */
if(direction == UP) {
Serial.println("up");
irsend.sendNEC(NEC_VOL_UP, 32);
delay(100);
irsend.sendNEC(NEC_VOL_UP, 32);
delay(100);
irsend.sendNEC(NEC_VOL_UP, 32);
} else if(direction == DOWN) {
Serial.println("down");
irsend.sendNEC(NEC_VOL_DOWN, 32);
delay(100);
irsend.sendNEC(NEC_VOL_DOWN, 32);
delay(100);
irsend.sendNEC(NEC_VOL_DOWN, 32);
}
oldDirection = direction;
oldVolume = v;
}
void sendNECRepeat() {
/* https://github.com/z3t0/Arduino-IRremote/issues/28 */
unsigned int buf[3];
buf[0] = 9000; // Mark 9ms
buf[1] = 2250; // Space 2.25ms
buf[2] = 560; // Burst
irsend.sendRaw(buf, 3, 38);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment