Wichtige Info

Die Inhalte, die du hier siehst stelle ich dir ohne Werbeanzeigen und ohne Tracking deiner Daten zur Verfügung. Trotzdem muss ich die Server bezahlen sowie Zeit in Recherche, Umsetzung sowie Mail Support stecken.
Um dies leisten zu können, verlinke ich in einigen Artikeln auf die Plattform Amazon. Alle diese Links nennen sich Afiliate Links. Wenn du dir mit diesem Link etwas kaufst, dann erhalte ich eine kleine Provision. Dies ändert jedoch NICHT den Preis, den du bezahlst!
Falls du mich also unterstützen möchtest, kannst du auf den Link zum Produkt klicken und hilfst mir dabei, dieses Hobby weiter zu betreiben.
Da ich Keine Werbung schalte und keine Spenden sammle, ist dies die einzige Möglichkeit, meine Systeme und mich zu finanzieren. Ich hoffe du kannst das verstehen :)



ESP IDF - Pinmode, GPIO and Extruders/Inputs


Introduction

This article is part of my series on the SDK ESP-IDF.

Taxing inputs and outputs is probably the most important in any project that has to do with microcontrollers. Be it the LED, which should go on or off, the reading of a temperature sensor or the control of a display. Everything needs the external connection to other devices.
Arduino has many developers by configuring with the use of the function pinMode picked up. There are also ESP-IDF (obvious, finally Arduino is based for ESP, on the SDK ESP-IDF :P ).

In this post, we want to see how the inputs and outputs are configured in ESP-IDF and what options you have.

Main part

First of all, we should define what such a pin can do. It is not done with input or output at ESP. However, I am not talking about the type of pin (e.g. DAC, ADC or PWM) but what function a pin can represent via software in ESP-IDF and we look at the following function:

esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)

These Function serves to configure the pin or several GPIO pins on the board. You can see that you need to specify a gpio_config_t configuration that looks like:

typedef struct {
    uint64t pinbit_mask;          /!< GPIO pin: set with bit mask, each bit maps to a GPIO /
    gpiomodet mode;               /!< GPIO mode: set input/output mode                     /
    gpiopullupt pullupen;       /!< GPIO pull-up                                         /
    gpiopulldownt pulldownen;   /!< GPIO pull-down                                       /
    gpiointtypet intrtype;      /!< GPIO interrupt type                                  /
#if SOCGPIOSUPPORTPINHYS_FILTER
    gpiohysctrlmodet hysctrlmode;       /!< GPIO hysteresis: hysteresis filter on slope input    /
#endif

} gpioconfigt;

This is the struct that configures our pins and here we want to work out the most important

pinbit_mask

The component "pinbit_mask" probably defines with the most important in this config, as it indicates which pins are affected. Depending on how deep you are with language C, the name will already tell you what to do.
To define the pins, a so-called. Bit mask required, i.e. in the case a 32-bit long value, which contains all required pins with the aid of Bis Shifts and logical OR connection.

An example:

We want to define the pin GPIO_NUM_20. In this case, we must first create a variable which is 32 BIT long and then perform a left shift with the assigned PIN value (for ESP it is the GPIO number, for example here 20). Here is the following:

uint64t pin_bit_mask = (1ULL << GPIO_NUM_20);

With this line we have created a new 32-bit long variable that has the value 1 (1 Unsingned Long Long). In this way, we certainly have a 32-bit value and no int, which may lead to problems. Once this is done, we will run a so-called "< <" operator. Left shift through. How far this goes is defined by the right value (here GPIO_NUM_20, which is resolved to 20). +

What if we have several pins now? - There is also a solution for this by linking the operations with a logical "Oder".

uint64t pin_bit_mask = ((1ULL<<GPIO_NUM_20) | (1ULL<<GPIO_NUM_21) | (1ULL<<GPIO_NUM_22))

Here you can see that 3 pins are defined (GPIO 20 - 22). These are linked or logically, i.e. a 1 is set at each point, the Pin Shifts (20, 21 and 22), since 0 | 1 = 1.

moderate

Next we have the pin mode, this keeps some in stock, for this reason I only go briefly about the respective values. More information here read.

  • GPIOMODEINPUT: The pin is in input mode, it is used to read data.
  • GPIOMODEOUTPUT: The pin is in output mode, it is used to send data.
  • GPIOMODEINPUTOUTPUT: The pin can be configured both for input and output in mode with open collector.
  • GPIOMODEOUTPUT_OD: The pin is in output mode with open collector, which can be useful if you want to control an external load.
  • GPIOMODEINPUTOUTPUTOD: The pin can be configured both for input and output in mode with open collector.
  • GPIOMODEDISABLE: The pin is disabled.
intrtype

This value is quite interesting as we can define when the pin should trigger an interrupt, for example when a button is pressed. There are also some modis here, which I will only fly briefly.

  • GPIOINTRDISABLE: Disable interrupt. - e.g. usable for outputs.
  • GPIOINTRANYEDGE: Trigger interrupt with rising or falling flank. - Useful if one is to be detected.
  • GPIOINTRNEGEDGE: Unlock interrupt with falling flank.
  • GPIOINTRPOSEDGE: Unlock interrupt with rising flank. - Here, the example button would only detect the rising edge (thus push button) (of course depends on the configuration. If the button switches to ground and thus the signal falls, it would be different to behave ^^^.
  • GPIOINTRHIGH_LEVEL: Trigger interrupt at high level. - Here's the same game, but the Interrput comes first, at a high level and not already at the change. It is waiting for a stable high level. Here, for example, one does not have the risk of bounce effects, which must be observed in previous mode.
  • GPIOINTRLOW_LEVEL: Trigger interrupt at low level.
pullupen / pulldownen

The values for these two components are each 0x0 or 0x1 so True/False. Depending on what you define here, the internal pull-up or pull-down residue is activated or shut off.

hysctrlmode

Finally, we have the so-called hysteresis fashion. This is used to minimize prell effects (bouncing) with, for example, switches or other (dynamic) sensors/signal sources or in the best case to suppress a clear state (i.e. 1 or 0). However, this mode is not supported by all systems. In summary, this mode can decide, in the case of signals near the switching threshold, whether it should already be changed to another state or not. In the best case, faulty triggering can be completely suppressed. Here the possible value is also 0x0 or 0x1, i.e. True doer False.

An example

Finally, there are 2 examples of how a configuration can look for an input or Output.

#include <stdio.h>
#include "driver/gpio.h"

//define all needed led pins
#define OkLED GPIO_NUM_2
#define WarnLED GPIO_NUM_3
#define ErrorLED GPIO_NUM_12
#define InfoLED GPIO_NUM_13

//Define all needed button pins
#define Btn1 GPIO_NUM_20
#define Btn2 GPIO_NUM_21
#define Btn3 GPIO_NUM_22

//Create the bit mask for each output and input pins.
#define GPIO_BIT_MASK_OUTPUT  ((1ULL<<OkLED) | (1ULL<<WarnLED) | (1ULL<<ErrorLED) | (1ULL<<InfoLED)) 
#define GPIO_BIT_MASK_INPUT  ((1ULL<<Btn1) | (1ULL<<Btn2) | (1ULL<<Btn3)) 

void app_main(void)
{
    
    gpio_config_t o_conf;
	o_conf.intr_type = GPIO_INTR_DISABLE;
	o_conf.mode = GPIO_MODE_OUTPUT;
	o_conf.pin_bit_mask = GPIO_BIT_MASK_OUTPUT;
	o_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
	o_conf.pull_up_en = GPIO_PULLUP_DISABLE;
    esp_err_t res_output_pin_conf = gpio_config(&o_conf);

    gpio_config_t i_conf;
	i_conf.intr_type = GPIO_INTR_ANYEDGE;
	i_conf.mode = GPIO_MODE_INPUT;
	i_conf.pin_bit_mask = GPIO_BIT_MASK_INPUT;
	i_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
	i_conf.pull_up_en = GPIO_PULLUP_DISABLE;
    esp_err_t res_input_pin_conf = gpio_config(&i_conf);

    while(1)
    {
        if (gpio_get_level(Btn1) == 1) {
            
            gpio_set_level(OkLED, 1);
            gpio_set_level(InfoLED, 1);
        } else {
            gpio_set_level(OkLED, 0);
            gpio_set_level(InfoLED, 0);
        }
    }
}

This is a very simple example. With the variables res_input_pin_conf and res_output_pin_conf could still be checked before the actual program start if everything worked. Here you can check whether the variable is either "ESP_OK" (here 0) or alternatively "ESP_FAIL" (here -1) corresponds.

That was already the case, with this example, the button would activate the OkLED and InfoLED at pressure.


Back…