Forum: Mikrocontroller und Digitale Elektronik ESP32 Tasterauswertutn Probleme


von Chandler B. (chandler)


Lesenswert?

Hallo,
ich habe ein Problem mit der Tastenauswertung an einem ESP32-Wroom-32 
Modul.
Ich habe 4 Taster (Pin 36, 39, 35,34) mit einem Pulldown-Widerstand 
angeschlossen.
Das Problem welches ich habe ist, dass wenn ich einen Taster drücke, 
alle anderen Taster den selben Zustand annehmen.
1
typedef enum
2
{
3
    PLAY,
4
    STOP,
5
    NEXT,
6
    SHUTDOWN,
7
    NUM_OF_BUTTONS
8
} ButtonName_te;
9
10
typedef enum
11
{
12
    LOW,
13
    RISING,
14
    HIGH,
15
    FALLING,
16
    ERROR
17
} ButtonState_te;
18
19
typedef struct
20
{
21
    ButtonName_te   name_e;
22
    gpio_num_t      gpioNum;
23
    ButtonState_te  state_e;
24
    ButtonState_te  oldState_e;
25
    bool            stateChanged_b;
26
} Button_ts;
1
        case INIT:
2
        {
3
            for (ButtonName_te x=PLAY; x<NUM_OF_BUTTONS; x++)
4
            {
5
                ESP_LOGI(TAG, "IO %d: %d ", x, button_as[x].gpioNum);
6
                gpio_set_direction(button_as[x].gpioNum, GPIO_MODE_INPUT);
7
                gpio_input_enable(button_as[x].gpioNum);
8
                gpio_set_pull_mode(button_as[x].gpioNum, GPIO_PULLDOWN_ONLY);
9
10
                button_as[x].state_e = LOW;
11
                button_as[x].oldState_e = LOW;
12
            }
13
            taskState_e = RUNNING;
14
            break;
15
        }
16
    
17
        case RUNNING:
18
        {
19
            for (ButtonName_te x=PLAY; x<NUM_OF_BUTTONS; x++)
20
            {
21
                getButtonState_v(&button_as[x]);
22
            }
23
24
            if (true == button_as[PLAY].stateChanged_b)
25
            {
26
                ESP_LOGI(TAG, "BUTTON PLAY Status Changed to: %d", button_as[PLAY].state_e);
27
                button_as[PLAY].stateChanged_b = false;
28
            }
29
            if (true == button_as[STOP].stateChanged_b)
30
            {
31
                
32
                ESP_LOGI(TAG, "BUTTON STOP Status Changed to: %d", button_as[STOP].state_e);
33
                button_as[STOP].stateChanged_b = false;
34
            }
35
            if (true == button_as[NEXT].stateChanged_b)
36
            {
37
                
38
                ESP_LOGI(TAG, "BUTTON NEXT Status Changed to: %d", button_as[NEXT].state_e);
39
                button_as[NEXT].stateChanged_b = false;
40
            }
41
            if (true == button_as[SHUTDOWN].stateChanged_b)
42
            {
43
                
44
                ESP_LOGI(TAG, "BUTTON SHUTDOWN Status Changed to: %d", button_as[SHUTDOWN].state_e);
45
                button_as[SHUTDOWN].stateChanged_b = false;
46
            }
47
            break;
48
        }

Tastenauswertung:
1
static void getButtonState_v(Button_ts* button_ps)
2
{
3
    if (LOW == button_ps->state_e)
4
    {
5
        if (FALLING == button_ps->oldState_e)
6
        {
7
            button_ps->oldState_e = LOW;
8
            button_ps->stateChanged_b = true;
9
        }
10
        if (1 == gpio_get_level(button_ps->gpioNum))
11
        {
12
            ESP_LOGI(TAG, "Button: %d", button_ps->gpioNum);
13
            button_ps->oldState_e = LOW;
14
            button_ps->state_e = RISING;
15
        }
16
    }
17
    else if (RISING == button_ps->state_e)
18
    {
19
        if (1 == gpio_get_level(button_ps->gpioNum))
20
        {
21
            button_ps->oldState_e = RISING;
22
            button_ps->state_e = HIGH;
23
        }
24
        else
25
        {
26
            button_ps->state_e = LOW;
27
        }
28
    }
29
    else if (HIGH == button_ps->state_e)
30
    {
31
        if (RISING == button_ps->oldState_e)
32
        {
33
            button_ps->oldState_e = HIGH;
34
            button_ps->stateChanged_b = true;
35
        }
36
        if (0 == gpio_get_level(button_ps->gpioNum))
37
        {
38
            button_ps->state_e = FALLING;
39
        }
40
    }
41
    else if (FALLING == button_ps->state_e)
42
    {
43
        if (0 == gpio_get_level(button_ps->gpioNum))
44
        {
45
            button_ps->oldState_e = FALLING;
46
            button_ps->state_e = LOW;
47
        }
48
        else
49
        {
50
            button_ps->state_e = HIGH;
51
        }
52
    }
53
}

Die Ausgabe aus dem INIT-State
1
I (344) GPIO: IO 0: 36
2
I (364) GPIO: IO 1: 39
3
I (364) GPIO: IO 2: 35
4
I (364) GPIO: IO 3: 34

Wenn ich jetzt eine Taste drücke (egal welche), werden alle Buttons 
getriggert. Ausgabe aus dem RUNNING-State wenn ich eine Taste Drücke
1
I (170074) GPIO: BUTTON PLAY Status Changed to: 2
2
I (170074) GPIO: BUTTON STOP Status Changed to: 2
3
I (170074) GPIO: BUTTON NEXT Status Changed to: 2
4
I (170074) GPIO: BUTTON SHUTDOWN Status Changed to: 2

Gleiches passiert, wenn ich den Taster loslasse.

von Rolf (rolf22)


Lesenswert?

Chandler B. schrieb:
> Ich habe 4 Taster (Pin 36, 39, 35,34) mit einem Pulldown-Widerstand
> angeschlossen.

Wer wird dieses lange Programm studieren, wenn er statt Schaltplan nur 
eine Wischiwaschi-Aussage bekommt?

> Das Problem welches ich habe ist, dass wenn ich einen Taster drücke,
> alle anderen Taster den selben Zustand annehmen.

Ach, die anderen Taster bewegen sich dann mit? Vielleicht ist Klebstoff 
dazwischen geraten? SCNR.

von Thomas W. (datenreisender)


Lesenswert?

Chandler B. schrieb:
> Hallo,
> ich habe ein Problem mit der Tastenauswertung an einem ESP32-Wroom-32
> Modul.
> Ich habe 4 Taster (Pin 36, 39, 35,34) mit einem Pulldown-Widerstand
> angeschlossen.

Ein Widerstand fuer vier Taster?

Schaltplan bitte!

von Chandler B. (chandler)


Angehängte Dateien:

Lesenswert?

Rolf schrieb:
> Wer wird dieses lange Programm studieren, wenn er statt Schaltplan nur
> eine Wischiwaschi-Aussage bekommt?
Anbei der Schaltplan
Jeder Taster hat seinen eigenen Widerstand.

von Anton V. (anton_elfi)


Lesenswert?

Erstmal direkt am µC Eingang messen, was bei Tastendruck passiert und so 
Verdrahtungsfehler ausschließen.

Danach würde ich zur Not die KI über den Code befragen.

Viele Grüße!

von Peter D. (peda)


Lesenswert?

Wer soll mit den rausgerissenen Schnipselchen was anfangen können?
Benutzt Du eine Entprellib?
Poste einen compilierbaren Code (0 errors, 0 warnings) als Anhang, d.h. 
nicht eingebettet!

Es sieht so aus, als machten unter RUNNING alle ifs das gleiche. Dann 
ersetze das if-Monster durch eine Schleife. Das ist weniger Code, besser 
zu verstehen und man muß es nur einmal lesen.

Tasten schaltet man vorzugsweise low aktiv. Dann besteht weniger Gefahr, 
die VCC versehentlich kurzzuschließen.

von N. M. (mani)


Lesenswert?

Aus was für einem context heraus wird denn dein Switch Case aufgerufen 
und wie ist button_as[] definiert?

Was passiert wenn bei init ein anderer Zustand als Low an den Tastern 
anliegt?

von Chandler B. (chandler)


Lesenswert?

N. M. schrieb:
> Aus was für einem context heraus wird denn dein Switch Case aufgerufen

das Switch-Case wird zyklisch aufgerufen
1
static void gpioTask_v(void * pvParameters)
2
{
3
    TickType_t xLastWakeTime;
4
    const TickType_t xFrequency = 20;
5
6
    for( ;; )
7
    {
8
        // Wait for the next cycle.
9
        xTaskDelayUntil( &xLastWakeTime, xFrequency );
10
11
        gpioExec_v();
12
        // Perform action here. xWasDelayed value can be used to determine
13
        // whether a deadline was missed if the code here took too long.
14
    }
15
}
16
17
static void gpioExec_v(void)
18
{
19
    switch(taskState_e)
20
    {
21
        case INIT:
22
        {
23
... ... ...
24
        }
25
    
26
        case RUNNING:
27
        {
28
... ... ...
29
        }
30
    }
31
}

N. M. schrieb:
> und wie ist button_as[] definiert?
1
static Button_ts button_as[NUM_OF_BUTTONS] =
2
{
3
    {
4
        .name_e = PLAY,
5
        .gpioNum = GPIO_INPUT_IO_PLAY,
6
        .state_e = LOW,
7
        .oldState_e = LOW,
8
        .stateChanged_b = false
9
    },
10
    {
11
        .name_e = STOP,
12
        .gpioNum = GPIO_INPUT_IO_STOP,
13
        .state_e = LOW,
14
        .oldState_e = LOW,
15
        .stateChanged_b = false
16
    },
17
    {
18
        .name_e = NEXT,
19
        .gpioNum = GPIO_INPUT_IO_NEXT,
20
        .state_e = LOW,
21
        .oldState_e = LOW,
22
        .stateChanged_b = false
23
    },
24
    {
25
        .name_e = SHUTDOWN,
26
        .gpioNum = GPIO_INPUT_IO_SHUTDOWN,
27
        .state_e = LOW,
28
        .oldState_e = LOW,
29
        .stateChanged_b = false
30
    }
31
};

N. M. schrieb:
> Was passiert wenn bei init ein anderer Zustand als Low an den Tastern
> anliegt?

Das sollte egal sein. Erst wenn es von LOW auf HIGH wechselt sollte der 
Zustandswechsel erkannt werden.

von Joachim B. (jar)


Lesenswert?

Chandler B. schrieb:
> Erst wenn es von LOW auf HIGH wechselt sollte der
> Zustandswechsel erkannt werden

und wie entprellst du?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.