6 switches
accessing 6 patches directly
USB midi connection between zoom and patch changer
USB power supply (It's a risk, because power and midi connectors are the same type USB :)
Using Arduino Uno and USB host shield
Works with Korg Pandora Stomp as well.
USB ports
The code:
Should be cleaned up, but I have no time for that:)
#include <Usb.h>
#include <usbh_midi.h>
#define ledpin 14
int buttonState = 0; // variable for reading the pushbutton status
int ledlight = 0;
int mode = 1;
int pushedbutton = 41;
unsigned long t1 = 0; // timer for usb keeping on
unsigned long t2 = 0; // timer for midi change
unsigned long t3 = 0; // timer for led turn off after change
unsigned long t4 = 0; //timer for mode change
USB Usb;
USBH_MIDI Midi(&Usb);
byte data;
void setup()
{
// start the library
// Serial.begin(9600);
Usb.Init();
data = 1;
SendMIDI(0);
pinMode(ledpin, OUTPUT);
for (int i = 0; i < 4; i++) { // flash led for indicating arduino start
digitalWrite(ledpin, HIGH);
delay(300);
digitalWrite(ledpin, LOW);
delay(200);
}
// Setup Switches, pull up because of floating
for (int i = 2; i < 8; i++) {
pinMode(i, INPUT_PULLUP);
}
}
void loop()
{
// read the state of the pushbutton value:
if (millis() > t1 + 1000) { // keeping the usb state active, this way the change will happen
Usb.Task(); // immediatley after button push, so we're sending usb initiate every 1 sec.
t1 = millis();
}
if (millis() > t3 + 100 && ledlight == 1) { // turn off led after midi change, iff 100 ms has passed.
digitalWrite(ledpin, LOW);
ledlight = 0;
}
for (int i = 41; i < 47; i++) { // checking momentary pushbutton state, in Zoom the patches are from patch 41 to 46.
buttonState = digitalRead(i - 39); // but the switches are from 2 to 7.
if (buttonState == LOW && millis() > t2 + 500) { //accept push only if 500ms has past since last push
if (i == pushedbutton && millis() < t2 + 800 && millis() > t4 + 2000) { // mode change if pushed button is the same as before and longpush and enough time has been passed since last mode change
for (int j = 0; j < 4; j++) { //flashing the led to indicate mode change
digitalWrite(ledpin, HIGH);
delay(100);
digitalWrite(ledpin, LOW);
delay(100);
}
if (mode == 1) { //mode change to 2 if it was 1, else to 1.
mode = 2;
}
else {
mode = 1;
}
t4 = millis(); //mode change starts timer, not being able to start new action too soon
}
if (millis() > t4 + 1000) { //make midi change only if enough time has passed since mode change
if (mode == 2) { // if in mode 2, make relative change
switch (i) {
case 41:
data = data - 1;
if (data < 1) {
data = 50;
}
break;
case 44:
data = data + 1;
if (data > 50) {
data = 1;
}
break;
case 42:
data = data - 5;
if (data < 1) {
data = data + 50;
}
break;
case 45:
data = data + 5;
if (data > 50) {
data = data - 50;
}
break;
case 43:
data = data - 10;
if (data < 1) {
data = data + 50;
}
break;
case 46:
data = data + 10;
if (data > 50) {
data = data - 50;
}
}
}
else { // if not in mode 2, make simple change to absolute value
data = i;
}
SendMIDI(data);
t2 = millis();
pushedbutton = i;
}
}
}
}
// Send "Program Change" MIDI Message
void SendMIDI(byte number)
{
//Serial.println("called");
// Serial.println(callcount);
number -= 1; // Change 1 to 0, 100 to 99.
t1 = millis();
Usb.Task();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )
{
byte Message[2]; // Construct the midi message (2 bytes)
Message[0] = 0xC0; // 0xC0 is for Program Change (Change to MIDI channel 0)
Message[1] = number; // Number is the program/patch (Only 0 to 99 is valid for ZOOM G3)
Midi.SendData(Message, 0); // Send the message
digitalWrite(ledpin, HIGH); // light led on
ledlight = 1;
t3 = millis();
delay(10);
//digitalWrite(ledpin, LOW);
//Serial.println("sent");
}
}