De Arduino digitale ingang fluctueert met aangrenzende pinnen

Ik gebruik digitale pinnen (2,3,4,5) om midi-tonen aan en uit te spelen met 3pdt-switches met een pull-down 10k-weerstand tussen ingangspen en aarde.

Nochtans wanneer ik knoop 2 willekeurig in verschillend tijdsinterval druk toont het soms pin 3 hoog in de monitor. (na het lezen van fora hier heb ik begrepen dat dit te wijten kan zijn aan grote schakelaars die ik gebruik waar de fysieke contactplaten reden voor kunnen zijn). Ik heb zelfs draden vervangen en ze van elkaar geïsoleerd om het geluid van de draden uit te sluiten. Ik heb alle verbindingen gecontroleerd en de Arduino-bordpinnen gesoldeerd met de best mogelijke vaardigheden die ik heb en de tracks zijn allemaal duidelijk.

Hetzelfde geval doet zich voor tussen andere knoppen, maar is niet altijd. Nochtans na lezing over Ontbinding heb ik veranderingen in de code als volgend gemaakt, nu kreeg ik de fout slechts eenmaal daarna die ik het niet heb gezien. Kan iemand de code hebben bekeken en mij adviseren als ik de Debounce-functie correct aan meerdere switches heb toegewezen en zo niet, wat zou dat dan zijn, want ik ben nieuw met codering Omdat ik de 3pdt-schakelaar gebruik, heb ik de schakelmodus toegevoegd ..

#include 

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;   
    }
}
0
@ frarugi87 Ik heb dat allemaal gecontroleerd en de print ook veranderd. Denk je dat het de code is ??
toegevoegd de auteur JJM Driessen, de bron
@NickGammon heeft de wijzigingen aangebracht.
toegevoegd de auteur JJM Driessen, de bron
Verricht bewerk je bericht en formatteer de code met behulp van de code opmaakmarkering (vier voorloopspaties). Voor hulp, zie Hulp bij het wegvallen . U zou dit moeten kunnen doen door de code te selecteren en op Ctrl + K te drukken om uw browser dit voor u te laten doen.
toegevoegd de auteur Nick Gammon, de bron
Je code is heel moeilijk te lezen. De IDE heeft een functie voor automatisch formatteren. Gebruik het en dien uw code opnieuw in. Vermeld ook (een afbeelding van) uw bedrading. Beschrijvingen van de bedrading zelden doen de feitelijke situatie recht.
toegevoegd de auteur Nick Gammon, de bron
Meestal als iets "fluctueert" betekent dit dat het geen vaste staat had: dit is gebruikelijk wanneer je een knop gebruikt zonder een pull-up/pull-down. Maar als je een double-throw (xxDT) -schakelaar hebt en zowel VECT als aarde met de terminals verbindt, wel, misschien is het gewoon een slecht contact ...
toegevoegd de auteur Tom Collins, de bron

1 antwoord

Hier plaatsen omdat het vrij lang is, maar het is geen volledig antwoord, slechts een paar gedachten en een mogelijke verbetering.

Ok, dus er zijn een paar dingen in je code die ik niet begrijp:

1: in de setup()

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

Waar zijn deze voor?

2: debouncing

U implementeert het niet correct, althans niet voor mij. Je leest de knop elke 50ms, zonder te debatteren. Ok, je zult geen "bounces" zien, maar er zijn betere oplossingen (zie later).

3: modi 1 en 3

Ze zijn tamelijk nutteloos. Waar zijn die voor?

4: pins 6,7,8,9

Waar zijn die voor?

5: variabele laststate

Waar is het voor? Je gebruikt het nooit

6: één knop per lus bijwerken

Is het nodig? Ik bedoel, je werkt slechts één knop per lus bij in plaats van allemaal voor elke lus.

In the end

Oké, nu mijn suggesties, behalve dat ik de code moet laten inspringen (anders is het onmogelijk om het te lezen): ik gebruik altijd de bounce2-klasse om een ​​knop te negeren, omdat deze alles bevat van binnen en .. Nou, het werkt goed. Het kan ook de stijgende en dalende randen van de knop detecteren, iets dat je nodig hebt als ik je code correct heb geïnterpreteerd.

Nog een ding: vertragingsvertraging kan worden verlaagd (zelfs tot slechts 5ms):

#include 
#include 

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);
    }
}
0
toegevoegd
Bedankt @ frarugi87 1.In de instelmodus zijn INT i en j voor 2 groepen schakelaars (elk 4 schakelaars) en hebben verschillende functies in deze code. Een groep schakelaars verzendt de NoteOn-opdracht wanneer de invoer hoog is en een andere groep verzendt NoteOff-opdracht wanneer de invoer hoog is. 2.Ik zou absoluut fout kunnen zijn met mijn debounce-logica met deze code 3. BY-modus 1 en 3 bedoel je Case 1 en 3 right ??? Aangezien het een 3pdt is waarbij de switch de status van de switch fysiek vergrendelt, vond ik het beter om maak CASE, maar ik zal je code proberen en updaten als het werkt met mijn switch
toegevoegd de auteur JJM Driessen, de bron
@ fraugi87 Ik begreep wat je zei en het is logisch. Bedankt voor je snelle antwoord. Ik zal wat testen doen en zo snel mogelijk terugkeren !!!
toegevoegd de auteur JJM Driessen, de bron
@ fraugi87 Ik heb je code geprobeerd en het werkt prima. Ik heb geen wijzigingen aangebracht alleen uw code en het werkt. Eerder zei u al dat het geen complete oplossing is. Is er meer om te improviseren ??
toegevoegd de auteur JJM Driessen, de bron
Mijn code werkt ook, maar soms lezen de digitale pinnen een ander nummer. Misschien heb je gelijk over de Debouncing :-)
toegevoegd de auteur JJM Driessen, de bron
@ Wees goed, je hebt altijd maar twee staten. Je kunt een switch-case aanpak gebruiken, maar cases 1 en 3 zijn nutteloos, omdat je die modus verlaat (ik heb ze modes genoemd sinds de variabele mode de case beslist) onmiddellijk (de voorwaarde is hetzelfde zoals de vorige). In elk geval stel ik je de bounce-aanpak voor: makkelijker, sneller en minder foutgevoelig
toegevoegd de auteur Tom Collins, de bron
@Ashish Ik zei dat het niet compleet was omdat ik niet begreep waar het probleem lag, en dus waren de mijne slechts 'generieke' adviezen. Als het werkt, wordt dit een echte oplossing, maar nogmaals, ik begrijp niet waarom dit werkt en het jouwe niet;) Misschien alleen vanwege de onjuiste debouncing, maar in ieder geval ... De enige verbetering die je kunt maken, is het verwijderen van de scheiding tussen de twee knopsets, maar het is geen praktische verbetering, alleen een beter leesbare oplossing ..
toegevoegd de auteur Tom Collins, de bron