ESP32 (9) – Basic I/O

luca 07/02/2017 3

Iniziamo, con il tutorial di oggi, ad utilizzare i pin di I/O del chip esp32. Il chip mette a disposizione 40 General Purpose I/O pads (GPIO), ovvero 40 “contatti” che possono essere utilizzati per diverse funzionalità di ingresso (input) e uscita (output).

La gestione di tali pads è abbastanza complessa: il chip esp32 consente infatti di “mappare” le diverse periferiche interne (UART, SPI…) sui vari pad tramite matrici configurabili via software. All’interno del technical reference manual è presente un diagramma che illustra questo meccanismo:

esp32-io01

In questo primo articolo non andrò ad illustrarvi tutti i diversi registri e configurazioni… è importante però tenere presente sin da subito che per utilizzare un pin, anche solo con funzioni di I/O base, è necessaria una configurazione iniziale. Il driver del framework da includere nel proprio codice per avere a disposizione tutte le funzioni descritte di seguito è:

#include "driver/gpio.h"

Funzionalità I/O base

Come detto, prima di poter utilizzare un pin è necessario impostare i vari registri che ne configurano i collegamenti interni. Dopo il reset del chip, molti pin sono automaticamente configurati per funzionalità di I/O base. Possiamo assicurarci che il pin scelto sia configurato per funzionalità di I/O con la funzione:

void gpio_pad_select_gpio(uint8_t gpio_num);

Nel funzionamento come pin di I/O, i pin del chip esp32 possono essere configurati in 3 direzioni:

  • input
  • output
  • open drain

Open Drain

Un pin configurato come open drain può soltanto accettare corrente in ingresso (se configurato a livello logico 0) ma non fornire corrente in uscita; se infatti è configurato a livello logico 1, il pin risulta di fatto disconnesso.

Le relative costanti sono definite nel file gpio.h:

esp32-io02

Vi sono alcune eccezioni, in particolare i pins > 33 possono essere utilizzati solo come input.

E’ possibile configurare la direzione di un pin con la funzione:

esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);

gpio_num indica il pin da configurare, mentre mode è una delle tre modalità descritte sopra. Per configurare ad esempio il pin 13 come output, il comando da utilizzare sarà:

gpio_set_direction(GPIO_NUM_13, GPIO_MODE_DEF_OUTPUT);

Possiamo leggere lo stato del pin, se configurato come input, con la funzione:

int gpio_get_level(gpio_num_t gpio_num);

mentre se il pin è configurato come output o open drain, possiamo cambiarne lo stato con:

esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);

Pull-up e pull-down

Ogni pin è anche dotato di resistenze di pull-up pull-down, attivabili tramite la funzione:

esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);

le costanti possibili sono:

esp32-io03

In alternativa esistono funzioni per abilitare/disabilitare le resistenze su ogni pin:

esp_err_t gpio_pullup_en(gpio_num_t gpio_num);
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num);
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);

Configurazioni multiple

Finora abbiamo visto come configurare singolarmente i vari pin. Esiste la possibilità di configurare simultaneamente più pin, applicando a tutti la medesima configurazione.

Per prima cosa va definita una struct di tipo gpio_config_t:

gpio_config_t pin_config;

I parametri configurabili sono:

esp32-io04

I pin oggetto della configurazione multipla vengono inseriti nella variabile pin_bit_mask concatenando le costanti GPIO_SEL_x con l’operatore OR (|). Vediamo un paio di esempi (degli interrupt parlerò più diffusamente in un prossimo post, per ora saranno disabilitati):

  • pin 2, 3 e 7 configurati come output, pull-up e down disabilitati:
pin_config.pin_bit_mask = GPIO_SEL_2 | GPIO_SEL_3 | GPIO_SEL_7;
pin_config.mode = GPIO_MODE_OUTPUT;
pin_config.pull_up_en = GPIO_PULLUP_DISABLE;
pin_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
pin_config.intr_type = GPIO_PIN_INTR_DISABLE;
  • pin 6 e 8 configurati come input con resistenza di pull-up abilitata:
pin_config.pin_bit_mask = GPIO_SEL_6 | GPIO_SEL_8;
pin_config.mode = GPIO_MODE_INPUT;
pin_config.pull_up_en = GPIO_PULLUP_ENABLE;
pin_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
pin_config.intr_type = GPIO_PIN_INTR_DISABLE;

La configurazione viene infine applicata con la funzione gpio_config(&pin_config).

Codice

Visti i concetti base affrontati in questo tutorial, non ho preparato dei programmi dedicati… insieme al framework sono infatti distribuiti due esempi che illustrano quanto spiegato:

3 Comments »

  1. Karl Britton 16/04/2017 at 15:41 - Reply

    Hi Luca

    I have read most of your web-site with interest. I wish I had found it 4 weeks ago while trying to set up Eclipse!
    Excellent tutorials!

    Would it be possible for you to explain how to send a data packet from a PC to the ESP32 on the same wireless home network (not accessing the external web)?

    My goal is to send a simple graphic (much like your LED matrix project) to the ESP32 and use the I/O (SPI) to control some LEDs.

    Would it require the ESP32 to have a fixed IP address or could the network be scanned to get the automatically assigned IP address?

    Many thanks in advance.

    • luca 19/04/2017 at 09:19 - Reply

      Hi Karl, thanks for your comment! I’m working on a tutorial for using ESP32 as a server and… something also to solve the problem to “find” the ESP32 on the network ;)

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi