Well, it's all come down to this: a clone of the FCB1010 based on the Arduino MEGA2560 microcontroller.
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!
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.
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.
Just change void expression to this:
Possibly messing with shift keys.
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.
ReplyDeleteJust a question. Could you not just attach a single 330k resistor to the power line feeding the leds and switches rather than running it through the dil.
ReplyDeleteWow. This is an 8 year old project and I haven't really thought about it in a while. It's good to see people still reading about it and taking an interest.
DeleteI seem to remember having issues with the switches in the FCB1010 being bouncy. That might have something to do with my final design decision on that one.
While the advancement of this project is stalled, the thing is still in use to this day!
I did however have a thought to convert the whole lot of this to I2C to simplify wiring and programming.
Cool. Yeah its brilliant I used it for a while on a bread board. Just wondering if there was a way to simplify wiring as it's a stand alone. Do you still have a layout for the daughter board?
ReplyDeleteI'm wondering to wire the pull up resistors to the pins as they exit the arduino. Or closer to the switch.
I have the week off next week. I'll set some time aside to tear everything apart and get that layout. My drawings have been lost to time. I think it's just making a 16 bit shift register out of 2 8 bit SRs and wiring inputs to them.
Delete