ESP32 Tasterauswertutn Probleme

OP #7883298
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.

#7883304
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.

#7883345
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.

OP #7883438
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren