Go Down

Topic: USB Midi Foot Controller Help (Read 2386 times) previous topic - next topic

NervusTwitch

Just some quick info on my knowledge.

In the past I have built several button boxes using button matrix,encoders,and pots for gaming and various other programs. Ive only used the Nano once, several Pro Micro's and a UNO once for force feedback for my racing sim setup.
I have not ever done the programming side of Arduino, I used MMJOY as it was adequate for my needs.

Now what Im trying to do is make a midi foot controller to use with my DAW and Amp/pedal sims for guitar thru USB.

My plans are to 10 momentary foot switches with LEDS only for 7 of the switches to show activated switch or off and 1 pot for an expression pedal.I plan to also use the Pro Micro since I already have it extra. Plus another on/off/on switch for switching layers.(used the way Ill show in example)

But for now Im having trouble trying to understand how I need to wire all this up with the amount of controls I want, meaning Im not sure if I have enough inputs. Trying to keep it budget since so far I already have the parts from the parts box so as of now cost is $0.

I was looking at this example from github,easy to understand diagrams and such but like I said cant figure out how to count for the extra buttons I was wanting to add.

Please some info,links any help would be appreciative.

Example Diagram from github: Also github link for the what I want but just more switches than the author is using.

https://github.com/Hecsall/arduino-midi-footswitch


Grumpy_Mike

#1
Jul 30, 2020, 09:57 am Last Edit: Jul 30, 2020, 10:05 am by Grumpy_Mike
Well first off do you know you can use the analogue inputs as normal digital pins. Just use A0 and so on in the digitalRead and write and in the pinMode call.

I have a MIDI foot switch project at:- http://www.thebox.myzen.co.uk/Hardware/MIDI_Footsteps.html

That uses an analogue multiplexer to read many sensors.

The thing is you have two problems:-
1) How to get more inputs
2) How to use those inputs for MIDI.

So search first for how to get more inputs.
There are several solutions to this:-
1) Using one or more shift registers for more inputs. This is like the more normal using shift registers for more outputs but uses a different type of shift register.

2) Multiplex them. You can use either digital or analogue multiplexers to feed many inputs into one input, digital or analogue. These multiplexers have address lines with control what input gets switched to the output.

3) Port expanders. Chips like the MSP23017 and MSP23S17 can give you 16 extra input / output pins. https://www.adafruit.com/product/732
Or you can buy boards with these already on:-
Expansion Board

Quote
easy to understand diagrams
What you posted is not a circuit diagram or schematic. It is physical layout diagram, otherwise known as a piece of Fritzing crap. They are not much use apart from blindly making a copy of something without thinking at all. Learning to read real schematics will serve you well in this game.

In the physical layout diagram you posted you will find that 10K will make the LEDs look dim and using 0.5W resistors is extreme overkill, normal quarter watt or eighth watt will be way more than you need. So it is best to assume the people who produced that, don't know what they are doing.

NervusTwitch

Thanks for the info.
I will be looking into your info more.

As for the diagram and link,i posted it as to show that it is how i wanted my setup to work. Since im very new to the music abilities of arduino it was simple to get an idea for me to know how and what i might need to do. As i mentioned i have no experience programming arduinos. I have made some fairly extensive button and control boxes but i used mmjoy as its a graphical interface for that purpose to use for flight sims etc.

But after looking at my project a bit more, i realised that i dont need as many buttons as mentioned above.

The project is actually only 8 switches of which only 7 will have led and 1 pot. For some reason i kept counting 2 extra switches that im not using.
So if im looking at things correct just the single pro micro would be enough.

As far as what you posted about leds and resistors,yes i am aware as i have a stock pile of the 1/4 watt that i use in other projects.

As for schematics i have an ok understanding of them since i use them normally for my other projects. Im just trying to keep my current one simple,not overly complicated so i thought the linked project would be good start.

Im just hobbiest and i learn what i need to as i work on whatever project i may be attempting,so far i havent failed at any with very minimal help from others,just read alot on what i need.

Im sure ill have another question as i plan this out more but i do like to figure things out for myself, its the way my dad taught me auto mechanics. 

Also please forgive my reply grammar, im using a tablet to reply with at the moment.

NervusTwitch

Ok I basically built the project mentioned in the OP except instead of 5 switches/leds Im using 7,everything works.

But I have 1 issue for now that I cant seem to figure out,well maybe 2 but one thing at a time.

All the switches seem to function as intended but I cant figure out how to make the led's light when I press a switch, it will only flash once with each press. That goes for all 7 switches/led's.

All I'm wanting this foot controller to do is to be used as a foot controller for amp changes and effects on/off and leave the corresponding led to each switch lit or off depending on state. Some of the software I will use this with would be Reaper DAW,Amplitube,Bias Amp/FX and so forth.

Is what Im wanting the led's to do possible? Remember I am just now learning the coding part of Arduino.

Code: [Select]
/*
Arduino USB MIDI FootSwitch
by Hecsall (https://github.com/Hecsall)
*/

// https://www.arduino.cc/en/Reference/MIDIUSB
#include "MIDIUSB.h"
#include "variables.h"

// Utility functions

// Event type is hard-coded (0x09 = note on, 0x08 = note off).
// First parameter is the MIDI channel, combined with the note-on/note-off.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Second parameter (pitch) is the note number (48 = middle C).
// Third parameter is the velocity (0 -> 127, 0 = no_sound, 64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity)
{
    midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity)
{
    midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOff);
}

// Event type hard-coded (0x0B = control change, aka "MIDI CC").
// First parameter is the channel (0-15), combined with the event type.
// Second parameter is the "control change" number (0-119, see top link to midi.org).
// Third parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value)
{
    midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
    MidiUSB.sendMIDI(event);
}

// BPM Counter
void initBPM()
{
    midiEventPacket_t rx;
    do {
        rx = MidiUSB.read();
        //Count pulses and send note
        if (rx.byte1 == 0xF8)
        {
            ++ppqn;
            if (ppqn == 24)
            {
                digitalWrite(10, HIGH);
                delay(80);
                digitalWrite(10, LOW);
                ppqn = 0;
            };
        }
        //Clock start byte
    } while (rx.header != 0);
}

// Button in "Push" mode
void handlePushButton(byte i)
{
    if (digitalRead(button_pins[i]) == LOW && button_states[i] == false)
    {
        controlChange(0, button_layers[current_layer][i], 127);
        MidiUSB.flush();
        button_states[i] = true;
        digitalWrite(led_pins[i], HIGH); // Turn the LED on
        led_states[i] = true;
        delay(15);
    }
    else if (digitalRead(button_pins[i]) == HIGH && button_states[i] == true)
    {
        controlChange(0, button_layers[current_layer][i], 0);
        MidiUSB.flush();
        button_states[i] = false;
        digitalWrite(led_pins[i], LOW); // Turn the LED off
        led_states[i] = false;
        delay(15);
    }
}

// Button in "Toggle" mode
void handleToggleButton(byte i)
{
    buttonState = digitalRead(button_pins[i]);
    if (buttonState != lastButtonState){
        if (buttonState == LOW && button_states[i] == false)
        {
            controlChange(0, button_layers[current_layer][i], 127);
            MidiUSB.flush();
            button_states[i] = true;
            digitalWrite(led_pins[i], HIGH); // Turn the LED on
            led_states[i] = true;
        }
        else if (buttonState == LOW && button_states[i] == true)
        {
            controlChange(0, button_layers[current_layer][i], 0);
            MidiUSB.flush();
            button_states[i] = false;
            digitalWrite(led_pins[i], LOW); // Turn the LED off
            led_states[i] = false;
        }
        delay(100);
    }
    lastButtonState = buttonState;
}

// Button "Change" mode
void handleChangeMode(byte i)
{
    buttonState = digitalRead(button_pins[i]);
    if (buttonState != lastButtonState){
        // Note: only layer 1 (switch OFF) can be customized
        if (buttonState == LOW && button_modes[1][i] == 0 && millis() - time > debounce)
        {
            button_modes[1][i] = 1;
            digitalWrite(led_pins[i], HIGH); // Turn the LED on
            led_states[i] = true;
            time = millis();
        }
        else if (buttonState == LOW && button_modes[1][i] == 1 && millis() - time > debounce)
        {
            button_modes[1][i] = 0;
            digitalWrite(led_pins[i], LOW); // Turn the LED off
            led_states[i] = false;
            time = millis();
        }
        delay(50);
    }
    lastButtonState = buttonState;
}

// Turn off all LEDs
void poweroffLeds()
{
    for (uint8_t i = 0; i < 7; i++)
    {
        digitalWrite(led_pins[i], LOW);
        led_states[i] = false;
    }
}

// Turn on all the current mode LEDs
void showModeLeds()
{
    for (uint8_t i = 0; i < 7; i++)
    {
        if (button_modes[1][i] == 1)
        {
            digitalWrite(led_pins[i], HIGH);
            led_states[i] = true;
        }
    }
}

// Check and set which layer is active
void setLayer()
{
    if (digitalRead(switch_pins[0]) == LOW && digitalRead(switch_pins[1]) == HIGH && current_layer != 0)
    {
        current_layer = 0; // Switch UP
    }
    else if (digitalRead(switch_pins[0]) == HIGH && digitalRead(switch_pins[1]) == HIGH && current_layer != 1)
    {
        current_layer = 1; // Switch OFF
    }
    else if (digitalRead(switch_pins[0]) == HIGH && digitalRead(switch_pins[1]) == LOW && current_layer != 2)
    {
        current_layer = 2; // Switch DOWN
    }
}

// Actual logic
void setup()
{
    Serial.begin(115200);
    // Button Pins
    for (uint8_t i = 0; i < 7; i++)
    {
        pinMode(button_pins[i], INPUT_PULLUP);
    }
    // LED Pins
    for (uint8_t i = 0; i < 7; i++)
    {
        pinMode(led_pins[i], OUTPUT);
    }
    // Switch Pins
    for (uint8_t i = 0; i < 2; i++)
    {
        pinMode(switch_pins[i], INPUT_PULLUP);
    }
    // Set currently active Layer
    setLayer();
}

void loop()
{
    initBPM(); // Blinking BPM LED - needs to be enabled in your DAW
    setLayer(); // Set which Layer we are using

    // Button operations based on current_layer
    for (uint8_t i = 0; i < 7; i++)
    {
        if (current_layer < 2) // Only layers 0 and 1 are normal operational layers
        {
            poweroffLeds();
            if (button_modes[current_layer][i] == 0)
            {
                handlePushButton(i);
            }
            else if (button_modes[current_layer][i] == 1)
            {
                handleToggleButton(i);
            }
        }
        else if (current_layer == 2) // Layer 2 is the "settings" layer
        {
            showModeLeds();
            handleChangeMode(i);
        }
    }
}




NervusTwitch

Also my variables file

Variables

Code: [Select]
/*
Arduino USB MIDI FootSwitch
by Hecsall (https://github.com/Hecsall)
*/

// https://www.arduino.cc/en/Reference/MIDIUSB
#include "MIDIUSB.h"
#include "variables.h"

// Utility functions

// Event type is hard-coded (0x09 = note on, 0x08 = note off).
// First parameter is the MIDI channel, combined with the note-on/note-off.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Second parameter (pitch) is the note number (48 = middle C).
// Third parameter is the velocity (0 -> 127, 0 = no_sound, 64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity)
{
    midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity)
{
    midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOff);
}

// Event type hard-coded (0x0B = control change, aka "MIDI CC").
// First parameter is the channel (0-15), combined with the event type.
// Second parameter is the "control change" number (0-119, see top link to midi.org).
// Third parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value)
{
    midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
    MidiUSB.sendMIDI(event);
}

// BPM Counter
void initBPM()
{
    midiEventPacket_t rx;
    do {
        rx = MidiUSB.read();
        //Count pulses and send note
        if (rx.byte1 == 0xF8)
        {
            ++ppqn;
            if (ppqn == 24)
            {
                digitalWrite(10, HIGH);
                delay(80);
                digitalWrite(10, LOW);
                ppqn = 0;
            };
        }
        //Clock start byte
    } while (rx.header != 0);
}

// Button in "Push" mode
void handlePushButton(byte i)
{
    if (digitalRead(button_pins[i]) == LOW && button_states[i] == false)
    {
        controlChange(0, button_layers[current_layer][i], 127);
        MidiUSB.flush();
        button_states[i] = true;
        digitalWrite(led_pins[i], HIGH); // Turn the LED on
        led_states[i] = true;
        delay(15);
    }
    else if (digitalRead(button_pins[i]) == HIGH && button_states[i] == true)
    {
        controlChange(0, button_layers[current_layer][i], 0);
        MidiUSB.flush();
        button_states[i] = false;
        digitalWrite(led_pins[i], LOW); // Turn the LED off
        led_states[i] = false;
        delay(15);
    }
}

// Button in "Toggle" mode
void handleToggleButton(byte i)
{
    buttonState = digitalRead(button_pins[i]);
    if (buttonState != lastButtonState){
        if (buttonState == LOW && button_states[i] == false)
        {
            controlChange(0, button_layers[current_layer][i], 127);
            MidiUSB.flush();
            button_states[i] = true;
            digitalWrite(led_pins[i], HIGH); // Turn the LED on
            led_states[i] = true;
        }
        else if (buttonState == LOW && button_states[i] == true)
        {
            controlChange(0, button_layers[current_layer][i], 0);
            MidiUSB.flush();
            button_states[i] = false;
            digitalWrite(led_pins[i], LOW); // Turn the LED off
            led_states[i] = false;
        }
        delay(100);
    }
    lastButtonState = buttonState;
}

// Button "Change" mode
void handleChangeMode(byte i)
{
    buttonState = digitalRead(button_pins[i]);
    if (buttonState != lastButtonState){
        // Note: only layer 1 (switch OFF) can be customized
        if (buttonState == LOW && button_modes[1][i] == 0 && millis() - time > debounce)
        {
            button_modes[1][i] = 1;
            digitalWrite(led_pins[i], HIGH); // Turn the LED on
            led_states[i] = true;
            time = millis();
        }
        else if (buttonState == LOW && button_modes[1][i] == 1 && millis() - time > debounce)
        {
            button_modes[1][i] = 0;
            digitalWrite(led_pins[i], LOW); // Turn the LED off
            led_states[i] = false;
            time = millis();
        }
        delay(50);
    }
    lastButtonState = buttonState;
}

// Turn off all LEDs
void poweroffLeds()
{
    for (uint8_t i = 0; i < 7; i++)
    {
        digitalWrite(led_pins[i], LOW);
        led_states[i] = false;
    }
}

// Turn on all the current mode LEDs
void showModeLeds()
{
    for (uint8_t i = 0; i < 7; i++)
    {
        if (button_modes[1][i] == 1)
        {
            digitalWrite(led_pins[i], HIGH);
            led_states[i] = true;
        }
    }
}

// Check and set which layer is active
void setLayer()
{
    if (digitalRead(switch_pins[0]) == LOW && digitalRead(switch_pins[1]) == HIGH && current_layer != 0)
    {
        current_layer = 0; // Switch UP
    }
    else if (digitalRead(switch_pins[0]) == HIGH && digitalRead(switch_pins[1]) == HIGH && current_layer != 1)
    {
        current_layer = 1; // Switch OFF
    }
    else if (digitalRead(switch_pins[0]) == HIGH && digitalRead(switch_pins[1]) == LOW && current_layer != 2)
    {
        current_layer = 2; // Switch DOWN
    }
}

// Actual logic
void setup()
{
    Serial.begin(115200);
    // Button Pins
    for (uint8_t i = 0; i < 7; i++)
    {
        pinMode(button_pins[i], INPUT_PULLUP);
    }
    // LED Pins
    for (uint8_t i = 0; i < 7; i++)
    {
        pinMode(led_pins[i], OUTPUT);
    }
    // Switch Pins
    for (uint8_t i = 0; i < 2; i++)
    {
        pinMode(switch_pins[i], INPUT_PULLUP);
    }
    // Set currently active Layer
    setLayer();
}

void loop()
{
    initBPM(); // Blinking BPM LED - needs to be enabled in your DAW
    setLayer(); // Set which Layer we are using

    // Button operations based on current_layer
    for (uint8_t i = 0; i < 7; i++)
    {
        if (current_layer < 2) // Only layers 0 and 1 are normal operational layers
        {
            poweroffLeds();
            if (button_modes[current_layer][i] == 0)
            {
                handlePushButton(i);
            }
            else if (button_modes[current_layer][i] == 1)
            {
                handleToggleButton(i);
            }
        }
        else if (current_layer == 2) // Layer 2 is the "settings" layer
        {
            showModeLeds();
            handleChangeMode(i);
        }
    }
}



Grumpy_Mike

#5
Aug 01, 2020, 11:10 am Last Edit: Aug 01, 2020, 11:22 am by Grumpy_Mike
Quote
Is what Im wanting the led's to do possible?
Yes.
Try replacing
Code: [Select]
digitalWrite(led_pins[i], HIGH); // Turn the LED on

With
Code: [Select]
digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED on
And do exactly the same in the else if clause for turning the LED off.

I can't fine the definition of the button_states array, it needs to be boolean to work.
When he told you on the GitHub page he was not a programmer he wasn't joaking. It is best to try and learn from good code. The code seems to have the turning on and off of the LEDs in two places, the code and the so called variables file, this is utter madness, I have no idea why he did this. You need to make those changes in both places to be sure the right one is being used.

NervusTwitch

Yes.
Try replacing
Code: [Select]
digitalWrite(led_pins[i], HIGH); // Turn the LED on

With
Code: [Select]
digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED on
And do exactly the same in the else if clause for turning the LED off.

I can't fine the definition of the button_states array, it needs to be boolean to work.
When he told you on the GitHub page he was not a programmer he wasn't joaking. It is best to try and learn from good code.
Thanks for the help.

Just so im clear, anywhere its says what i have,replace with what you have said in all sections of code?

Once i get the leds working correct , then i have to figure out how to add and expression pedal and ill be set.
I have the pots wired to pro micro,just cant really figure out coding to add and where im suppose to put it in my current sketch.


Honestly i wouldnt know good from bad code. I was just wanting a basic foot controller to work with my music software,im no fan of coding.

Now ive built several projects but the are basically joysticks. Ive built from scratch a couple joysticks,throttle, a few button boxes, an led display that works simhub, and rumble motors to my racing pedals.
But i did all this using mmjoy2 of which is all graphical interface and really simplifies things,no coding.

Id rather just found a sketch that fit my needs but the current one is all i found.

All i want is usb midi foot controller with an expression pedal,7 buttons w/led on each,a shift switch to make the switches read another line of midi commands.

After my issues tonight with uploaded sketch connection issues im almost ready to give up and i never give up, drives my wife crazy...lol

NervusTwitch

I tried your suggestion for the leds, they didnt work at all afterwards. I might look into them more tomorrow.
But for now I want to figure out how to the expression pedal coded in of which I havent any idea yet.

But Im off to bed for now

Thanks for the help and anymore help.

cameron206

If I were doing this, I would use the Control_Surface library. It would be pretty straightforward.

Only one part might be tricky:

Quote
All I'm wanting this foot controller to do is to be used as a foot controller for amp changes and effects on/off and leave the corresponding led to each switch lit or off depending on state. Some of the software I will use this with would be Reaper DAW,Amplitube,Bias Amp/FX and so forth.
This. Having the LED toggle when you click a switch is easy.
But do you want it to toggle if you change the state via Mouse, though? Of course you do. If you want it to follow the ~actual state~, not just if you toggle the switch.. then you got some twiddling to do, I think.


Grumpy_Mike

#9
Aug 01, 2020, 10:38 pm Last Edit: Aug 01, 2020, 11:59 pm by Grumpy_Mike
Quote
I tried your suggestion for the leds, they didnt work at all afterwards.
So what you should do on this forum is to post your latest code and say exactly what it did do. Then we can see if you got it right.

Quote
But for now I want to figure out how to the expression pedal coded in of which I havent any idea yet.
Almost trivial, read the pot and if it has changed since last time you read it then send out the reading divided by 8 to the appropriate CC channel number.


Quote
If I were doing this, I would use the Control_Surface library.
Maybe but that code is a lot more "software intense" requiring newcomers to know more software techniques than they normally do when asking these sorts of questions. In the end you give them advice about what to change but they don't actually learn anything and they are stuck in a dependent state. The whole point in answering questions here in my opinion is to teach something that can be built upon.

NervusTwitch

Only one part might be tricky:

This. Having the LED toggle when you click a switch is easy.
But do you want it to toggle if you change the state via Mouse, though? Of course you do. If you want it to follow the ~actual state~, not just if you toggle the switch.. then you got some twiddling to do, I think.


OK  so that never really crossed my mind, something to think about but for me one thing at a time. I'm just starting to get some kind of grasp on this.

NervusTwitch

So what you should do on this forum is to post your latest code and say exactly what it did do. Then we can see if you got it right.
Almost trivial, read the pot and if it has changed since last time you read it then send out the reading divided by 8 to the appropriate CC channel number.

Maybe but that code is a lot more "software intense" requiring newcomers to know more software techniques than they normally do when asking these sorts of questions. In the end you give them advice about what to change but they don't actually learn anything and they are stuck in a dependent state. The whole point in answering questions here in my opinion is to teach something that can be built upon.
Yes I realise now I should have posted the code here after my changes,I was tired and not really thinking to clearly which didnt help either.

I should have researched the software side more since I know nothing at all.Im more a hardware type and dont have much problems building things.

I may work on this some today but health issues keeping me down today.

Thank you everyone for all the help. Still not done but its close.

cameron206

The whole point in answering questions here in my opinion is to teach something that can be built upon.
I totally agree, in principal.
But I also feel the pain (being a non-coder myself), of facing a huge learning curve for something I might only do once or twice.

It was not until I'd made maybe 6 controllers that I felt like learning actual language :)

But you are NOT wrong.

NervusTwitch

I totally agree, in principal.
But I also feel the pain (being a non-coder myself), of facing a huge learning curve for something I might only do once or twice.

It was not until I'd made maybe 6 controllers that I felt like learning actual language :)

But you are NOT wrong.
Ok so you feel about the same as I do. Ive built alot of arduino game based controllers but didnt need to code anything,I am quiet comfortable with it.
But for this midi stuff it looks like coding is required and is the main reason I have put this off for so long since most likely this will just be a once or twice thing for me.

Now I looked into the Control Surface and a couple examples, to me it actually looks easier to use and get a handle on. I do much better when things are more straight forward.

As for this I have been looking for example code that will show me what I want so that I could implement it into my project. But most of the examples I have looked at are more a mixer type board.
Its my learning process, I look at examples that shows what I need then try to add/modify/learn for my needs.

I'm not asking anyone to sit and do the code for me, but I do have a question concerning Control Surface library:


what I want my pedal project to do is:
7 switches each with own led. leds to light on/off depending if the switch is on/off.
Have 6 of those switches bankable.
Have 1 expression pedal.
Be USB

Now Ive seen the array setups and such in the code and thats why this looks much easier to code and edit.

I read that I would need the midiusb control surface library, correct?

could I either get a basic generic code example or a link to one that will show those basic things I mention so can try learning this? Remember I am a total noob so I dont know all the places to look or really what I'm looking at,I barely understand this coding stuff.

Sorry for long post.


NervusTwitch

Yes.
Try replacing
Code: [Select]
digitalWrite(led_pins[i], HIGH); // Turn the LED on

With
Code: [Select]
digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED on
And do exactly the same in the else if clause for turning the LED off.

I can't fine the definition of the button_states array, it needs to be boolean to work.
When he told you on the GitHub page he was not a programmer he wasn't joaking. It is best to try and learn from good code. The code seems to have the turning on and off of the LEDs in two places, the code and the so called variables file, this is utter madness, I have no idea why he did this. You need to make those changes in both places to be sure the right one is being used.
Ok so I tried what you said again. I seem to be missing something here.
All lights still work,but they just give a single flash with each button push.

Also only 1 switch only lights every other switch push but in my amp sim software when testing it it reads every switch push.


Code: [Select]
/*
Arduino USB MIDI FootSwitch
by Hecsall (https://github.com/Hecsall)
*/

// https://www.arduino.cc/en/Reference/MIDIUSB
#include "MIDIUSB.h"
#include "variables.h"

// Utility functions

// Event type is hard-coded (0x09 = note on, 0x08 = note off).
// First parameter is the MIDI channel, combined with the note-on/note-off.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Second parameter (pitch) is the note number (48 = middle C).
// Third parameter is the velocity (0 -> 127, 0 = no_sound, 64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity)
{
    midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity)
{
    midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOff);
}

// Event type hard-coded (0x0B = control change, aka "MIDI CC").
// First parameter is the channel (0-15), combined with the event type.
// Second parameter is the "control change" number (0-119, see top link to midi.org).
// Third parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value)
{
    midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
    MidiUSB.sendMIDI(event);
}



// Button in "Push" mode
void handlePushButton(byte i)
{
    if (digitalRead(button_pins[i]) == LOW && button_states[i] == false)
    {
        controlChange(0, button_layers[current_layer][i], 127);
        MidiUSB.flush();
        button_states[i] = true;
        digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED on
        led_states[i] = true;
        delay(15);
    }
    else if (digitalRead(button_pins[i]) == HIGH && button_states[i] == true)
    {
        controlChange(0, button_layers[current_layer][i], 0);
        MidiUSB.flush();
        button_states[i] = false;
        digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED off
        led_states[i] = false;
        delay(15);
    }
}

// Button in "Toggle" mode
void handleToggleButton(byte i)
{
    buttonState = digitalRead(button_pins[i]);
    if (buttonState != lastButtonState){
        if (buttonState == LOW && button_states[i] == false)
        {
            controlChange(0, button_layers[current_layer][i], 127);
            MidiUSB.flush();
            button_states[i] = true;
            digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED on
            led_states[i] = true;
        }
        else if (buttonState == LOW && button_states[i] == true)
        {
            controlChange(0, button_layers[current_layer][i], 0);
            MidiUSB.flush();
            button_states[i] = false;
            digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED off
            led_states[i] = false;
        }
        delay(100);
    }
    lastButtonState = buttonState;
}

// Button "Change" mode
void handleChangeMode(byte i)
{
    buttonState = digitalRead(button_pins[i]);
    if (buttonState != lastButtonState){
        // Note: only layer 1 (switch OFF) can be customized
        if (buttonState == LOW && button_modes[1][i] == 0 && millis() - time > debounce)
        {
            button_modes[1][i] = 1;
            digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED on
            led_states[i] = true;
            time = millis();
        }
        else if (buttonState == LOW && button_modes[1][i] == 1 && millis() - time > debounce)
        {
            button_modes[1][i] = 0;
            digitalWrite(led_pins[i], ! button_states[i]); // Turn the LED off
            led_states[i] = false;
            time = millis();
        }
        delay(50);
    }
    lastButtonState = buttonState;
}

// Turn off all LEDs
void poweroffLeds()
{
    for (uint8_t i = 0; i < 7; i++)
    {
        digitalWrite(led_pins[i], LOW);
        led_states[i] = false;
    }
}

// Turn on all the current mode LEDs
void showModeLeds()
{
    for (uint8_t i = 0; i < 7; i++)
    {
        if (button_modes[1][i] == 1)
        {
            digitalWrite(led_pins[i], HIGH);
            led_states[i] = true;
        }
    }
}

// Check and set which layer is active
void setLayer()
{
    if (digitalRead(switch_pins[0]) == LOW && digitalRead(switch_pins[1]) == HIGH && current_layer != 0)
    {
        current_layer = 0; // Switch UP
    }
    else if (digitalRead(switch_pins[0]) == HIGH && digitalRead(switch_pins[1]) == HIGH && current_layer != 1)
    {
        current_layer = 1; // Switch OFF
    }
    else if (digitalRead(switch_pins[0]) == HIGH && digitalRead(switch_pins[1]) == LOW && current_layer != 2)
    {
        current_layer = 2; // Switch DOWN
    }
}

// Actual logic
void setup()
{
    Serial.begin(115200);
    // Button Pins
    for (uint8_t i = 0; i < 7; i++)
    {
        pinMode(button_pins[i], INPUT_PULLUP);
    }
    // LED Pins
    for (uint8_t i = 0; i < 7; i++)
    {
        pinMode(led_pins[i], OUTPUT);
    }
    // Switch Pins
    for (uint8_t i = 0; i < 2; i++)
    {
        pinMode(switch_pins[i], INPUT_PULLUP);
    }
    // Set currently active Layer
    setLayer();
}

void loop()
{
   
    // Button operations based on current_layer
    for (uint8_t i = 0; i < 7; i++)
    {
        if (current_layer < 2) // Only layers 0 and 1 are normal operational layers
        {
            poweroffLeds();
            if (button_modes[current_layer][i] == 0)
            {
                handlePushButton(i);
            }
            else if (button_modes[current_layer][i] == 1)
            {
                handleToggleButton(i);
            }
        }
        else if (current_layer == 2) // Layer 2 is the "settings" layer
        {
            showModeLeds();
            handleChangeMode(i);
        }
    }
}

Go Up