#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Keypad.h>
LiquidCrystal lcd(19, 18, 17, 16, 15, 14);
#define rHot LOW
#define rGnd HIGH
void setupRelays();
void switchRelay(int, int);
const int bankButton = A15; //blue button
const int downButton = A12; //red button
int progButton = A14; //program button (green) - matches LED
int saveButton = A13; //save button (yellow) - matches LED
const byte rows = 9;
const byte cols = 3;
char keys[rows][cols] = {
{ 'a', 'j', 's' },
{ 'b', 'k', 't' },
{ 'c', 'l', 'u' },
{ 'd', 'm', 'v' },
{ 'e', 'n', 'w' },
{ 'f', 'o', 'x' },
{ 'g', 'p', 'y' },
{ 'h', 'q', 'z' },
{ 'i', 'r', '$' }
};
byte rowPins[rows] = { 2, 3, 4, 20, 21, 22, 23, 24, 25 }; /* buttons or momentary switches */
//byte colPins[cols] = {5,6,7}; /* rotary switch - pin 7 is read/use, pin 5 is program/choose effects, pin 6 is save to a preset. */
byte colPins[cols] = { 46, 48, 44 }; /* Green and Yellow Buttons - pin 44 is read/use, pin 46 is program/choose effects, pin 48 is save to a preset. */
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
int OneRelayPin[9] = { 8, 9, 10, 26, 27, 28, 29, 30, 31 }; /* pin 1 on relay - reset/default has pin 1 at 0v - RED LED */
int TenRelayPin[9] = { 11, 12, 13, 32, 33, 34, 35, 36, 37 }; /* pin 10 on relay - reset/default has pin 10 at 5v - BLUE LED */
int presetLEDPin[3] = { A0, A1, A2 }; /* shows which preset is engaged - GREEN LED */
int effectLEDPin[3] = { A3, A4, A5 }; /* shows which effects are engaged - YELLOW LED */
int progRelay = 53;
int progLED = 52;
int saveRelay = 51;
int saveLED = 50;
byte midiChannel = 0;
int numberOfPedal = 3;
int bankVariable = 9;
int numberOfBanks = 9;
int bank = 0; //Starting Bank Number
boolean lastBankButton = LOW;
boolean currentBankButton = LOW;
boolean lastDownButton = LOW;
boolean currentDownButton = LOW;
boolean lastProgButton = LOW;
boolean currentProgButton = LOW;
boolean progOn = true;
boolean lastSaveButton = LOW;
boolean currentSaveButton = LOW;
boolean saveOn = true;
/******************************************************/
void setup() {
lcd.begin(16, 2);
lcd.print("You are a fat");
lcd.setCursor(0, 1);
lcd.print("sausage bitch!");
setupRelays(); // pins and initial state
pinMode(progLED, OUTPUT);
pinMode(progRelay, OUTPUT);
pinMode(saveLED, OUTPUT);
pinMode(saveRelay, OUTPUT);
for (int ii = 0; ii < numberOfPedal; ii++) /* setup device */
{
pinMode(presetLEDPin[ii], OUTPUT);
pinMode(effectLEDPin[ii], OUTPUT);
digitalWrite(presetLEDPin[ii], LOW);
digitalWrite(effectLEDPin[ii], LOW);
delay(100);
}
delay(100);
for (int ii = 0; ii < numberOfPedal; ii++) {
digitalWrite(presetLEDPin[ii], HIGH);
digitalWrite(effectLEDPin[ii], HIGH);
delay(100);
}
digitalWrite(progLED, LOW);
digitalWrite(saveLED, LOW);
digitalWrite(progRelay, LOW);
digitalWrite(saveRelay, LOW);
delay(100);
digitalWrite(progLED, HIGH);
digitalWrite(saveLED, HIGH);
delay(100);
digitalWrite(progRelay, HIGH);
digitalWrite(saveRelay, HIGH);
delay(100);
//readPreset((bank * bankVariable), 1, 0); /* pulls first saved preset in memory */
Serial.begin(31250); /* for midi communication - pin 1 TX */
/*for (int i = 0; i < 10; i++) // erase eeprom (optional) */
}
/* Bank Button Debounce */
boolean bankdebounce(boolean last) {
boolean current = digitalRead(bankButton);
if (last != current) {
delay(5);
current = digitalRead(bankButton);
}
return current;
}
boolean downdebounce(boolean last) {
boolean current = digitalRead(downButton);
if (last != current) {
delay(5);
current = digitalRead(downButton);
}
return current;
}
/* Program and Save Button Debounce */
boolean progdebounce(boolean last) {
boolean current = digitalRead(progButton);
if (last != current) {
delay(5);
current = digitalRead(progButton);
}
return current;
}
boolean savedebounce(boolean last) {
boolean current = digitalRead(saveButton);
if (last != current) {
delay(5);
current = digitalRead(saveButton);
}
return current;
}
/*********************************************************/
void midiProg(byte status, int data) {
Serial.write(status);
Serial.write(data);
}
/*********************************************************/
void memory(int addr, int led) {
for (int ii = 0; ii < numberOfPedal; ii++) {
EEPROM.write((addr) + ii, digitalRead(effectLEDPin[ii]));
digitalWrite(presetLEDPin[ii], HIGH); // turns off all preset LEDs
}
lcd.clear();
lcd.print("Program saved to");
lcd.setCursor(0, 1);
lcd.print("Bank ");
lcd.print(bank);
lcd.print(" Preset ");
lcd.print(led + 1);
/* Preset LED will flash when saving effects loops */
delay(100);
digitalWrite(presetLEDPin[led], LOW);
delay(100);
digitalWrite(presetLEDPin[led], HIGH);
delay(100);
digitalWrite(presetLEDPin[led], LOW);
delay(100);
digitalWrite(presetLEDPin[led], HIGH);
delay(100);
digitalWrite(presetLEDPin[led], LOW);
delay(100);
digitalWrite(presetLEDPin[led], HIGH);
delay(100);
digitalWrite(presetLEDPin[led], LOW);
delay(100);
digitalWrite(presetLEDPin[led], HIGH);
saveOn = !saveOn;
delay(1500);
lcd.clear();
lcd.print("Hit Prog to Exit");
lcd.setCursor(0, 1);
lcd.print("Or Select Loops");
}
/*********************************************************/
void resetAllRelays() {
for (int ii = 0; ii < numberOfPedal; ii++)
switchRelay(ii, LOW); //... whatever the reset state is
}
/*********************************************************/
void resetAllLeds() {
for (int ii = 0; ii < numberOfPedal; ii++) {
digitalWrite(presetLEDPin[ii], HIGH);
}
}
/*********************************************************/
void writeOut(int relay) {
resetAllLeds();
digitalWrite(effectLEDPin[relay], !digitalRead(effectLEDPin[relay]));
/*digitalWrite(ledPin[relay], !digitalRead(relayPin[relay]));
/* thanks to anton.efremoff.1 for this tip */
lcd.clear();
lcd.print("Current Bank: ");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Select Loops: ");
lcd.print(relay + 1);
}
/*********************************************************/
void readPreset(int addr, int pcNum, int led) {
for (int ii = 0; ii < numberOfPedal; ii++) {
digitalWrite(effectLEDPin[ii], EEPROM.read((addr) + ii));
digitalWrite(presetLEDPin[ii], HIGH);
int kPreset = EEPROM.read((addr) + ii);
switchRelay(ii, kPreset ? HIGH : LOW);
}
digitalWrite(presetLEDPin[led], LOW);
lcd.clear();
lcd.print(" B-");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Preset ");
lcd.print(led + 1);
delay(100);
}
/*********************************************************/
void loop() {
currentBankButton = bankdebounce(lastBankButton);
if (lastBankButton == LOW && currentBankButton == HIGH) {
bank++;
for (int ii = 0; ii < numberOfPedal; ii++) {
digitalWrite(presetLEDPin[ii], HIGH); //turn OFF all preset LEDs
digitalWrite(effectLEDPin[ii], HIGH);
}
lcd.clear();
lcd.print(" B-");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Press Any Preset");
if (bank >= numberOfBanks) {
bank = 0;
}
}
lastBankButton = currentBankButton;
/*
currentDownButton = downdebounce(lastDownButton);
if (lastDownButton == LOW && currentDownButton == HIGH) {
bank--;
for (int ii = 0; ii < numberOfPedal; ii++) {
digitalWrite(presetLEDPin[ii], HIGH); //turn OFF all preset LEDs
digitalWrite(effectLEDPin[ii], HIGH);
}
lcd.clear();
lcd.print(" B-");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Press Any Preset");
if (bank <= 1) {
bank = numberOfBanks + 1;
}
}
lastDownButton = currentDownButton;
*/
currentProgButton = progdebounce(lastProgButton);
if (lastProgButton == LOW && currentProgButton == HIGH) {
progOn = !progOn;
if (progOn == HIGH) {
lcd.clear();
lcd.print("Program Mode:");
lcd.setCursor(0, 1);
lcd.print("Select Loops");
} else {
lcd.clear();
lcd.print(" B-");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Press Any Preset");
if (bank >= numberOfBanks) {
bank = 0;
}
}
}
lastProgButton = currentProgButton;
digitalWrite(progLED, progOn);
digitalWrite(progRelay, progOn);
currentSaveButton = savedebounce(lastSaveButton);
if (lastSaveButton == LOW && currentSaveButton == HIGH) {
saveOn = !saveOn;
if (saveOn == HIGH) {
lcd.clear();
lcd.print("Save Mode:");
lcd.setCursor(0, 1);
lcd.print("Select Preset");
}
}
lastSaveButton = currentSaveButton;
digitalWrite(saveLED, saveOn);
digitalWrite(saveRelay, saveOn);
char key = keypad.getKey();
if (key) // Check for a valid key.
{
switch (key) {
/* Program Mode - Select Loops */
case 'a':
writeOut(0); // relay
break;
case 'b':
writeOut(1);
break;
case 'c':
writeOut(2);
break;
case 'd':
writeOut(3);
break;
case 'e':
writeOut(4);
break;
case 'f':
writeOut(5);
break;
case 'g':
writeOut(6);
break;
case 'h':
writeOut(7);
break;
case 'i':
writeOut(8);
break;
/* Save Mode - Select Preset */
case 'j':
memory((bank * bankVariable), 0); //addr, led
break;
case 'k':
memory(100 + (bank * bankVariable), 1);
break;
case 'l':
memory(200 + (bank * bankVariable), 2);
break;
case 'm':
memory(300 + (bank * bankVariable), 3);
break;
case 'n':
memory(400 + (bank * bankVariable), 4);
break;
case 'o':
memory(500 + (bank * bankVariable), 5);
break;
case 'p':
memory(600 + (bank * bankVariable), 6);
break;
case 'q':
memory(700 + (bank * bankVariable), 7);
break;
case 'r':
memory(800 + (bank * bankVariable), 8);
break;
/* Read Mode - Use the Damn Thing */
case 's':
readPreset((bank * bankVariable), 1, 0); // addr, pcNum, relay
break;
case 't':
readPreset(100 + (bank * bankVariable), 2, 1);
break;
case 'u':
readPreset(200 + (bank * bankVariable), 3, 2);
break;
case 'v':
readPreset(300 + (bank * bankVariable), 4, 3);
break;
case 'w':
readPreset(400 + (bank * bankVariable), 5, 4);
break;
case 'x':
readPreset(500 + (bank * bankVariable), 6, 5);
break;
case 'y':
readPreset(600 + (bank * bankVariable), 7, 6);
break;
case 'z':
readPreset(700 + (bank * bankVariable), 8, 7);
break;
case '$':
readPreset(800 + (bank * bankVariable), 9, 8);
break;
}
}
}
void setupRelays() {
for (int ii = 0; ii < numberOfPedal; ii++) {
//digitalWrite(OneRelayPin[ii], LOW);
//digitalWrite(TenRelayPin[ii], LOW); // they will be, but here explicitly so no one wonders
pinMode(OneRelayPin[ii], OUTPUT);
pinMode(TenRelayPin[ii], OUTPUT);
initRelay(ii, LOW); // HIGH or LOW as desired
}
}
void setupRelays();
// this driver
// gives him a little jolt left to right, or right to left. careful how you fix things, think it out
void switchRelay(int relayNumber, int onOff) {
if (onOff) { // close the contacts current flows 1 to 10
digitalWrite(OneRelayPin[relayNumber], rHot);
digitalWrite(TenRelayPin[relayNumber], rGnd);
} else { // open the contacts
digitalWrite(TenRelayPin[relayNumber], rHot);
digitalWrite(OneRelayPin[relayNumber], rGnd);
}
// if we have additional tell-tale lamps for the relays
// digitalWrite(tellTale[relayNumber], onOff ? HIGH : LOW);
// delay(7); // give peace a chance. implement the "stab" function
//delay(75); // let us see the pulse for now
digitalWrite(OneRelayPin[relayNumber], rGnd);
digitalWrite(TenRelayPin[relayNumber], rGnd); // always return to
}
void initRelay(int relayNumber, int onOff) {
if (onOff) { // close the contacts current flows 1 to 10
digitalWrite(OneRelayPin[relayNumber], rHot);
digitalWrite(TenRelayPin[relayNumber], rGnd);
} else { // open the contacts
digitalWrite(TenRelayPin[relayNumber], rHot);
digitalWrite(OneRelayPin[relayNumber], rGnd);
}
delay(50);
// if we have additional tell-tale lamps for the relays
// digitalWrite(tellTale[relayNumber], onOff ? HIGH : LOW);
// delay(7); // give peace a chance. implement the "stab" function
//delay(500); // let us see the pulse for now
digitalWrite(OneRelayPin[relayNumber], rGnd);
//delay(100);
digitalWrite(TenRelayPin[relayNumber], rGnd); // always return to
//delay(100); // let us see the pulse for now
}