I got the MEGA2560 in the mail the other day and it is a real pain to use at first. NewSoftSerial.h is a necessary include. On a side note: I would like to thank Arduino for NOT pointing that out anywhere in the documentation and let me assume my brand new microcontroller was bricked for about 3 hours. Jeeze!
Hardware
Before hooking everything up, I had to first do some soldering. Well, not some. A ton. Everything hooked to the resistor packs in the image of my hardware setup below had to be hooked into a daughter board.And here is the finished daughter board.
Top
Bottom
And here is the Arduino with everything hooked up to it and everything being insulated/held-on by good old-fashioned electrical tape.
I opted for pin/ribbon cable connections between the boards to avoid any spaghetti wiring. It keeps everything organized and neat. And I think it looks cool.
Software
OK so I'm not an experienced electronics engineer or claim to know very much about the topic. As such, I wasn't sure which switch went to which digital pin after I soldered them all in. So I wrote some code to easily tell me. I knew the input pins were 22-33 so I wrote this code, uploaded, opened the serial monitor and started pressing buttons on the footswitch boards.
#include <NewSoftSerial.h>
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(digitalRead(22) == LOW){
Serial.println("22 pressed.");
}
if(digitalRead(23) == LOW){
Serial.println("23 pressed.");
}
if(digitalRead(24) == LOW){
Serial.println("24 pressed.");
}
if(digitalRead(25) == LOW){
Serial.println("25 pressed.");
}
if(digitalRead(26) == LOW){
Serial.println("26 pressed.");
}
if(digitalRead(27) == LOW){
Serial.println("27 pressed.");
}
if(digitalRead(28) == LOW){
Serial.println("28 pressed.");
}
if(digitalRead(29) == LOW){
Serial.println("29 pressed.");
}
if(digitalRead(30) == LOW){
Serial.println("30 pressed.");
}
if(digitalRead(31) == LOW){
Serial.println("31 pressed.");
}
if(digitalRead(32) == LOW){
Serial.println("32 pressed.");
}
if(digitalRead(33) == LOW){
Serial.println("33 pressed.");
}
}
That step was quick. Figuring out the LED pins was a trail and error test that took a while longer.
The next step was to marry the test effect change code with the wah/volume code. This was no easy task and took hours of troubleshooting with a sniper rifle to get it right. Here is the final functional code to produce a clone of the FCB1010.
#include <NewSoftSerial.h>
int bank = 0x00;//Default bank of 0
int number_in_bank = 0x0A;//10 effects per bank
const int volume_pin = 0;// Pot connected to analog pin 0
const int wah_pin = 1;// Pot connected to analog pin 1
const int pot_threshold = 7;// Threshold amount to guard against false values
const int midi_channel = 0;
void setup() {
for(int i = 34; i <= 43; i++)//Set up the LED pins and make them float high right off the bat
{
pinMode(i, OUTPUT);
digitalWrite(i, HIGH);
}
Serial.begin(31250);// Set MIDI baud rate:
changeProgram(0x00,43);//Homed to program 1
}
void loop() {
///////////
//EFFECTS//
///////////
//
//Lower Button Bank
//
//Button 1
if(digitalRead(23) == LOW)
{
changeProgram(0x00,43);
}
//Button 2
if(digitalRead(25) == LOW)
{
changeProgram(0x01,41);
}
//Button 3
if(digitalRead(29) == LOW)
{
changeProgram(0x02,39);
}
//Button 4
if(digitalRead(27) == LOW)
{
changeProgram(0x03,37);
}
//Button 5
else if(digitalRead(33) == LOW)
{
changeProgram(0x04,35);
}
//Bank Down
else if(digitalRead(31) == LOW)
{
if(bank != 0x01)
{
bank -= number_in_bank;
changeProgram(0x00,43);
delay(250);
}
}
//
//Upper Bank
//
//Button 6
else if(digitalRead(22) == LOW)
{
changeProgram(0x05,42);
}
//Button 7
else if(digitalRead(24) == LOW)
{
changeProgram(0x06,40);
}
//Button 8
else if(digitalRead(26) == LOW)
{
changeProgram(0x07,38);
}
//Button 9
else if(digitalRead(28) == LOW)
{
changeProgram(0x08,36);
}
//Button 10 (0)
else if(digitalRead(30) == LOW)
{
changeProgram(0x09,34);
}
//Bank Up
else if(digitalRead(32) == LOW)
{
if(bank != 0x19)
{
bank += number_in_bank;
changeProgram(0x00,43);
delay(250);
}
}
//////////
//VOLUME//
//////////
expression(volume_pin);
///////
//WAH//
///////
expression(wah_pin);
}
void changeProgram(int effect_number, int LED) {
int program = bank + effect_number;//Program 1 would be bank(0)+effect_button(0) so 0x00 with 10 effects in the bank
Serial.print(0xC0, BYTE);//Program Change
Serial.print(program, BYTE);
digitalWrite(LED,LOW); //Light the associated LED
for(int i =34; i <= 43; i++)//Turn off all the rest of the LEDs
{
if(i != LED)
{
digitalWrite(i, HIGH);
}
}
delay(250);//Some debounce
}
void changeVolume(byte channel, byte volume)
{
Serial.print(0xB0 | (channel & 0x0F), BYTE); //Control Change
Serial.print(0x07, BYTE);//Volume CC number
Serial.print(volume & 0x7F, BYTE);//Volume level (0-127)
}
void wahCharacter(byte channel, byte wah)
{
Serial.print(0xB0 | (channel & 0x0F), BYTE);//Control Change
Serial.print(0x1B, BYTE);//Wah character CC number
Serial.print(wah & 0x7F, BYTE);//Wah tone character (0-127)
}
void expression(int pin)
{
static int s_nLastPotValue = 0;
static int s_nLastMappedValue = 0;
int nCurrentPotValue = analogRead(pin);
if(abs(nCurrentPotValue - s_nLastPotValue) < pot_threshold)
return;
s_nLastPotValue = nCurrentPotValue;
int nMappedValue = map(nCurrentPotValue, 0, 1023, 0, 127); // Map the value to 0-127
if(nMappedValue == s_nLastMappedValue)
return;
s_nLastMappedValue = nMappedValue;
if(nMappedValue >= 15){
if (pin == volume_pin)
{
changeVolume(midi_channel, nMappedValue);
}
else
{
wahCharacter(midi_channel, nMappedValue);
}
}
}
Extra
While messing with the code, I discovered that you can run 2 wah pedals off of the same controller. The effects processor takes the setpoints from both of the expression pedals and bounces in between them. It sounds like this [link]
void expression(int pin)
{
static int s_nLastPotValue = 0;
static int s_nLastMappedValue = 0;
int nCurrentPotValue = analogRead(pin);
if(abs(nCurrentPotValue - s_nLastPotValue) < pot_threshold)
return;
s_nLastPotValue = nCurrentPotValue;
int nMappedValue = map(nCurrentPotValue, 0, 1023, 0, 127); // Map the value to 0-127
if(nMappedValue == s_nLastMappedValue)
return;
s_nLastMappedValue = nMappedValue;
if(nMappedValue >= 15){
wahCharacter(midi_channel, nMappedValue);
}
}Still to Come
I have an LCD display on the way. This should be fun.Possibly messing with shift keys.

Keeps getting better and better
ReplyDeletevery good read! i also playing around with the code but the threshold method will not work. i have a permanent midi stream. im just about to have 2 pedals.
ReplyDelete