Homemade MIDI controller Success!
Posted: Tue Mar 20, 2012 3:13 pm
So, I've successfully been able to hook up my Arduino to my Vyper 15W and send MIDI commands. So far, I've managed to be able to control the volume, wah, presets, and looper function.
I've got this all set out on a breadboard right now for prototyping, but I've just ordered out for some parts so I can put this together properly. Right now that ugly cable you see coming from the back of the amp is wired directly into the MIDI header holes on the DSP board. The black linear potentiometer is controlling the volume (read on an analog input on the arduino).. The two pushbuttons are currently controlling the Looper Record/Play and Stop/Erase.
Anyways, I've ordered some nice pushbuttons and an LCD. Also ordered a couple MIDI jacks. I have something that I can use as the enclosure. Once I have it all put together and working I'll post a writeup with pictures.
Picture of the current hideous setup attached.
Here's the current Arduino code, if anyone's interested.
I've got this all set out on a breadboard right now for prototyping, but I've just ordered out for some parts so I can put this together properly. Right now that ugly cable you see coming from the back of the amp is wired directly into the MIDI header holes on the DSP board. The black linear potentiometer is controlling the volume (read on an analog input on the arduino).. The two pushbuttons are currently controlling the Looper Record/Play and Stop/Erase.
Anyways, I've ordered some nice pushbuttons and an LCD. Also ordered a couple MIDI jacks. I have something that I can use as the enclosure. Once I have it all put together and working I'll post a writeup with pictures.
Picture of the current hideous setup attached.
Here's the current Arduino code, if anyone's interested.
Code: Select all
/*
VipryPedyl
This sketch sends MIDI commands to the Peavey Vypyr AMP
created 29 Mar 2012
*/
#include <LiquidCrystal.h>
#include <EEPROM.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
int sensorValue = 0;
int ledPin = 13;
int Volume = 0;
byte R_ARR = 0x7E;
byte L_ARR = 0x7F;
byte BLOCK = 0xFF;
enum e_mode { preset, looper, volume, wah, pregain, bass, mid, high, postgain, NumberOfModes };
char* s_mode[NumberOfModes] = { "Preset", "Looper", "Volume", "Wah", "PreGain", "Bass", "Mid", "High", "PostGain" };
char* s_abbr[NumberOfModes] = { "Pre", "Looper", "Vol", "Wah", "PrG", "Bas", "Mid", "Hi ", "PsG" };
int b_mode[2] = { preset, preset };
int b_pins[2] = { 8, 9 }; //Pins the buttons are on
int b_vals[2] = { 0, 0 }; //Paramtere values when buttons are pressed
void setup() {
Serial.begin(31250);
lcd.begin(8, 2);
lcd.setCursor(0, 0);
lcd.print("VYPYR-");
lcd.setCursor(0, 1);
lcd.print(" PEDYL");
delay(3000);
pinMode(8, INPUT);
pinMode(9, INPUT);
getSettings();
}
void getSettings() {
b_mode[0] = EEPROM.read(0);
if (b_mode[0]>NumberOfModes) b_mode[0]=preset;
b_mode[1] = EEPROM.read(1);
if (b_mode[1]>NumberOfModes) b_mode[1]=preset;
b_vals[0] = EEPROM.read(2);
if (b_vals[0] > 127) b_vals[0]=1;
b_vals[1] = EEPROM.read(3);
if (b_vals[1] > 127) b_vals[1]=2;
}
void saveSettings() {
EEPROM.write(0, b_mode[0]);
EEPROM.write(1, b_mode[1]);
EEPROM.write(2, b_vals[0]);
EEPROM.write(3, b_vals[1]);
}
void loop() {
buttonClear();
printHome();
int b = getButton();
if (b>0) {
b--;
if ((b_mode[0]==looper)||(b_mode[1]==looper))
{
//Looper stuff
switch(b) {
case 0: //Button 1 Short Press
noteOn(0); //PLAY WORKS
noteOff(0); //PLAY WORKS
break;
case 1: //Button 2 Short Press
noteOn(2); //STOP
noteOff(2); //STOP
break;
case 2: //Button 1 Long Press
noteOn(0); //RECORD WORKS
noteOff(0); //RECORD WORKS
break;
case 3: //Button 2 Long Press
noteOn(2); //ERASE WORKS
break;
}
}
else
{
lcd.setCursor(1,b);
lcd.print(R_ARR);
switch(b_mode[b]) {
case preset:
patch(b_vals[b]-1);
break;
case wah:
controller(6, b_vals[b]);
break;
case volume:
controller(7, b_vals[b]);
break;
case pregain:
controller(16, b_vals[b]);
break;
case bass:
controller(17, b_vals[b]);
break;
case mid:
controller(18, b_vals[b]);
break;
case high:
controller(19, b_vals[b]);
break;
case postgain:
controller(22, b_vals[b]);
break;
}
}
buttonClear();
}
else if (b==0)
{
//Mode Selection Menu
lcd.clear(); lcd.print(BLOCK); lcd.print("SELECT"); lcd.print(BLOCK); lcd.setCursor(0,1); lcd.print(BLOCK); lcd.print("BUTTON"); lcd.print(BLOCK);
buttonClear();
int btn = getButton();
if (btn>0) {
lcd.clear(); lcd.print(L_ARR); lcd.print(btn); lcd.print(" MODE"); lcd.print(R_ARR);
btn--;
printMode(b_mode[btn]);
buttonClear();
while(1) {
b = getButton();
if (b==1) { if (b_mode[btn]==0) b_mode[btn]=NumberOfModes-1; else b_mode[btn]--; }
else if (b==2) { if (b_mode[btn]==NumberOfModes-1) b_mode[btn]=0; else b_mode[btn]++; }
else { break; }
printMode(b_mode[btn]);
}
buttonClear();
lcd.clear();
switch(b_mode[btn])
{
case preset:
lcd.print(s_mode[b_mode[btn]]);
b_vals[btn] = getNumberValue(1, 12, b_vals[btn]);
break;
case volume: case wah: case pregain: case bass: case mid: case high: case postgain:
lcd.print(s_mode[b_mode[btn]]);
b_vals[btn] = getNumberValue(0, 127, b_vals[btn]);
break;
case looper:
lcd.print("*LOOPER*");
lcd.setCursor(0,1);
lcd.print("**MODE**");
delay(4000);
break;
}
saveSettings();
buttonClear();
}
}
delay(100);
}
int getNumberValue(int mn, int mx, int df)
{
int val = df; int b;
if (val < mn) val = mn;
if (val > mx) val = mx;
lcd.setCursor(0,1);
lcd.print(L_ARR);
lcd.setCursor(7,1);
lcd.print(R_ARR);
while(1) {
lcd.setCursor(3,1); lcd.print(" ");
lcd.setCursor(3,1); lcd.print(val);
b = getButton();
if (b==1) { if (val==mn) val=mx; else val--; }
else if (b==2) { if (val==mx) val=mn; else val++; }
else { break; }
}
return val;
}
void printMode(int mode) {
lcd.setCursor(0,1); lcd.print(" ");
lcd.setCursor(0,1); lcd.print(s_mode[mode]);
}
void printHome() {
lcd.clear();
if ((b_mode[0]==looper)||(b_mode[1]==looper))
{
//looper mode
//(both buttons are needed for looper mode)
lcd.print("1"); lcd.print("PLY/REC");
lcd.setCursor(0,1);
lcd.print("2"); lcd.print("STP/ERS");
}
else
{
//normal modes
lcd.print("1:"); lcd.print(s_abbr[b_mode[0]]);
lcd.setCursor(5+numCharLen(b_vals[0]),0); lcd.print(b_vals[0]);
lcd.setCursor(0,1);
lcd.print("2:"); lcd.print(s_abbr[b_mode[1]]);
lcd.setCursor(5+numCharLen(b_vals[1]),1); lcd.print(b_vals[1]);
}
}
int numCharLen(int val) {
if (val<10)
return 2;
else if (val<100)
return 1;
else
return 0;
}
int getButton() {
//Waits for a button push.. 1, 2, 0 (both)
//3, 4 for looper mode long button press
boolean longpress=true;
while(1)
{
for(int b=0;b<=1;b++) {
if (getButtonPin(b,false))
{
//debounce and make sure B2 isn't pressed while in wait
for(int i=0;i<40;i++)
{
lcd.setCursor(0,1);
delay(10);
if (getButtonPin(b,false)) {
if (getButtonPin(b,true))
return 0;
}
else
{
longpress=false;
break;
}
}
if (longpress && ((b_mode[0]==looper)||(b_mode[1]==looper)))
return b+3;
else
return b+1;
}
}
}
}
int getButtonPin(int btn, boolean opposite) {
if (opposite) { if (btn==1) btn=0; else btn=1; }
return digitalRead(b_pins[btn]);
}
void buttonClear() {
//waits for all buttons to be cleared
while(digitalRead(8) || digitalRead(9)) { }
delay(10);
}
//MIDI COMMANDS
void patch(int instrument) {
Serial.print(0xC0, BYTE);
Serial.print(instrument, BYTE);
}
void controller(int controller, int value) {
Serial.print(0xB0, BYTE);
Serial.print(controller, BYTE);
Serial.print(value, BYTE);
}
void noteOn(int key) {
Serial.print(0x90, BYTE);
Serial.print(key, BYTE);
Serial.print(0x7F, BYTE);
}
void noteOff(int key) {
Serial.print(0x90, BYTE);
Serial.print(key, BYTE);
Serial.print(0x00, BYTE);
}