Foot pedals
Found under: Settings > Controls > Pedal
OpenSongApp is designed to work with any foot pedal (Bluetooth or USB) that sends key events or midi control messages.
If you wish to use a MIDI device as a foot pedal, you first have to connect the device in the MIDI page and then switch it on in the foot pedal options. If you are not using this option, switch it off as it will override the key event listener that most pedals use.
Most users only have a pedal with two buttons. OpenSongApp allows you to use these pedals to simulate up to six options. This is done by allowing next / previous pedals to also scroll before changing songs. This makes a two pedal function like a four pedal set up (scroll up, scroll down, previous song, next song). By also allowing additional long press commands (key event only, not MIDI), you can also assign two additional functions to your pedals taking them to a six pedal set up!
If you find that long press actions are not working for your pedal, you can switch on 'AirTurn mode'. This changes the way long presses are detected by using a timer. This is common for AirTurn branded pedals and any pedals made using Arduino or ESP32 boards.
Unlike many apps that limit you to standard set ups, or certain pedal boards, OpenSongApp allows you to freely customise pedals with up to 8 buttons (along with long press and scroll before turn gives you up to 18 commands!).
The commands available can be viewed on the Available commands page.
To customise the pedal actions for your foot pedal, connect it using Android's default method (either plug it in if it is USB, or pair as a Bluetooth device). If this is a MIDI pedal, remember to connect it to the app first using the MIDI page, then switch on the 'Listen for incoming MIDI' button in the pedal settings page.
Scroll to the pedal 1 and click on the button (by default it will be set to KEYCODE_DPAD_LEFT and MIDI note C3). It will then say 'Waiting for button'. Tap the desired button on your foot pedal and it will be assigned as pedal 1. Choose a short press/tap action and an additional long press action. Repeat this process for each button on your foot pedal.
If you use a 2 pedal controller, I'd recommend setting the left button short press command to "Previous" and the right button short press command to "Next". You should also switch on the "Try to scroll before move" option.
If you are worried about accidentally moving to the next song when trying to scroll to the bottom, you can switch on the "Show warning" option. This displays a warning prompt before moving to the next song and requires you to press the button again within 2 seconds. If you do this, you get 10 seconds grace time (to allow skipping songs) before the warning is reactivated.
Known Working Pedals (there will be more)
Any pedal made from a USB/Bluetooth keyboard
Any pedal made using an Arduino, ESP32 or BlueFruit board (sometimes requires AirTurn mode for long press actions)
Most AirTurn pedals (you will likely need to switch on AirTurn mode for long press actions). AirTurn Ped Pro works, but not particularly responsive on some surfaces and can be slow to detect presses according to some users
Lekato / M-VAVE / CuVave wireless foot pedal (some versions require switching the pedal to iOS mode or mode 2 to send key events). Unsure if long press action is detected
Donner Wireless Turner
Coda wireless turner and Coda stomp
If you have any information on working/not working foot pedals, please let us know via the forum thread.
Making a Bluetooth foot pedal
If you fancy having a go at making a Bluetooth foot pedal, you can do this without spending too much money. It's also a relatively straightforward project if you know how to use a soldering iron and can follow simple instructions and wiring diagrams!
Unfortunately the Bluetooth board I originally used (AdaFruit EZ-Key) is not currently available, but thanks to our amazing community Leo gave me some tips to build an alternative using a ESP32 WiFi/Bluetooth development board. It's also a lot cheaper. I've since rewritten the code and changed the set up slightly.
Equipment you will need (I've included links to suppliers I've used so you can see what the bits look like):
Hammond enclosure - the size required will depend on how many buttons you plan on adding and if you are including a battery, etc. I'd recommend a minimum height of 3cm. Metal enclosures are sturdier than plastic ones, but will likely reduce the Bluetooth range to a few metres (I still use a metal case).
Some SPST switches (one for each foot switch button you need)
ESP32 WiFi/Bluetooth development board (approx £6/€8)
Female-Female Dupont Wires / Jumper Wires (approx £1 / €1.50) - you can use simple cable wire, but these reduce the risk to your board and allow quick connect/disconnect
LEDs, resistors, and mounts (about £1/€1) total . Use this website to help you calculate the best resistor size to use depending on your input voltage and led voltage, however, most LEDs will cope with a resistor between 200 Ohms and 1k Ohms. The Vf (forward voltage) of the LED should be approx 3.3-3.5V meaning it should have a minimum working voltage of about 2.7V. The ESP32 board supplies a voltage of 3.3V. You'll need two of each LED, resistor and mount.
Heat shrink tube or electrical tape and some foam or an old sponge to safely mount the board in the hammond enclosure to avoid shorts.
Solder iron, solder and cold running water for when you burn yourself...
ESP32 development board
Download the free Arduino IDE software for your PC/Mac operating system and boot it up
Follow the instructions on this webpage to make sure you can use the ESP32 board properly in Arduino: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
Go to the Sketch menu and select Include Library. Look for the library name ESP32 BLE Keyboard. If it is already there, great, but if not you can manually download it as a zip file from the developer's GitHub repository BLE Keyboard library (0.3.2 beta) and install it using the Add ZIP Library... option from the same menu.
Either download and open the GarethBluetoothPageFlip.ino file into Arduino, or copy and paste in the code further down the page. This code is for a 5 pedal setup and will work fine if you only want to use 2 pedals. You can also adapt the code if you want to add more pedals - you should be able to follow the code!
Plug in your ESP32 board to your PC using a USB cable and select the appropriate Board from the menu in Arduino. These should be recognised automatically if you've followed the steps above. Click on the upload button to load the code from my file in Arduino into your ESP32 board. Unplug the board once done and proceed with the pedal construction!
A simple circuit diagram is shown below for my 5 button pedal setup. By default you power the pedal via the USB port (cut a hole in the side of the hammond enclosure for the USB port and use a glue gun to attach the board in place, making sure you avoid shorting the board if using a metal case, with the USB port in the hole).
The ESP32 should not be powered by a 9V guitar power supply unless you take steps to reduce this voltage first using a 9V to 5V step down voltage circuit inline. Running without this could cause the ESP32 board to overheat as it tries to regulate the excess voltage by converting to heat.
I later added a rechargeable 3.7V Li-Po battery along with a charging circuit and voltage booster circuit to convert to a stable 5V output. I then positioned the USB input for the charging circuit into the hole in the hammond enclosure and also added an on/off switch inline with the battery output from the charge circuit and the boost circuit input (battery should not be charged and discharged simultaneously). Alternatively, use a cheap USB power bank to plug in and power your pedal.
The code in GarethBluetoothPageFlip.ino file
#include <BleKeyboard.h>
// Set up the pin numbers for the buttons
const int pinButton1 = 12;
const int pinButton2 = 14;
const int pinButton3 = 27;
const int pinButton4 = 26;
const int pinButton5 = 25;
// Set up the pin numbers for the LEDs
// const int pinLEDOnboard = 36;
const int pinLEDPress = 33;
const int pinLEDConnected = 32;
// Because we connect to GND we use reverse HIGH/LOW logic
// HIGH = off, LOW = on
// Set up the pin states (track changes)
int button1State = HIGH;
int button2State = HIGH;
int button3State = HIGH;
int button4State = HIGH;
int button5State = HIGH;
int connectedLEDState = HIGH;
int pressedLEDState = HIGH;
// Variables for blinking the Bluetooth LED
// The last time LED was updated
unsigned long previousMillis = 0;
// Interval at which to blink (milliseconds)
const long notconnectedInterval = 200;
const long connectedInterval = 1000;
// First param is name
// Second is manufacturer
// Third is initial battery level
BleKeyboard bleKeyboard("PageFlip", "OpenSongApp", 100);
void setup() {
Serial.begin(115200);
//pinMode(pinLEDOnboard, OUTPUT);
pinMode(pinLEDPress,OUTPUT);
pinMode(pinLEDConnected,OUTPUT);
pinMode(pinButton1,INPUT_PULLUP);
pinMode(pinButton2,INPUT_PULLUP);
pinMode(pinButton3,INPUT_PULLUP);
pinMode(pinButton4,INPUT_PULLUP);
pinMode(pinButton5,INPUT_PULLUP);
digitalWrite(pinLEDPress,pressedLEDState);
digitalWrite(pinLEDConnected,connectedLEDState);
bleKeyboard.begin();
}
void loop() {
// Check the key press state
int new_button1State = digitalRead(pinButton1);
int new_button2State = digitalRead(pinButton2);
int new_button3State = digitalRead(pinButton3);
int new_button4State = digitalRead(pinButton4);
int new_button5State = digitalRead(pinButton5);
boolean ispressed1 = (new_button1State == LOW);
boolean ispressed2 = (new_button2State == LOW);
boolean ispressed3 = (new_button3State == LOW);
boolean ispressed4 = (new_button4State == LOW);
boolean ispressed5 = (new_button5State == LOW);
// If we have pressed a button, light the LED, otherwise turn it off)
triggerPressLED(ispressed1 || ispressed2 ||
ispressed3 || ispressed4 || ispressed5);
if (button1State != new_button1State) {
// We have changed the button state, so need to do something
button1State = new_button1State;
if (new_button1State == LOW) {
// We have pressed the first button (left arrow)
Serial.print("\nButton1 pressed");
sendKey(KEY_LEFT_ARROW,true);
} else {
Serial.print("\nButton1 released");
sendKey(KEY_LEFT_ARROW,false);
}
}
if (button2State != new_button2State) {
// We have changed the button state, so need to do something
button2State = new_button2State;
if (new_button2State == LOW) {
// We have pressed the second button (right arrow)
Serial.print("\nButton2 pressed");
sendKey(KEY_RIGHT_ARROW,true);
} else {
Serial.print("\nButton2 released");
sendKey(KEY_RIGHT_ARROW,false);
}
}
if (button3State != new_button3State) {
// We have changed the button state, so need to do something
button3State = new_button3State;
if (new_button3State == LOW) {
// We have pressed the third button (up arrow)
Serial.print("\nButton3 pressed");
sendKey(KEY_UP_ARROW,true);
} else {
Serial.print("\nButton3 released");
sendKey(KEY_UP_ARROW,false);
}
}
if (button4State != new_button4State) {
// We have changed the button state, so need to do something
button4State = new_button4State;
if (new_button4State == LOW) {
// We have pressed the fourth button (down arrow)
Serial.print("\nButton4 pressed");
sendKey(KEY_DOWN_ARROW,true);
} else {
Serial.print("\nButton4 released");
sendKey(KEY_DOWN_ARROW,false);
}
}
if (button5State != new_button5State) {
// We have changed the button state, so need to do something
button5State = new_button5State;
if (new_button5State == LOW) {
// We have pressed the fifth button (home)
Serial.print("\nButton5 pressed");
sendKey(KEY_HOME,true);
} else {
Serial.print("\nButton5 released");
sendKey(KEY_HOME,false);
}
}
connectedLEDPulse();
// Allow for flickering on/off as connection is made
delay(50);
}
void connectedLEDPulse() {
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
int interval;
if (bleKeyboard.isConnected()) {
interval = connectedInterval;
} else {
interval = notconnectedInterval;
}
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (connectedLEDState == LOW) {
connectedLEDState = HIGH;
} else {
connectedLEDState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(pinLEDConnected, connectedLEDState);
}
}
void triggerPressLED(boolean ispressed) {
pressedLEDState = ispressed;
if (ispressed) {
digitalWrite(pinLEDPress,HIGH);
} else {
digitalWrite(pinLEDPress,LOW);
}
}
void sendKey(int keyCode, boolean keyDown) {
// Only try to send the command if we are connected
if (bleKeyboard.isConnected()) {
if (keyDown) {
bleKeyboard.press(keyCode);
} else {
bleKeyboard.release(keyCode);
}
}
}
Some other user submitted pedals: