0

I am using digital pins (2,3,4,5) to play midi notes on and off with 3pdt switches with pull down 10k resistor between input pin and ground.

However when I press button 2 randomly at different time interval it sometimes shows pin 3 high in the monitor. (after reading forums here I have realised that it might be due to big switches that I am using where the physical contact plates might be reason for this). I have even changed wires and isolated them from each other to rule out the noise from the wires. I have checked all the connections and soldered the Arduino board pins with best possible skills that I have and tracks are all clear.

Same case occurs between other buttons as but its not always. However after reading about Debounce I have made changes to the code as following, now I got the error only once after that I havent seen it. Can someone have look at the code and advice me if I have assigned Debounce function to multiple switches correctly and if not, what should it be as I am new with coding Since I am using 3pdt switch I have added switch mode..

#include <MIDI.h>

int buttonPin[] = {2, 3, 4, 5};
byte mode[] = {0, 0 , 0 ,0};
boolean currentState = LOW;
boolean lastState = LOW;
int buttonPinM[] = {6, 7, 8, 9};
byte mode1[] = {0, 0, 0, 0};

boolean currentState1 = LOW;
boolean lastState1 = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;

void setup (){
    MIDI.begin(MIDI_CHANNEL_OMNI);

    int i;
    for (i = 0; i < 4; i++) {
        pinMode(buttonPin[i], INPUT);
    }
    int j;
    for (j = 0; j < 4; j++) {
        pinMode(buttonPinM[j], INPUT);
    }

    {
        int i;
        for (i = 0; i < 4; i++);
    }
    {
        int j;
        for (j = 0; j < 4; j++);
    }
}

// This will track which pin/mode we're using

int j = 0;
int i = 0;

void loop () {
    {  
        currentState = digitalRead(buttonPin[i]);

        if ( (millis() - lastDebounceTime) > debounceDelay) {
            switch (mode[i]) {
                case 0:
                    if (currentState == HIGH) {
                        MIDI.sendNoteOff (i+55, 0, 1);
                        mode[i] = 1;
                        lastDebounceTime = millis();
                    }
                    break;
                case 1:
                    if (currentState == HIGH)
                        mode[i] = 2;
                    break;
                case 2:
                    if (currentState == LOW) {
                        MIDI.sendNoteOn (i+55, 127, 1);
                        mode[i] = 3;
                        lastDebounceTime = millis();
                    }
                    break;
                case 3:
                    if (currentState == LOW)
                        mode[i] = 0;
                    break;
            }
        }
        lastState = currentState;
        if (++i > 3)
            i = 0;  
    }
    {
        currentState1 = digitalRead(buttonPinM[j]);
        if ( (millis() - lastDebounceTime) > debounceDelay) {
            switch (mode1[j]) {
                case 0:
                    if (currentState1 == HIGH ) {
                        MIDI.sendNoteOn (j+61, 127, 1);
                        mode1[j] = 1;
                        lastDebounceTime = millis();
                    }
                    break;
                case 1:
                    if (currentState1 == HIGH)
                        mode1[j] = 2;
                    break;
                case 2:
                    if (currentState1 == LOW) {
                        MIDI.sendNoteOff (j+61, 0, 1);
                        mode1[j] = 3;
                        lastDebounceTime = millis();
                    }
                    break;
                case 3:
                    if (currentState1 == LOW)
                        mode1[j] = 0;
                break;
            }
        }
        lastState1 = currentState1;
        if (++j > 3)
            j = 0;   
    }
}
  • Please edit your post and format the code using the code formatting markdown (four leading spaces). For help see Markdown help. You should be able to do this by selecting the code and pressing Ctrl+K to have your browser do this for you. – Nick Gammon Mar 16 '16 at 9:06
  • Usually when something "fluctuates" it means that it had not a fixed state: this is usual when you use a button without a pull-up/pull-down. But if you have a double-throw (xxDT) switch and connected BOTH vcc and ground to its terminals, well, maybe it's just a bad contact... – frarugi87 Mar 16 '16 at 9:32
  • @frarugi87 I cross checked all that and changed the pcb as well. Do you think its the code?? – Ashish Mar 16 '16 at 10:00
  • @NickGammon have made the changes. – Ashish Mar 16 '16 at 10:01
  • Your code is very hard to read. The IDE has an auto-format feature. Please use it and re-submit your code. Also please include (an image of) your wiring. Descriptions of wiring rarely do the actual situation justice. – Nick Gammon Mar 16 '16 at 10:39
0

Posting here since it is quite long, but it's not a complete answer, just a few thoughts and a possible improvement.

Ok, so there are a couple of things in your code I don't understand:

1: in the setup()

{
    int i;
    for (i = 0; i < 4; i++);
}
{
    int j;
    for (j = 0; j < 4; j++);
}

What are these for?

2: debouncing

You are not implementing it correctly, at least not for me. You are reading the button every 50ms, without debouncing. Ok, you won't see "bounces", but there are better solutions (see later).

3: modes 1 and 3

They are quite useless. What are they for?

4: pins 6,7,8,9

What are they for?

5: variable laststate

What is it for? You never use it

6: updating one button per loop

Is it needed? I mean, you are just updating one button per loop instead of all of them for each loop.

In the end

Ok, now my suggestions, apart from learning to indent the code (otherwise it's impossible to read it): I always use the bounce2 class to debounce a button, since it contains everything inside and.. Well, it works well. It can also detect the rising and falling edges of the button, thing that you need if I interpreted correctly your code.

One more thing: debounce delay can be lowered (even to just 5ms):

#include <MIDI.h>
#include <Bounce2.h>

int buttonPin[] = {2, 3, 4, 5};
int buttonPinM[] = {6, 7, 8, 9};

Bounce debouncers[4];
Bounce debouncersM[4];

int debounceDelay = 50; // Usually is lower - even 5ms is fine
uint8_t i = 0;

void setup ()
{
    MIDI.begin(MIDI_CHANNEL_OMNI);

    for (i = 0; i < 4; i++)
    {
        pinMode(buttonPin[i], INPUT);
        debouncers[i].attach(buttonPin[i]);
        debouncers[i].interval(debounceDelay);

        pinMode(buttonPinM[i], INPUT);
        debouncersM[i].attach(buttonPinM[i]);
        debouncersM[i].interval(debounceDelay);
    }
}

void loop ()
{
    for (i = 0; i < 4; i++)
    {
        debouncers[i].update();
        debouncersM[i].update();
    }

    for (i = 0; i < 4; i++)
    {
        if (debouncers[i].rose()) // button i switched from 0 to 1
            MIDI.sendNoteOff(i+55, 0, 1);
        if (debouncers[i].fell()) // button i switched from 1 to 0
            MIDI.sendNoteOn (i+55, 127, 1);
        if (debouncersM[i].rose()) // button i switched from 0 to 1
            MIDI.sendNoteOn (i+61, 127, 1);
        if (debouncersM[i].fell()) // button i switched from 1 to 0
            MIDI.sendNoteOff(i+61, 0, 1);
    }
}
  • Thanks @frarugi87 1.In the set up mode INT i and j are for 2 groups of switches (4 switches each) and have different functions in this code One group of switches are sending NoteOn command when the Input is high and other group will send NoteOff command when the Input is High. 2.I might be absolutely wrong with my debounce logic with this code 3. BY mode 1 and 3 you mean Case 1 and 3 right???Since its a 3pdt where the switch physically locks the State of the switch I thought its better to make CASE but I will try your code and update if it works with my switch – Ashish Mar 16 '16 at 11:29
  • @Ashish well, you always have just two states. You can use a switch-case approach, but cases 1 and 3 are useless, since you exit from that mode (I called them modes since the variable mode decides the case) immediately (the condition is the same as the previous one). Anyway I suggest you the bounce approach: easier, faster and less error prone – frarugi87 Mar 16 '16 at 11:38
  • @fraugi87 I understood what you said and it makes sense. Thank you for your prompt reply. I will do some test and revert back asap!!! – Ashish Mar 16 '16 at 11:49
  • @fraugi87 I tried your code and its working fine. I didnt make any changes just your code and it works. Earlier you mentioned its not a complete solution. Is there more to improvise?? – Ashish Mar 16 '16 at 16:56
  • @Ashish I said it was not complete because I did not understand where the problem was, and so mine were just "generic" advices. If it works, this becomes a real solution, but again I do not understand why this works and yours not ;) Maybe just because of the incorrect debouncing, but anyway... The only improvement you can make is to remove the division between the two button sets, but it's not a practical improvement, just a more readable solution.. – frarugi87 Mar 17 '16 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.