Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: MIDI stompbox + expedal (spdt switches - help with code)

  1. #1
    Junior Member
    Join Date
    Oct 2019
    Posts
    2

    MIDI stompbox + expedal (spdt switches - help with code)

    Greetings all!
    First time here and first teensy project.

    So im building a stompbox for my bandmate. It is a four button + expedal.
    Iv got almost everything working exept the behavior of the switches.

    The switches are spdt-switches, the problem is that it only sends midiCC when the switches are in gnd state(pullup) hence i have to press two times (instead of one) for a mapped button in my daw to change (since its a toggleswitch), the code seems to be for momentary buttons.

    Im using the code posted by oddson: mod on "manybuttonsknobs"
    Code:
    // include the ResponsiveAnalogRead library for analog smoothing
    #include <ResponsiveAnalogRead.h>
    // include the Bounce library for 'de-bouncing' switches -- removing electrical chatter as contacts settle
    #include <Bounce.h> 
    //usbMIDI.h library is added automatically when code is compiled as a MIDI device
    
    // ******CONSTANT VALUES******** 
    // customize code behaviour here!
    const int channel = 1; // MIDI channel
    const int A_PINS = 1; // number of Analog PINS
    const int D_PINS = 4; // number of Digital PINS
    const int ON_VALUE = 127; // note-one velocity sent from buttons (should be 65 to  127)
    
    // define the pins you want to use and the CC ID numbers on which to send them..
    const int ANALOG_PINS[A_PINS] = {A1};
    const int CCID[A_PINS] = {21};
    
    // define the pins and notes for digital events
    const int DIGITAL_PINS[D_PINS] = {7,8,9,10};
    const int CC[D_PINS] = {60,61,62,63};
    const int BOUNCE_TIME = 7; // 5 ms is usually sufficient
    const boolean toggled = false;
    
    
    //******VARIABLES***********
    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS]; // when lag and new are not the same then update MIDI CC value
    byte CClast[D_PINS];
    
    //************INITIALIZE LIBRARY OBJECTS**************
    // not sure if there is a better way... some way run a setup loop on global array??
    // use comment tags to comment out unused portions of array definitions
    
    // initialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[]{
      {ANALOG_PINS[0],true}/*,
      {ANALOG_PINS[1],true},
      {ANALOG_PINS[2],true},
      {ANALOG_PINS[3],true},
      {ANALOG_PINS[4],true},
      {ANALOG_PINS[5],true},
      {ANALOG_PINS[6],true},
      {ANALOG_PINS[7],true},*/
    }; 
    
    // initialize the bounce objects 
    Bounce digital[] =   {
      Bounce(DIGITAL_PINS[0],BOUNCE_TIME), 
      Bounce(DIGITAL_PINS[1], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[2], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[3], BOUNCE_TIME)/*,
      Bounce(DIGITAL_PINS[4], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[5], BOUNCE_TIME)/*,
      Bounce(DIGITAL_PINS[6], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[7], BOUNCE_TIME),*/
    }; 
    
    //************SETUP**************
    void setup() {
    // loop to configure input pins and internal pullup resisters for digital section
      for (int i=0;i<D_PINS;i++){
        pinMode(DIGITAL_PINS[i], INPUT_PULLUP);
      }
    }
    
    //************LOOP**************
    void loop() {
      getAnalogData();
      getDigitalData();
      while (usbMIDI.read()) {
         // controllers must call .read() to keep the queue clear even if they are not responding to MIDI
      }
    }
    
    
    //************ANALOG SECTION**************
    void getAnalogData(){  
      for (int i=0;i<A_PINS;i++){
        // update the ResponsiveAnalogRead object every loop
        analog[i].update(); 
        // if the repsonsive value has change, print out 'changed'
        if(analog[i].hasChanged()) {
          data[i] = analog[i].getValue()>>3;
          if (data[i] != dataLag[i]){
            dataLag[i] = data[i];
            usbMIDI.sendControlChange(CCID[i], data[i], channel);
          }
        }
      }
    }
    
    
    
    //************DIGITAL SECTION**************
    void getDigitalData(){
      for (int i=0;i<D_PINS;i++){
      digital[i].update();
        if (digital[i].fallingEdge()) {
          if (CClast[i]){
            usbMIDI.sendControlChange(CC[i], 0, channel);
            CClast[i] = 0;
          }else{
            usbMIDI.sendControlChange(CC[i], ON_VALUE, channel);
            CClast[i] = ON_VALUE;
          }
        }
        // rising ignored for toggles
      }
    
    }
    i dont really know how to do a wiringdiagram but this is basically how the wiring is done.

    Click image for larger version. 

Name:	output.jpg 
Views:	5 
Size:	57.0 KB 
ID:	17952


    So, i humbly ask for help regarding the code to make it momentary (since its toggle switches), also dont really know how to make a wiringdiagram..

    Any help is appreciated, take care
    Last edited by Lemonmeth; 10-18-2019 at 08:42 PM. Reason: spelling

  2. #2
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,201
    That modified code was to implement toggle behaviour with momentary switches.

    If you have toggle switches the stock many-button-and-knobs sketch should work by just replacing the note on/off commands with CC messages at 0 and 127 for off and on.

    Code:
    //************DIGITAL SECTION**************
    void getDigitalData(){
      for (int i=0;i<D_PINS;i++){
      digital[i].update();
        if (digital[i].fallingEdge()) {
         usbMIDI.sendControlChange(note[i], ON_VELOCITY, channel);  
        }
        // with a toggle switch we send off with rising edge
        if (digital[i].risingEdge()) {
          usbMIDI.sendControlChange(note[i], 0, channel);  
        }
      }
    }
    You might rename note[] to something more descriptive for CC numbers (you need to alter where it's initialized too) but I think it will work as is. You just put what CC numbers you want the buttons to toggle in the note array or it's replacement.

    Re wiring: That diagram suggests you have the pins electrically connected together which I don't think you mean. If the toggles are grounded on one side and connected to the correct digital pin on the other the code should work.

    The potentiometer for the expression pedal needs to have the 3.3 volt power on the top end and ground on the bottom with the wiper (middle contact) connected to the analog pin.

    ...about signal stability.. You might need a very high BOUNCE_TIME if your toggles are slow to settle with the latching mechanism.

    And expression pedals can bring a lot of noise on an analog signal. ResponsiveAnalogRead() was used rather naively in this code but it's usually enough to tame for seven-bit MIDI values. You also need to be sure yours is wired as you expect as some use different wiring to the TRS connector.
    Last edited by oddson; 10-18-2019 at 09:15 PM.

  3. #3
    Junior Member
    Join Date
    Oct 2019
    Posts
    2
    Yeees! That did it!
    Thank you for clarifying and explaining, it makes sense now.
    i set the bouncetime to 5 ms and did some testing, seems to work fine.
    regarding the wiringdiagram , i made it on the phone and tried to scale it down to its essence - but the physical wiring is ok.


    Thanks heaps for the quick reply and your time oddson.
    Let me know if i can buy you a coffee or something

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •