Skip to content

Instantly share code, notes, and snippets.

@aarontwf
Last active April 26, 2016 01:57
Show Gist options
  • Save aarontwf/d3125350efa9fde89856 to your computer and use it in GitHub Desktop.
Save aarontwf/d3125350efa9fde89856 to your computer and use it in GitHub Desktop.
#include <OneButton.h>
#include <MIDI.h>
#include <SoftwareSerial.h>
// Constants
const int timelineChannel = 1;
const int bigskyChannel = 2;
const int displayTx = 10;
const int displayRx = -1;
const int ledRed = 3;
const int ledGreen = 4;
const int ledBlue = 5;
const int ledA1 = 20;
const int ledA2 = 21;
const int ledA3 = 22;
const int ledA4 = 23;
const int inA = 2;
const int inB = 6;
const int inC = 7;
const int inD = 8;
const int inE = 9;
const int SCROLL_DELAY = 500;
// Variables
OneButton buttonA(inA, true);
OneButton buttonB(inB, true);
OneButton buttonC(inC, true);
OneButton buttonD(inD, true);
OneButton buttonE(inE, true);
SoftwareSerial s7s(displayRx, displayTx);
char tempString[10]; // Will be used with sprintf to create strings
unsigned int presetB = 0;
unsigned int presetT = 0;
boolean engagedB = false;
boolean engagedT = false;
const int MODE_EDIT = -1;
int mode = 0;
typedef struct {
unsigned int bigskyPreset;
unsigned int timelinePreset;
boolean bigskyEngaged;
boolean timelineEngaged;
} ControllerPreset;
const int NUM_BANKS = 10;
const int NUM_PRESETS = 4;
unsigned int controllerBank = 0;
unsigned int controllerPreset = 0;
ControllerPreset presets[NUM_BANKS * NUM_PRESETS] = {
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false},
{0, 0, false, false}
};
char presetLetters[NUM_PRESETS] = {
'A', 'B', 'C', 'D'
};
// Edit mode
unsigned int saveBank = 0;
unsigned int savePreset = 0;
void setupLeds() {
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(ledA1, OUTPUT);
pinMode(ledA2, OUTPUT);
pinMode(ledA3, OUTPUT);
pinMode(ledA4, OUTPUT);
}
void setupButtons() {
pinMode(inA, INPUT_PULLUP);
pinMode(inB, INPUT_PULLUP);
pinMode(inC, INPUT_PULLUP);
pinMode(inD, INPUT_PULLUP);
pinMode(inE, INPUT_PULLUP);
buttonA.setClickTicks(0);
buttonB.setClickTicks(0);
buttonC.setClickTicks(0);
buttonD.setClickTicks(0);
buttonE.setClickTicks(0);
buttonA.setPressTicks(500);
buttonB.setPressTicks(500);
buttonC.setPressTicks(500);
buttonD.setPressTicks(500);
buttonE.setPressTicks(500);
buttonA.attachClick(btnAPress);
buttonA.attachDuringLongPress(btnAHold);
buttonB.attachClick(btnBPress);
buttonB.attachDuringLongPress(btnBHold);
buttonC.attachClick(btnCPress);
buttonC.attachDuringLongPress(btnCHold);
buttonD.attachClick(btnDPress);
buttonD.attachDuringLongPress(btnDHold);
buttonE.attachClick(btnEPress);
buttonE.attachDuringLongPress(btnEHold);
}
void setup() {
// Must begin s7s software serial at the correct baud rate.
// The default of the s7s is 9600.
s7s.begin(9600);
clearDisplay(); // Clears display, resets cursor
setBrightness(255); // High brightness
s7s.print(" ");
delay(SCROLL_DELAY);
clearDisplay();
s7s.print("- ");
delay(SCROLL_DELAY);
clearDisplay();
s7s.print("-- ");
delay(SCROLL_DELAY);
clearDisplay();
s7s.print("--- ");
delay(SCROLL_DELAY);
clearDisplay();
s7s.print("----");
delay(SCROLL_DELAY);
clearDisplay();
setupLeds();
setupButtons();
MIDI.begin();
Serial.begin(38400);
setPreset(0, 0);
setMode(mode);
}
void loop() {
// Magical sprintf creates a string for us to send to the s7s.
// The %4d option creates a 4-digit integer.
if (mode == MODE_EDIT) {
char letter = presetLetters[savePreset];
sprintf(tempString, "%02d %c", saveBank, letter);
} else if (mode == 0) {
char letter = presetLetters[controllerPreset];
sprintf(tempString, "%02d %c", controllerBank, letter);
if (controllerPreset == 0) {
digitalWrite(ledA1, HIGH);
digitalWrite(ledA2, LOW);
digitalWrite(ledA3, LOW);
digitalWrite(ledA4, LOW);
} else if (controllerPreset == 1) {
digitalWrite(ledA1, LOW);
digitalWrite(ledA2, HIGH);
digitalWrite(ledA3, LOW);
digitalWrite(ledA4, LOW);
} else if (controllerPreset == 2) {
digitalWrite(ledA1, LOW);
digitalWrite(ledA2, LOW);
digitalWrite(ledA3, HIGH);
digitalWrite(ledA4, LOW);
} else if (controllerPreset == 3) {
digitalWrite(ledA1, LOW);
digitalWrite(ledA2, LOW);
digitalWrite(ledA3, LOW);
digitalWrite(ledA4, HIGH);
} else {
digitalWrite(ledA1, LOW);
digitalWrite(ledA2, LOW);
digitalWrite(ledA3, LOW);
digitalWrite(ledA4, LOW);
}
} else if (mode == 1) {
int bankB = presetB / 2;
int bankT = presetT / 2;
if (engagedB && engagedT) {
sprintf(tempString, "%02d%02d", bankB, bankT);
} else if (engagedB) {
sprintf(tempString, "%02d--", bankB);
} else if (engagedT) {
sprintf(tempString, "--%02d", bankT);
} else {
sprintf(tempString, "----");
}
} else {
sprintf(tempString, "SCAR");
}
// This will output the tempString to the S7S
s7s.print(tempString);
buttonA.tick();
buttonB.tick();
buttonC.tick();
buttonD.tick();
buttonE.tick();
}
void setMode(int m) {
if (mode == 0) {
digitalWrite(ledA1, LOW);
digitalWrite(ledA2, LOW);
digitalWrite(ledA3, LOW);
digitalWrite(ledA4, LOW);
}
mode = m;
if (m == MODE_EDIT) {
initModeEdit();
} else if (m == 0) {
initMode0();
} else if (m == 1) {
initMode1();
} else if (m == 2) {
initMode2();
} else {
mode = 0;
setMode(mode);
return;
}
}
void initModeEdit() {
setColor(90, 30, 0);
digitalWrite(ledA4, HIGH);
saveBank = controllerBank;
savePreset = controllerPreset;
sprintf(tempString, "EDIT");
s7s.print(tempString);
delay(800);
}
void initMode0() {
setColor(0, 80, 120);
}
void initMode1() {
setColor(200, 0, 100);
}
void initMode2() {
setColor(255, 0, 0);
}
// Send the clear display command (0x76)
// This will clear the display and reset the cursor
void clearDisplay() {
s7s.write(0x76); // Clear display command
}
// Set the displays brightness. Should receive byte with the value
// to set the brightness to
// dimmest------------->brightest
// 0--------127--------255
void setBrightness(byte value) {
s7s.write(0x7A); // Set brightness command byte
s7s.write(value); // brightness data byte
}
// Turn on any, none, or all of the decimals.
// The six lowest bits in the decimals parameter sets a decimal
// (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
// [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimals(byte decimals) {
s7s.write(0x77);
s7s.write(decimals);
}
// -------------------------------------
// Controller Presets
// -------------------------------------
void loadPreset() {
ControllerPreset p = presets[(controllerBank * NUM_PRESETS) + controllerPreset];
presetB = p.bigskyPreset;
presetT = p.timelinePreset;
engagedB = p.bigskyEngaged;
engagedT = p.timelineEngaged;
MIDI.sendControlChange(0, presetB > 127 ? 1 : 0, bigskyChannel);
MIDI.sendProgramChange(presetB % 128, bigskyChannel);
MIDI.sendControlChange(102, engagedB ? 127 : 0, bigskyChannel); // Turn on/off
MIDI.sendControlChange(0, presetT > 127 ? 1 : 0, timelineChannel);
MIDI.sendProgramChange(presetT % 128, timelineChannel);
MIDI.sendControlChange(102, engagedT ? 127 : 0, timelineChannel); // Turn on/off
}
void setPreset(int newBank, int newPreset) {
if (newBank < 0 || newBank >= NUM_BANKS || newPreset < 0 || newPreset >= NUM_PRESETS) {
clearDisplay();
delay(100);
} else {
controllerBank = newBank;
controllerPreset = newPreset;
loadPreset();
}
}
void bankUp() {
setPreset(controllerBank + 1, 0);
}
void bankDown() {
setPreset(controllerBank - 1, 0);
}
void cyclePreset() {
int p = controllerPreset + 1;
if (p >= NUM_PRESETS) p = 0;
setPreset(controllerBank, p);
}
void presetUp() {
int p = controllerPreset + 1;
if (p >= NUM_PRESETS) p = 0;
setPreset(controllerBank, p);
}
void presetDown() {
int p = controllerPreset - 1;
if (p < 0) p = NUM_PRESETS - 1;
setPreset(controllerBank, p);
}
void toggleEngaged() {
}
void setSavePreset(int newBank, int newPreset) {
if (newBank < 0 || newBank >= NUM_BANKS || newPreset < 0 || newPreset >= NUM_PRESETS) {
clearDisplay();
delay(100);
} else {
saveBank = newBank;
savePreset = newPreset;
}
}
// -------------------------------------
// -------------------------------------
// -------------------------------------
void tap() {
setDecimals(0b001111);
MIDI.sendControlChange(93, 127, bigskyChannel);
MIDI.sendControlChange(93, 127, timelineChannel);
delay(50);
setDecimals(0b000000);
}
void setPresetT(int newPreset) {
presetT = newPreset;
MIDI.sendControlChange(0, presetT > 127 ? 1 : 0, timelineChannel);
MIDI.sendProgramChange(presetT % 128, timelineChannel);
engagedT = true;
MIDI.sendControlChange(102, engagedT ? 127 : 0, timelineChannel); // Turn on/off
}
void setPresetB(int newPreset) {
presetB = newPreset;
MIDI.sendControlChange(0, presetB > 127 ? 1 : 0, bigskyChannel);
MIDI.sendProgramChange(presetB % 128, bigskyChannel);
engagedB = true;
MIDI.sendControlChange(102, engagedB ? 127 : 0, bigskyChannel); // Turn on/off
}
void setEngagedT(boolean engaged) {
engagedT = false;
MIDI.sendControlChange(102, engagedT ? 127 : 0, timelineChannel); // Turn on/off
}
void setEngagedB(boolean engaged) {
engagedB = false;
MIDI.sendControlChange(102, engagedB ? 127 : 0, bigskyChannel); // Turn on/off
}
void presetUpT() {
if (presetT >= 198) {
setPresetT(198);
clearDisplay();
delay(100);
} else {
setPresetT(presetT + 1);
}
}
void presetDownT() {
if (presetT <= 0) {
setPresetT(0);
clearDisplay();
delay(100);
} else {
setPresetT(presetT - 1);
}
}
void presetUpB() {
if (presetB >= 199) {
setPresetB(199);
clearDisplay();
delay(100);
} else {
setPresetB(presetB + 1);
}
}
void presetDownB() {
if (presetB <= 0) {
setPresetB(0);
clearDisplay();
delay(100);
} else {
setPresetB(presetB - 1);
}
}
void btnAPress() {
setMode(mode + 1);
}
void btnAHold() {
if (mode != MODE_EDIT) {
setMode(MODE_EDIT);
}
}
void btnBPress() {
if (mode == 0) {
bankDown();
} else if (mode == 1) {
digitalWrite(ledA1, HIGH);
presetDownB();
delay(200);
digitalWrite(ledA1, LOW);
} else if (mode == MODE_EDIT) {
digitalWrite(ledA1, HIGH);
setSavePreset(saveBank - 1, savePreset);
delay(200);
digitalWrite(ledA1, LOW);
}
}
void btnBHold() {
if (mode == 0) {
setPreset(controllerBank, 0);
}
}
void btnCPress() {
if (mode == 0) {
bankUp();
} else if (mode == 1) {
digitalWrite(ledA2, HIGH);
presetUpB();
delay(200);
digitalWrite(ledA2, LOW);
} else if (mode == MODE_EDIT) {
digitalWrite(ledA2, HIGH);
setSavePreset(saveBank + 1, savePreset);
delay(200);
digitalWrite(ledA2, LOW);
}
}
void btnCHold() {
if (mode == 0) {
setPreset(controllerBank, 1);
} else if (mode == 1) {
setEngagedB(!engagedB);
}
}
void btnDPress() {
if (mode == 0) {
cyclePreset();
} else if (mode == 1) {
digitalWrite(ledA3, HIGH);
presetDownT();
delay(200);
digitalWrite(ledA3, LOW);
} else if (mode == MODE_EDIT) {
digitalWrite(ledA3, HIGH);
int p = savePreset + 1;
if (p >= NUM_PRESETS) p = 0;
setSavePreset(saveBank, p);
delay(200);
digitalWrite(ledA3, LOW);
}
}
void btnDHold() {
if (mode == 0) {
setPreset(controllerBank, 2);
}
}
void btnEPress() {
if (mode == 0) {
tap();
} else if (mode == 1) {
digitalWrite(ledA4, HIGH);
presetUpT();
delay(200);
digitalWrite(ledA4, LOW);
} else if (mode == MODE_EDIT) {
ControllerPreset p = presets[(saveBank * NUM_PRESETS) + savePreset];
p.bigskyEngaged = engagedB;
p.timelineEngaged = engagedT;
p.bigskyPreset = presetB;
p.timelinePreset = presetT;
presets[(saveBank * NUM_PRESETS) + savePreset] = p;
sprintf(tempString, "SET ");
s7s.print(tempString);
delay(200);
digitalWrite(ledA1, HIGH);
delay(100);
digitalWrite(ledA1, LOW);
digitalWrite(ledA2, HIGH);
delay(100);
digitalWrite(ledA2, LOW);
digitalWrite(ledA3, HIGH);
delay(100);
digitalWrite(ledA3, LOW);
digitalWrite(ledA4, HIGH);
delay(100);
digitalWrite(ledA4, LOW);
setMode(0);
setPreset(saveBank, savePreset);
}
}
void btnEHold() {
if (mode == 0) {
setPreset(controllerBank, 3);
}
}
void setColor(int red, int green, int blue) {
analogWrite(ledRed, red);
analogWrite(ledGreen, green);
analogWrite(ledBlue, blue);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment