Go Down

Topic: Foot Switch Box for Rocksmith and other Applications (Read 818 times) previous topic - next topic

calli

Mar 07, 2013, 11:54 am Last Edit: Mar 07, 2013, 12:02 pm by calli Reason: 1
Hi,

I got addicted to a music game/learning tool called Rocksmith, here you can connect a real e-guitar and/or a e-bass to your computer and learn and play along rocksongs. I played more guitar in the last months like in the past 30 years.

In this game you can use different effects and amplifiers and also switch between them during a play, however it is not very comfortable and in some songs it is even not possible to let the guitar go to type on the computer keyboard. So I decided that a box with footswitches is needed. Some experimenting later I ordered a Arduino Micro because the Keyboard.h method on normal Arduinos was too wacky. The Micro has the ability like as the Leonardo to act as a USB Host, emulating a keyboard or a mouse.

The hardware consists out of a case, some stripe perfboard, a resistor array for the switches (somehow I don't like the internal ones), two LEDs wits Rs, a Arduino Micro, some buttons, one switch, cables, connectors and hot glue ;-)

Usually the buttons are like this:


ESC     ENTER     Bank Switch (LED dark, see below)
F1      F2           F3


The red Button in in fact a switch and changes the keys to:


ESC     ENTER     Bank Switch (orange LED lit)
LEFT   SPACE      RIGHT


That way you can control the whole game with the box, during play you switch between amps/effects with F1 - F3 (in fact F4 could also be used but no room left here), ESC and ENTER allows you to pause and to resume and also to control most of the gui.  For song select and advanced options you switch to the second bank and so you can controll the whole gui.

The sketch is nothing fancy:

Code: [Select]

/*
Keybox.ino - Footswitch controller box for Arduino with USB Host, like Leonardo and Micro
Copyright (c) 2013 Carsten Wartmann.  All right reserved.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

   Dieses Programm ist Freie Software: Sie können es unter den Bedingungen
   der GNU General Public License, wie von der Free Software Foundation,
   Version 3 der Lizenz oder (nach Ihrer Option) jeder späteren
   veröffentlichten Version, weiterverbreiten und/oder modifizieren.

   Dieses Programm wird in der Hoffnung, dass es nützlich sein wird, aber
   OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
   Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
   Siehe die GNU General Public License für weitere Details.

   Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
   Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>.
*/


// Two LEDs for showing "shift" status and power/ready/keypress
#define SHIFTLED 10  // orange
#define POWERLED 11  // green

#define DEBOUNCE 5  // button debounce interval

// here is where we define the input lines to use
byte buttons[] = {2, 3, 4, 5, 6, 7};
#define NUMBUTTONS sizeof(buttons)
byte pressed[NUMBUTTONS];

boolean hold=false;


void setup() {
 byte i;

 // LEDs
 pinMode(POWERLED,OUTPUT);
 pinMode(SHIFTLED,OUTPUT);

 // Make input & enable pull-up resistors on switch pins
 for (i=0; i< NUMBUTTONS; i++) {
   pinMode(buttons[i], INPUT);
   //    digitalWrite(buttons[i], HIGH); // uncomment to use internal pullups
 }

 delay(1000);
 Keyboard.begin();
}



// check the buttons (summs up to debounce)
void check_switches()
{
 byte index;

 for (index = 0; index < NUMBUTTONS; index++)
 {
   if (digitalRead(buttons[index]) and (pressed[index]<DEBOUNCE))
   {
     pressed[index]++;
   }
   else if (!digitalRead(buttons[index]))
   {
     pressed[index]=0;
   }
 }
}


// sending a key and repeats if needed
void keySend(char key)
{
 digitalWrite(POWERLED, LOW);
 Keyboard.press(key);
 delay(50);
 Keyboard.releaseAll();
 delay(50);
 if (!hold)
 {
   delay(200);
 }
 hold=true;
}



void loop()
{
 digitalWrite(POWERLED, HIGH);

 delay(10);
 check_switches();
 if (pressed[0] >= DEBOUNCE)
 {
   if (!digitalRead(SHIFTLED))
   {
     keySend(KEY_F1); // F1
   }
   else
   {
     keySend(KEY_LEFT_ARROW); // Links      
   }
 }
 else if (pressed[1] >= DEBOUNCE)
 {
   if (!digitalRead(SHIFTLED))
   {
     keySend(KEY_F2);
   }
   else
   {
     keySend(' '); // Space!
   }
 }
 else if (pressed[2] >= DEBOUNCE)
 {
   if (!digitalRead(SHIFTLED))
   {
     keySend(KEY_F3);
   }
   else
   {
     keySend(KEY_RIGHT_ARROW);  
   }  
 }
 else if (pressed[3] >= DEBOUNCE)
 {
   keySend(KEY_ESC);
 }
 else if (pressed[4] >= DEBOUNCE)
 {
   keySend(KEY_RETURN);
 }
 else
 {
   hold=false;
 }

 // "Shift" switch, we use the SHIFTLED to store the status
 // this switches to a second bank of meanings, it is not the keyboard Shift-key!
 if (digitalRead(buttons[NUMBUTTONS-1]))
 {
   digitalWrite(SHIFTLED, HIGH);
 }
 else
 {
   digitalWrite(SHIFTLED, LOW);    
 }
}


Attached some photos. I think all is pretty straight forward but don't hesitate to ask if something is unclear.

Of course this box could be used for other things, like controlling a computer which does not need a complete but sturdy keyboard etc. Also nice for projects with small computers (Raspberry Pi) where you don't want to use GPIO pins for Buttons.

Cheers,
Carsten

Go Up