Hi everyone! Now that I have a functional (if imperfect, but still!) relay switching setup for my guitar effects switcher, I've added LCD display and a bank button - both of which work great - but that leaves the programming function - e.g. choosing the effect loops for a preset, and then saving them to a preset. It's currently very clunky to me.
The code uses the keypad library/setup as the basis for reading and storing information. There are 3 columns of inputs - one to read the memory (e.g., use the thing), one to select effect loops for a preset, and one that saves those effect loops to memory.
Currently, this is done with either a 3 way rotary or 2 slide/foot switches. The 3 pins for the columns each read as "IN floating" in the simulator - all of the preset buttons link together and then connect to these pins. The manual switches effectively make it so only one input can be active at a time.
I had a thought to use relays instead of manual switches and control those with a button, but I still feel like that's overkill.
so I guess my question is: I know you can't "turn off" an input - but is there a way to sort of say "on button press, use this input only"? I'm not sure if you can set a pin as OUTPUT, LOW within a function, but that's where my brain is going.
Here's my code:
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Keypad.h>
LiquidCrystal lcd(19, 18, 17, 16, 15, 14);
const int bankButton = A15;
const int progButton = A13;
const int saveButton = A14;
const byte rows = 3;
const byte cols = 3;
char keys[rows][cols] = {
{'a','f','k'},
{'b','g','l'},
{'c','h','m'}
};
byte rowPins[rows] = {2,3,4}; /* 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. */
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
int OneRelayPin[3] = {8,9,10}; /* pin 1 on relay - reset/default has pin 1 at 0v - RED */
int TenRelayPin[3] = {11,12,13}; /* pin 10 on relay - reset/default has pin 10 at 5v - BLUE */
int presetLEDPin[3] = {A0,A1,A2}; /* shows which preset is engaged - GREEN */
int effectLEDPin[3] = {A3,A4,A5}; /* shows which effects are engaged - YELLOW */
const int progRelay = 29;
const int saveRelay = 31;
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 lastProgButton = LOW;
boolean currentProgButton = LOW;
boolean lastSaveButton = LOW;
boolean currentSaveButton = LOW;
/******************************************************/
void setup()
{
lcd.begin (16, 2);
lcd.print("You are a fat");
lcd.setCursor(0, 1);
lcd.print("sausage bitch!");
for(int cc=0; cc<numberOfPedal; cc++) /* setup device */
{
pinMode(OneRelayPin[cc], OUTPUT);
pinMode(TenRelayPin[cc], OUTPUT);
pinMode(presetLEDPin[cc], OUTPUT);
pinMode(effectLEDPin[cc], OUTPUT);
digitalWrite(OneRelayPin[cc], LOW);
digitalWrite(TenRelayPin[cc], LOW);
digitalWrite(presetLEDPin[cc], LOW);
digitalWrite(effectLEDPin[cc], LOW);
delay(100);
}
delay(100);
for(int dd=0; dd<numberOfPedal; dd++)
{
digitalWrite(OneRelayPin[dd], HIGH);
delay(100);
}
delay(100);
for(int ee=0; ee<numberOfPedal; ee++)
{
digitalWrite(TenRelayPin[ee], HIGH);
digitalWrite(presetLEDPin[ee], HIGH);
digitalWrite(effectLEDPin[ee], HIGH);
delay(100);
}
delay(1000);
//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)
// EEPROM.write(i, 0); */
}
/* Bank Button Debounce */
boolean bankdebounce(boolean last) {
boolean current = digitalRead(bankButton);
if (last != current) {
delay(5);
current = digitalRead(bankButton);
}
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 ff=0; ff<numberOfPedal; ff++)
{
EEPROM.write((addr) + ff, digitalRead(effectLEDPin[ff]));
digitalWrite(presetLEDPin[ff], 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);
}
/*********************************************************/
void resetAllRelays()
{
for(int gg=0; gg<numberOfPedal; gg++)
{
digitalWrite(OneRelayPin[gg], HIGH);
digitalWrite(TenRelayPin[gg], LOW);
}
delay(100);
for(int hh=0; hh<numberOfPedal; hh++)
{
digitalWrite(TenRelayPin[hh], HIGH);
}
}
/*********************************************************/
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("Choose Loops: ");
lcd.print(relay + 1);
}
/*********************************************************/
void readPreset(int addr, int pcNum, int led)
{
for(int jj=0; jj<numberOfPedal; jj++)
{
digitalWrite(effectLEDPin[jj], EEPROM.read((addr)+jj));
digitalWrite(presetLEDPin[jj], HIGH);
digitalWrite(presetLEDPin[led], LOW);
if (EEPROM.read((addr)+jj)) {
digitalWrite(OneRelayPin[jj], HIGH);
digitalWrite(TenRelayPin[jj], LOW);
}
else {
digitalWrite(OneRelayPin[jj], LOW);
digitalWrite(TenRelayPin[jj], HIGH);
}
}
lcd.clear();
lcd.print(" B-");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Preset ");
lcd.print(led + 1);
delay(100);
for(int kk=0; kk<numberOfPedal; kk++)
{
digitalWrite(OneRelayPin[kk], HIGH);
digitalWrite(TenRelayPin[kk], HIGH);
}
}
/*********************************************************/
void loop()
{
currentBankButton = bankdebounce(lastBankButton);
if (lastBankButton == LOW && currentBankButton == HIGH) {
bank ++;
for (int zz = 0; zz < numberOfPedal; zz++) {
digitalWrite(presetLEDPin[zz], HIGH); //turn OFF all preset LEDs
digitalWrite(effectLEDPin[zz], 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;
/*
currentProgButton = progdebounce(lastProgButton);
if (lastProgButton == LOW && currentProgButton == HIGH) {
if (progRelay == HIGH) {
digitalWrite(progRelay, LOW);
digitalWrite(progRelay, HIGH);
lcd.clear();
lcd.print("Bank ");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Press Any Preset");
} else if (progRelay == LOW) {
digitalWrite(progRelay, HIGH);
digitalWrite(progRelay, HIGH);
for (int m = 0; m < numberOfPedal; m++) {
digitalWrite(presetLEDPin[m], HIGH);
digitalWrite(effectLEDPin[m], HIGH);
}
lcd.clear();
lcd.print("Current Bank: ");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Choose Loops: ");
// lcd.print(relay + 1);
}
}
lastProgButton = currentProgButton;
currentSaveButton = savedebounce(lastSaveButton);
if (lastSaveButton == LOW && currentSaveButton == HIGH) {
if (saveRelay == HIGH) {
digitalWrite(saveRelay, LOW);
lcd.clear();
lcd.print("Current Bank: ");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Select Preset");
} else if (saveRelay == LOW) {
digitalWrite(saveRelay, HIGH);
for (int n = 0; n < numberOfPedal; n++) {
digitalWrite(ledPin[n], HIGH);
digitalWrite(presetLed[n], HIGH);
}
lcd.clear();
lcd.print("Current Bank: ");
lcd.print(bank);
lcd.setCursor(0, 1);
lcd.print("Choose Loops: ");
// lcd.print(relay + 1);
}
}
lastSaveButton = currentSaveButton;
*/
char key = keypad.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
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;
/****************************** STORE PRESET MODE */
//. case 'q': storePreset((bank * bankVariable), 0);
case 'f': memory((bank * bankVariable), 0); //addr, led
break;
case 'g': memory(100 + (bank * bankVariable), 1);
break;
case 'h': memory(200 + (bank * bankVariable), 2);
break;
case 'i': memory(300 + (bank * bankVariable), 3);
break;
case 'j': memory(400 + (bank * bankVariable), 4);
break;
/****************************** READ PRESET MODE */
case 'k': readPreset((bank * bankVariable), 1, 0); // addr, pcNum, relay
break;
case 'l': readPreset(100 + (bank * bankVariable), 2, 1);
break;
case 'm': readPreset(200 + (bank * bankVariable), 3, 2);
break;
case 'n': readPreset(300 + (bank * bankVariable), 4, 3);
break;
case 'o': readPreset(400 + (bank * bankVariable), 5, 4);
break;
}
}
}
and here's a link to a working version of what I'm thinking: 3-loops-LCD - Wokwi ESP32, STM32, Arduino Simulator (you'll notice I put in the buttons and extra relays, but figured to ask before I went down that path)
You'll see that pins 5, 6 and 7 are the ones that accept information. Any guidance?