ESP32 (30) – HTTP server in modalità SoftAP

luca 29/01/2018 9

Una delle domande che ricevo più spesso tramite il form sul sito o nella pagina Facebook è se sia possibile pubblicare un server HTTP quando il chip esp32 è in modalità SoftAP, ovvero quando pubblica una propria rete wifi.

In precedenti tutorial (18 – Access Point20 – Webserver) ho già trattato separatamente le due tematiche, oggi vediamo come combinarle.

Access Point

Iniziamo con la definizione dei parametri della rete TCP/IP che sarà pubblicata dal chip esp32. Dobbiamo scegliere un piano di indirizzamento, ovvero quali indirizzi IP apparterranno alla rete. Possiamo scegliere tra gli indirizzi IP dedicati dalla IANA alle reti private (RFC1918):

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
I numeri /8/12/16 indicano, in forma ridotta, la maschera di rete. Ad esempio /8 significa che alla rete 10.0.0.0/8 appartengono tutti gli indirizzi da 10.0.0.1 a 10.255.255.254, per un totale di 16.777.216 indirizzi possibili. Grazie al subnetting è possibile tagliare una rete in sottoreti più piccole.

In questo esempio utilizzerò la rete 192.168.1.0 con netmask 255.255.255.0 (/24), ovvero una rete con 254 indirizzi possibili (192.168.1.1 – 192.168.1.254). Al chip esp32 dovrà essere assegnato staticamente un indirizzo appartenente a tale rete; per semplicità ho scelto il primo (192.168.1.1):

tcpip_adapter_ip_info_t info;
memset(&info, 0, sizeof(info));
IP4_ADDR(&info.ip, 192, 168, 1, 1);
IP4_ADDR(&info.gw, 192, 168, 1, 1);
IP4_ADDR(&info.netmask, 255, 255, 255, 0);
ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info));

I vari dispositivi che si collegheranno alla rete dovranno ricevere dinamicamente un indirizzo IP, grazie al servizio DHCP. Per utilizzarlo nel mio programma devo stopparlo prima della configurazione dei parametri di rete, quindi avviarlo al termine della configurazione:

ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP));
[...]
ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP));

Una volta terminata la configurazione della rete TCP/IP e dei servizi associati, possiamo configurare l’interfaccia wifi del chip esp32 e attivare la modalità SoftAP:

wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));

Dobbiamo preparare una struct wifi_config_t con i diversi parametri della rete wifi (SSID, autenticazione…) e passarla al metodo:

ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));

Possiamo decidere di inserire i parametri hardcoded nel programma, di renderli configurabili tramite menuconfig (come nell’esempio) o ancora di leggerli da files di configurazione o variabili NVS.

Infine avviamo l’interfaccia wifi con:

ESP_ERROR_CHECK(esp_wifi_start());

HTTP server

Utilizziamo le Netconn API della libreria lwip per mettere il nostro programma in ascolto sulla porta TCP/80 (è la porta standard utilizzata dal protocollo HTTP):

struct netconn *conn;
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, NULL, 80);
netconn_listen(conn);

Il metodo accept() blocca il programma fino all’arrivo di una nuova connessione:

struct netconn *newconn;
netconn_accept(conn, &newconn);

Una volta stabilita la connessione, dobbiamo implementare nel nostro programma il “linguaggio” (protocollo) che parla il client; in questo caso il protocollo HTTP utilizzato dai browser web.

Per semplicità nell’esempio pubblicherò un sito statico, il cui contenuto è memorizzato in una partizione SPIFFS (vedi il progetto ESP32lights per maggiori dettagli), quindi risponderò a richieste di tipo GET <risorsa> da parte del browser cercando la risorsa nella partizione SPIFFS e inviando il suo contenuto con il metodo netconn_write():

http-ap-001

Bonus, mDNS

Per potersi collegare al server HTTP pubblicato dal chip esp32, un client deve conoscere l’indirizzo IP (192.168.1.1) assegnato al chip.

Possiamo sfruttare il servizio mDNS (come spiegato qui) per consentire ai client di collegarsi utilizzando un alias (ad esempio esp32web):

mdns_server_t* mDNS = NULL;
ESP_ERROR_CHECK(mdns_init(TCPIP_ADAPTER_IF_AP, &mDNS));
ESP_ERROR_CHECK(mdns_set_hostname(mDNS, "esp32web"));
ESP_ERROR_CHECK(mdns_set_instance(mDNS, "esp32 webserver"));

Se il dispositivo che utilizziamo supporta mDNS, il sito web sarà quindi accessibile usando l’indirizzo esp32web.local:

http-ap-002

Demo

Il programma completo è disponibile nel mio repository Github. Una volta caricato sulla devboard, sarà disponibile una nuova rete wifi:

http-ap-003

collegandosi a tale rete il proprio PC otterrà un IP sulla rete 192.168.1.0/24:

http-ap-004

e collegandosi via browser al sito http://esp32web.local (o http://192.168.1.1) sarà possibile accedere al sito pubblicato:

http-ap-005

9 Comments »

  1. Eric 30/01/2018 at 22:45 - Reply

    Hi,
    I don’t see the sample code in your Git repo. Is that normal ?
    Thanks,

    • luca 31/01/2018 at 14:40 - Reply

      Hi, sorry I forgot to sync the local repo… now it’s present

  2. Gian Luigi Baldini 08/02/2018 at 11:55 - Reply

    Salve Luca, e complimenti per la serie di tutorial, veramente preziosi.
    Hai in programma una puntata su un server web con pagine dinamiche, che prevedano cioè input da parte dell’utente e visualizzazione di dati variabili (tipicamente, il valore letto da un sensore)?

    Grazie.

    • luca 08/02/2018 at 13:43 - Reply

      Ciao Gian Luigi, se guardi il progetto ESP32Lights trovi già un sito dinamico che visualizza lo stato del sensore di luminosità e riceve soglie e programmazione oraria da parte dell’utente

  3. Gian Luigi Baldini 09/02/2018 at 17:07 - Reply

    Grazie Luca, è esattamente quello che mi serviva!

  4. Franck 27/08/2018 at 10:25 - Reply

    Hi Luca,
    Thanks for your website, very useful!
    Have you tried to run an HTTP server in SoftAp + STA mode?
    It seems that when SoftAP+STA mode is selected, the HTTP server is only accessible via SoftAP…

    • luca 27/08/2018 at 13:18 - Reply

      Hi Franck… no never tried before. With SoftAP+STA esp32 creates two “interfaces”… it might be (but I have to verify in the source code) that lwIP only binds to the first one.
      I’ll let you know if I discover something…

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