News:

SMF for DIYStompboxes.com!

Main Menu

Arduino MIDI Switcher

Started by potul, November 04, 2015, 01:21:57 PM

Previous topic - Next topic

andersm

#20
Sorry for making it so overcomplicated  :D
But yes, you got everything right. The 4PDT was necessary to keep the signal paths discrete and not to create any short circuits.
I had indeed forgotten that there were relays left, maybe I could use thm to contol the bubble machine and the flame thrower on stage XD

As for the question about the use of Loop B, I guess it depends on what effect I put there. I don't think I would need to switch this on the fly, really. But then again, this way I could if need be. And some effects work both ways but sound differently.
But I guess if I can fit an enclosure into my floorboard that's big enough for all the switches I might just give the post fx their own loop, while I'm at it.

potul

#21
So here it goes, my 2 cents....

If you don't need to move loop B from pre to post in the middle of a show, I would skip completely the 4PDT (I will explain later). If it's needed, it can be done with a 3PDT using the FX juggler schematic from Geofex.

Option 1: No relocation of loop B on the fly

-Wire both Loop A and Loop B as true bypass using 2 relays each.
-You then don't need the additional true bypass for loop A. If you still want to control independently Loop A, you can add a button and control it via the Arduino.
-Instead of sending the output of loop A to the input of Loop B, just send the output of Loop A to a jack and the input of Loop B to another jack. This way, you have two separated loops, not connected to each other.
-You have then 2 ways to connect it

Guitar -> LoopA -> preamp -> LoopB -> power amp
Guitar -> LoopA -> Loop B -> Amp

You can simply use a cable patch from LoopA to LoopB, or even better, using a switching jack, you can make this connection automatic when there is nothing inserted in the post-fx jack.
Each loop is trubypass and controlled via MIDI. If you want to change position of LoopB you need to rewire.

Option 2: Loop B switching

if switching is needed without re-wiring, I would do:
-Basically same as option 1. But in this case, think about post-fx being another loop (at the end it is a loop that goes to the preamp of your amp and returns)
-You keep the 2 relays for LoopA and LoopB for true bypass. post-fx loop is always on.
-You add the FX juggler so that you can change the order of LoopB and post-fx.
http://www.geofex.com/article_folders/juggler/juggler.htm
You can use a rotary 4PDT and add a status LED
This will enable you to change the order of the post-fx and loopB loops, that is in essence placing the loopB before or after your preamp.


potul

If you need it I can draw something....

andersm

Wow. That is pretty cool, although I have to admit I'm not sure I understood all the technicalities.
I would go with option A, since most effects are either pre or post, really.

Basically there are 2 aspects I haven't quite understood yet.
) How do you wire 2 relays to create a true bypass? Doesn't the actual signal still have to run through them?
) The switching jack, I assume, would be the SEND jack for the B Loop, right? How would that relate to whether it's a post or pre effect?
Sorry for the hassle, maybe a schematic would help me indeed. You do have an online tip jar for coffee I hope ;)

potul

Ok,... gimme some time. This evening when I'm  at home I will draw something.

Mat

andersm

Take your time dude, I appreciate this!

potul

#26
Here it goes, this is what I would do, without fancy switching:

Relay 1 and 2 get activated at the same time.
Relay 3 and 4 get activated at the same time.



How to connect it..

Option 1: LoopB is "post" (so, in the FX loop of the amp)

Guitar -> IN
LOOPA Send -> Stompbox IN
Stompbox OUT -> LOOP A return
Preamp Send -> Amp IN
Amp FX send -> Preamp Return
LOOP B send -> Stompbox IN
Stompbox OUT -> LOOP B return
OUT -> Amp Fx return

With this connections, LOOP A is pre, LOOP B is post.

Option 2: LoopB is "Pre" (so, before Amp input)

Guitar -> IN
LOOPA Send -> Stompbox IN
Stompbox OUT -> LOOP A return
Preamp Send -> Nothing
Nothing -> Preamp Return
LOOP B send -> Stompbox IN
Stompbox OUT -> LOOP B return
OUT -> AMP IN

With these connections, both LOOPs are PRE. Nothing inserted in the Preamp Send/Return, or you could put there something you want between loops, without switching capability.
Note that the Preamp Send jack has a switch, so when no jack is inserted, the whole Preamp loop is bypassed.


Take a look a it and see if this fulfills your needs.

Mat





potul

It's still possible to add "on-the-fly switching" to change LoopB from Pre to Post, using a 3pdt or 4pdt if LED needed.

andersm

Alright, I get it now  8)
Yes I will definitely go for this. I didn't even know those switched jacks existed. Brilliant!
Thank you for the schematic.

potul

Yep, you have the open type, like this one:




And the neutrik style:




jimmyq

Wow, this looks awesome!
I've been looking for this kind of thing for a while and this looks the closest to what I've been looking for.
There might be some adjustments I'd need to make though as I'm trying to modify a standard A/B box, so that I can switch it via midi commands from a floor controller.
I'm a complete newbie in this area, but I'm thinking that each relay could route the signal to A or B. Each relay would have to stay on until I change channel so would I need a specific relay type?
I'd have to install a switch on the unit to latch from manual mode to midi mode unless I could wire it so that stomping on it overrides the midi signal. I'd appreciate your thoughts?

potul

Hi

For a pure A/B switch you only need one Relay. If you want A/B/Y then it gets more tricky, it could probably be done with 2 relays (without buffering).

If you want to "override" with a stomp, what I would do is add a momentary switch, and do it via software. So you can switch from the stomp, and switch via MIDI. Last one to be actuated wins.

Mat

caldersm

Agree with you on using the momentary switch and do the code in the chip.

I just finished some software software using a Teensy.....for a project with 8 momentary switches in and 8 relays out, a Mini OLED display, a rotary encoder with switch, USB Midi and Hardwired Midi with a remote stomp via a cable.  Via the menu you can change PC and CC Channels and the CC Command registers.....also Latching vs Momentary outputs.  About 700 lines code....


achben

I have everything working save for being able to change the state of the pins with note on/off or PC.
What code do I put where to change the states of the digital pins with PC 01 and PC 02?

potul

It should be easy to add it. I am away from my PC this week. Tonight I will be back home and I will take a look at the code.

potul

Quote from: achben on August 26, 2017, 01:40:54 PM
I have everything working save for being able to change the state of the pins with note on/off or PC.
What code do I put where to change the states of the digital pins with PC 01 and PC 02?

Can you clarify? Do you want to change the state with note on/off, or with PC messages?

If note on/off,  what notes do you want to use for each relay?

jmrwoods

Resurrecting this thread.  Here is a version for amps with momentary (non-latching) footswitches.



HUGE thanks to potul for his help with coding, advice, and troubleshooting.

As you can see, this version incorporates LEDs. It senses and shows the amps current state. It senses which is on/off so it knows which relay(s) to engage when memory is recalled. Instead of a normal push button, I elected for a momentary footswitch. In this case, I can set it next to my POD when I'm programming (and tap with my foot) – or it works just as well sitting on top of the amp when setup more for performance. The button works the exact same was as potul described in his first post (cycles through the four possible states – press of >1sec saves to memory).

Sensing circuit was simple (one for each channel) – and basically based on the footswitch that came with the amp. A simple voltage divider (with or without LED) would work, too. The end result should be getting around 3V (for an ON state) to the proper Arduino pin, or ~0V for an OFF state. Here is the original sketch, but I ended up with different values for the zeners and added resistors (circuit is at the very bottom of the circuit board in the gut shot).










Updated code:


#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 SW1 12  //set pin for button (Cycle states & Save)
#define LED1 11 //set pin for Relay1 (Reverb)
#define LED2 10 //set pin for Relay2 (Channel)
#define REV 9   //Set pin for reading Reverb
#define CHAN 8  //set pin for reading Channel

//#define BUT 7 //pin for debugging
//#define BUTUP 6 //pin for debugging
MIDI_CREATE_DEFAULT_INSTANCE();

byte curr_program;  //current PC value

// Setup a new OneButton on pin 11. 
OneButton button1(SW1, true);
//OneButton button2(BUT, true); //debugging
//OneButton button3(BUTUP, true); //debugging

// -----------------------------------------------------------------------------
// 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);
  //activate relay 1 if needed
     if (getBit(value,1))
   {
    if (!digitalRead(REV))
      {
        digitalWrite(LED1,LOW);
        delay(50);
        digitalWrite(LED1,HIGH);
      }
   }
   else
   {
      if (digitalRead(REV))
      {
        digitalWrite(LED1,LOW);
        delay(50);
        digitalWrite(LED1,HIGH);   
      }
   }
  //activate relay 2 if needed
  if (getBit(value,2))
   {
    if (!digitalRead(CHAN))
      {
        digitalWrite(LED2,LOW);
        delay(50);
        digitalWrite(LED2,HIGH);
      }
   }
   else
   {
      if (digitalRead(CHAN))
      {
        digitalWrite(LED2,LOW);
        delay(50);
        digitalWrite(LED2,HIGH);   
      }
   }

}
//debug start
//void click2(){
//  handleProgramChange(1, curr_program-1);
//  }
//  void click3(){
//  handleProgramChange(1, curr_program+1);
//  }
//debug end

// This function will be called when the button1 was pressed 1 time.
void click1() {
  //toggle Relay1
  byte value;
  value=digitalRead(REV)+digitalRead(CHAN)*2;
  value++;
    if (getBit(value,1))
   {
    if (!digitalRead(REV))
      {
        digitalWrite(LED1,LOW);
        delay(50);
        digitalWrite(LED1,HIGH);
      }
   }
   else
   {
      if (digitalRead(REV))
      {
        digitalWrite(LED1,LOW);
        delay(50);
        digitalWrite(LED1,HIGH);   
      }
   }
  //activate relay 2 if needed
  if (getBit(value,2))
   {
    if (!digitalRead(CHAN))
      {
        digitalWrite(LED2,LOW);
        delay(50);
        digitalWrite(LED2,HIGH);
      }
   }
   else
   {
      if (digitalRead(CHAN))
      {
        digitalWrite(LED2,LOW);
        delay(50);
        digitalWrite(LED2,HIGH);   
      }
   }
} // click1


// This function will be called when the button1 was pressed 2 times in a short timeframe.
void doubleclick1() {
} // doubleclick1


// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  //save preset
  byte value=0;
  if (digitalRead(REV))
  {
    setBit(value,1);
  }
  if (digitalRead(CHAN))
  {
    setBit(value,2);
  }
  EEPROM.write(curr_program,value);
 
} // 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(LED2,LOW);
} // longPressStop1


// -----------------------------------------------------------------------------
void setup()
{
    pinMode(LED1, OUTPUT);
    digitalWrite(LED1,HIGH);
    pinMode(LED2, OUTPUT);
    digitalWrite(LED2,HIGH);
    pinMode(CHAN, INPUT);
    pinMode(REV, INPUT);
    pinMode(SW1, INPUT_PULLUP);
//    pinMode(BUT, INPUT_PULLUP); //debug
//    pinMode(BUTUP, INPUT_PULLUP);  //debug
    //write inital presets, only for debugging.
//    for (int i=0;i<128;i++)
//    {
//      EEPROM.write(i,i);
//    }
   
    //Define button handling functions
//    button2.attachClick(click2); //debug
//    button3.attachClick(click3); //debug
    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
   
}
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();
//    button2.tick();  //debug
//    button3.tick();  //debug
}

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));
}

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

Hatredman

What a lovely Strat!

.sig goes here.

Kirk Hammet invented the Burst Box.

potul

Quote from: jmrwoods on February 16, 2018, 02:12:41 PM
Resurrecting this thread.  Here is a version for amps with momentary (non-latching) footswitches.

I just wanted to step in to highlight the remote collaborative job we did, Mike and I. It was fun to troubleshoot the software and hardware from the other side of the world.

This version will work with a Bugera amp (I don't remember the exact model), but it could maybe work with other brands. The key here is that the circuit is monitoring the status of the channels by looking at the voltage that comes from the amp through the footswitch cable. This only works in those amps that use momentary switches, and have LEDs on the footswitch. For other brands/models, some minor adjustments on the hardware might be needed (adjusting the zener or similar)

Good Job!

jmrwoods

Quote from: Hatredman on March 21, 2018, 01:57:48 PM
What a lovely Strat!

.sig goes here.

Thanks! That's actually a JTV69s Tyler Variax that I refinished. It started out Shoreline Gold, but I wanted to highlight more of the offset design (i.e. Jaguar, Jazzmaster) and less strat. Walnut stain and hand-rubbed oil finish. Turned out great!


Quote from: potul on March 22, 2018, 03:31:18 AM
Quote from: jmrwoods on February 16, 2018, 02:12:41 PM
Resurrecting this thread.  Here is a version for amps with momentary (non-latching) footswitches.

I just wanted to step in to highlight the remote collaborative job we did, Mike and I. It was fun to troubleshoot the software and hardware from the other side of the world.

This version will work with a Bugera amp (I don't remember the exact model), but it could maybe work with other brands. The key here is that the circuit is monitoring the status of the channels by looking at the voltage that comes from the amp through the footswitch cable. This only works in those amps that use momentary switches, and have LEDs on the footswitch. For other brands/models, some minor adjustments on the hardware might be needed (adjusting the zener or similar)

Good Job!

It WAS a lot of fun - and best of all - works like a charm.