Author Topic: Arduino MIDI Switcher  (Read 28634 times)

EeroN

Re: Arduino MIDI Switcher
« Reply #40 on: July 27, 2018, 05:24:45 AM »
potul,

Thank you for sharing your instructions here. I just recently completed a three channel tube preamp with a graphic EQ assignable to each channel (Mesa style). I built a temporary footswitch for it, but eventually wanted to have MIDI control. I took your basic circuit and code, and after some tweaking I got it working.

Eventually, I will control five features of my preamp with the controller: CH1 CH2 or CH3, EQ on/off, reverb on/off (CH1 only). I have alredy implemented these in the code, I just have some wiring to do.

I'm running the controller with 12 V from my preamp, as that's the voltage my relays work at. Relay switching in the preamp is controlled by a CMOS Quad fliflop. The Arduino is controlling transistors, which again pull the corresponding logic pins of the fliflop high for channel changes.

Here's a quick video:

https://www.youtube.com/watch?v=-dw1Pc2Kgns

I'll put it in a Hammond enclosure on my pedalboard, where I'll send program changes from a Boss MS-3.

If anyone wants to see the code or has any other questions, I'll happily answer them.

Thanks again potul and all who have contribted to this thread.
« Last Edit: July 27, 2018, 05:31:19 AM by EeroN »

potul

Re: Arduino MIDI Switcher
« Reply #41 on: July 27, 2018, 06:33:56 AM »
Great!

Happy to see my work is an inspiration for others.

Mat

bogdancat

Re: Arduino MIDI Switcher
« Reply #42 on: December 11, 2018, 01:07:53 AM »
potul,

Thank you for sharing your instructions here. I just recently completed a three channel tube preamp with a graphic EQ assignable to each channel (Mesa style). I built a temporary footswitch for it, but eventually wanted to have MIDI control. I took your basic circuit and code, and after some tweaking I got it working.

Eventually, I will control five features of my preamp with the controller: CH1 CH2 or CH3, EQ on/off, reverb on/off (CH1 only). I have alredy implemented these in the code, I just have some wiring to do.

I'm running the controller with 12 V from my preamp, as that's the voltage my relays work at. Relay switching in the preamp is controlled by a CMOS Quad fliflop. The Arduino is controlling transistors, which again pull the corresponding logic pins of the fliflop high for channel changes.

Here's a quick video:

https://www.youtube.com/watch?v=-dw1Pc2Kgns

I'll put it in a Hammond enclosure on my pedalboard, where I'll send program changes from a Boss MS-3.

If anyone wants to see the code or has any other questions, I'll happily answer them.

Thanks again potul and all who have contribted to this thread.

Please post the code for your switch. I'm looking to make a similar one for an Ibanez amp.

EeroN

Re: Arduino MIDI Switcher
« Reply #43 on: December 21, 2018, 10:57:54 AM »
Sorry, I just now checked back on this thread. Here's my code:

Code: [Select]
#include <OneButton.h>
#include <EEPROM.h>
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
#define RLY1 11 //set pin for Relay1
#define RLY2 10 //set pin for Relay2
#define RLY3 9  //set pin for Relay3
#define RLY4 8  //set pin for Relay4
#define REVC 7  //set pin for Reverb control (jfet)
#define SW1 12  //set pin for button
MIDI_CREATE_DEFAULT_INSTANCE();

byte curr_program;  //current PC value
byte state;     //current state

byte n = 1;     //these are for cycling states
byte neq = 0;

unsigned long startMillis; //for getting relays to activate simultaneously
unsigned long currentMillis;
const unsigned long period = 50; //set delay for RLY4

bool eq;
bool ch1;
bool ch2;
bool ch3;
bool rev;

// Setup a new OneButton on pin 11.
OneButton button1(SW1, true);

// -----------------------------------------------------------------------------
// This function will be automatically called when a NoteOn is received.
// It must be a void-returning function with the correct parameters,
// see documentation here:
// http://arduinomidilib.fortyseveneffects.com/a00022.html
void handleNoteOn(byte channel, byte pitch, byte velocity)
{
  // Do whatever you want when a note is pressed.
  // Try to keep your callbacks short (no delays ect)
  // otherwise it would slow down the loop() and have a bad impact
  // on real-time performance.
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
  // Do something when the note is released.
  // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
}

void handleProgramChange(byte channel, byte number)
{
  //do something when receiving PC messages
  byte value;
  curr_program = number; //stores the PC number for later
  //read preset value from EEPROM
  value = EEPROM.read(number);

  if (getBit(value, 1))
  {
    digitalWrite(RLY4, HIGH);
  }
  if (getBit(value, 2))
  {
    digitalWrite(RLY1, HIGH);
    delay(period);
    digitalWrite(RLY1, LOW);
  }
  if (getBit(value, 3))
  {
    digitalWrite(RLY2, HIGH);
    delay(period);
    digitalWrite(RLY2, LOW);
  }
  if (getBit(value, 4))
  {
    digitalWrite(RLY3, HIGH);
    delay(period);
    digitalWrite(RLY3, LOW);
  }
  if (getBit(value, 5) && getBit(value, 2))
  {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else
  {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

// This function will be called when the button1 was pressed 1 time.
void click1() {

  eq = false;
  ch1 = false;
  ch2 = false;
  ch3 = false;

  byte temp = 1 << n;
  state = temp + neq;

  if (getBit(state, 1))
  {
    digitalWrite(RLY4, HIGH);
    eq = true;
    neq = 0;
    n++;
  }
  else
  {
    neq = 1;
  }

  if (getBit(state, 4))
  {
    digitalWrite(RLY3, HIGH);
    delay(period);
    digitalWrite(RLY3, LOW);
    ch3 = true;
    digitalWrite(LED_BUILTIN, LOW);
  }

  if (getBit(state, 3))
  {
    digitalWrite(RLY2, HIGH);
    delay(period);
    digitalWrite(RLY2, LOW);
    ch2 = true;
    digitalWrite(LED_BUILTIN, LOW);
  }

  if (getBit(state, 2))
  {
    digitalWrite(RLY1, HIGH);
    delay(period);
    digitalWrite(RLY1, LOW);
    ch1 = true;
  }
  if (state == 9) //restart cycling all states
  {
    n = 1;
    neq = 0;
  }
} // click1


// This function will be called when the button1 was pressed 2 times in a short timeframe.
void doubleclick1() { //toggle reverb
  if (rev == false && ch1)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    rev = true;
  }
  else
  {
    digitalWrite(LED_BUILTIN, LOW);
    rev = false;
  }

} // doubleclick1


// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  //save preset
  byte value;
  if (eq)
  {
    setBit(value, 1);
    //Serial.print("eq ");
  }
  if (ch1)
  {
    setBit(value, 2);
    //Serial.print("ch1 ");
  }
  if (ch2)
  {
    setBit(value, 3);
    //Serial.print("ch2 ");
  }
  if (ch3)
  {
    setBit(value, 4);
    //Serial.print("ch3 ");
  }
  if (digitalRead(LED_BUILTIN) && ch1)
  {
    setBit(value, 5);
    //Serial.print(" rev");
  }

  EEPROM.write(curr_program, value);
  //Serial.println(value, BIN);

} // longPressStart1


// This function will be called often, while the button1 is pressed for a long time.
void longPress1() {
  //Serial.println("Button 1 longPress...");
} // longPress1


// This function will be called once, when the button1 is released after beeing pressed for a long time.
void longPressStop1() {
  //digitalWrite(RLY2,LOW);
} // longPressStop1


// -----------------------------------------------------------------------------
void setup()
{
  pinMode(RLY1, OUTPUT);
  pinMode(RLY2, OUTPUT);
  pinMode(RLY3, OUTPUT);
  pinMode(RLY4, OUTPUT);
  pinMode(REVC, OUTPUT);
  pinMode(SW1, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);

  //write inital presets, only for debugging.
  for (int i = 0; i < 128; i++)
  {
    //EEPROM.write(i,i);
  }

  //Define button handling functions
  button1.attachClick(click1);
  button1.attachDoubleClick(doubleclick1);
  button1.attachLongPressStart(longPressStart1);
  button1.attachLongPressStop(longPressStop1);
  button1.attachDuringLongPress(longPress1);
  // Connect the handleNoteOn function to the library,
  // so it is called upon reception of a NoteOn.
  MIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function
  // Do the same for NoteOffs
  MIDI.setHandleNoteOff(handleNoteOff);
  // And for PC message
  MIDI.setHandleProgramChange(handleProgramChange);
  // Initiate MIDI communications, listen to all channels
  MIDI.begin(MIDI_CHANNEL_OMNI);
  //Serial.begin(9600); //Set serial to 9600, only for debugging
  //Serial.println("Start");

}
void loop()
{
  // Call MIDI.read the fastest you can for real-time performance.
  MIDI.read();
  // There is no need to check if there are messages incoming
  // if they are bound to a Callback function.
  // The attached method will be called automatically
  // when the corresponding message has been received.

  // Call button tick to check button status
  button1.tick();
  // See if RLY4 is on, turn it off after preset period
  currentMillis = millis();
  if (digitalRead(RLY4));
  {
    startMillis = millis(); //start counting milliseconds if RLY4 on
    if (currentMillis - startMillis >= period)
    {
      digitalWrite(RLY4, LOW);
    }
  }
}

byte setBit(byte &store, byte bitn) { //bit 1 is right-most
  store |= (1 << (bitn - 1)); //set bit 5 to '1'.
}

byte clearBit(byte &store, byte bitn) {
  store &= !(1 << (bitn - 1));
}

byte getBit(byte store, byte bitn) {
  byte b = (1 << (bitn - 1));
  return (store & b);
}


It's been a while since I wrote this, but I'll try to explain. I'm not really a programmer at all, so the code is probably a bit of a hack job and it's still a work in progress, but it works for now.

The sound preset (channel, eq and reverb on or off) is stored as byte 'value' which has 5 bits. The least significant bit indicates EQ state, the next three are the preamp channels 1 to 3, bit 5 is the CH1 reverb (although I haven't implemented this in my preamp yet, so it just lights the inbuilt led).

So CH1 with no EQ is 00010, CH1 with EQ is 00011, CH2 without EQ is 00100, CH2 with EQ is 00101, CH3 without EQ is 01000, CH3 with EQ is 01001. The reverb for CH1 is activated by a double click, and the current program is saved by a long press.

Also note that all of these different states are non-latching, so they only give a pulse of 50 ms (controlled by "const unsigned long period"), you might need to change it to operate as latching.

Hope this helps!


sixtheory

Re: Arduino MIDI Switcher
« Reply #44 on: January 01, 2019, 09:37:12 AM »
Ok folks, here's what i got:

I'm needing to adapt this to control a Mesa Roadking Series I head... i Know its a big undertaking.

This amp has 8 remotely-controllable functions via "Latching type, Tip-to-Ground" Logic on  1/4" mono jacks mounted on the rear panel of the amp head. I have a Decibel 11 Midi controller for my guitar rig to control functions via midi.

It might be too much to tackle for me, as i am pretty new to this. I have brief knowledge of programming Arduino for a college project..but thats about it?

Any Help would be greatly appreciated!

EeroN

Re: Arduino MIDI Switcher
« Reply #45 on: January 02, 2019, 06:59:37 AM »
Ok folks, here's what i got:

I'm needing to adapt this to control a Mesa Roadking Series I head... i Know its a big undertaking.

This amp has 8 remotely-controllable functions via "Latching type, Tip-to-Ground" Logic on  1/4" mono jacks mounted on the rear panel of the amp head. I have a Decibel 11 Midi controller for my guitar rig to control functions via midi.

It might be too much to tackle for me, as i am pretty new to this. I have brief knowledge of programming Arduino for a college project..but thats about it?

Any Help would be greatly appreciated!

After a quick google search it seems to be possible to have multiple OneButtons within a single arduino sketch. I'd suggest setting up three of them as follows:

Button1: Channel 1, 2, 3 or 4, long press for program save
Button2: Loop 1, 2 or loop off
Button3: Combinations of Reverb and Solo on/off (4 in total)

It would of course be possible to use a single OneButton, but a total of 255 states is a lot to cycle through :) so from a usability standpoint it's probably worth the trouble to use multiple buttons.

The Nano has a total of 12 digital pins (D2-D13), so you could use the first 8 (D2-D9) for your control outputs and three (D10-D12) for the OneButtons and still have D13 (the inbuilt LED) for an indicator.

The hardware bit also needs some consideration. I've been experimenting with the ULN2003 IC, which I originally got for controlling stepper motors for another unrelated project, but it can be used as a logic buffer too. I'm not sure, but it might be possible to use that instead of having to wire up 8 relays to the arduino. The problem for your project is that the ULN2003 only has 7 inputs but your application needs 8. One solution would just be to use 2 of those, still a lot less PCB real estate than 8 relays.

What you should do is find out the control voltage sent out by the RK.

I can also do a bit of breadboarding for you later today with the Nano and the ULN2003 and report back with my results.

EeroN

Re: Arduino MIDI Switcher
« Reply #46 on: January 03, 2019, 08:43:26 AM »
I breadboarded the Nano with the ULN2003, and it seems to work as I thought. The ULN2003 doesn't pull the pins all the way to ground, but to about 0.7 V, which is probably close enough to trigger switching on the amp.

I also took a look at the RK schematic (version 2, but I believe the switching circuit on version 1 is similar), and the voltage used by the switching circuitry is 12V and that's what I used to test my circuit, so I'd say it's worth a try. The problem is you'd need a separate powersupply to power the Nano. You can't use the voltage from the RK switching circuit.

Of course, the simple solution to the above concerns would be to just use 8 relays, but this will require a much bigger PCB and will cost more. You'd also need to take into consideration the current drawn by the relays, and you'd need to use a separate power source for the circuit regardless.

ElectricDruid

Re: Arduino MIDI Switcher
« Reply #47 on: January 05, 2019, 05:28:45 AM »
If you're just triggering switching in the amp, a simple transistor is probably enough. A relay would be overkill. Use the Arduino to switch a transistor, and then use the transistor to short the tip to ground as if it was a foot switch.

T.

EeroN

Re: Arduino MIDI Switcher
« Reply #48 on: January 05, 2019, 07:19:27 AM »
If you're just triggering switching in the amp, a simple transistor is probably enough. A relay would be overkill. Use the Arduino to switch a transistor, and then use the transistor to short the tip to ground as if it was a foot switch.

T.

Agreed, and that's how I did mine (see image).



That's also why I suggested the ULN2003, it basically has seven transistor switches in one package, resistors and all. Much less soldering than seven individual transistors. The Road King needs eight, but the remaining one can be easily implemented with a separate NPN transistor.


philos

Re: Arduino MIDI Switcher
« Reply #49 on: July 30, 2019, 03:36:30 PM »
Nice project! Exactly what i need (the version with two loops)!  I want to use two pedals controlled by MIDI.

Just one change:

Two footswitches, one to each loop. Long press the two at the same time to save rpeset.

Could some good soul post the code to that for me? I don't know pretty much nothing about this stuff.

Thank you in advance!

potul

Re: Arduino MIDI Switcher
« Reply #50 on: July 31, 2019, 09:12:00 AM »
I can try to help, but I will need to understand what your needs are.