ESP32 (18) – Access Point

luca 20/05/2017 10

In tutti gli esempi finora proposti, abbiamo utilizzato il chip esp32 in STAtion Mode, ovvero come client che si collega ad una rete wifi esistente. In un precedente articolo ho spiegato in dettaglio come interagiscono i vari componenti del framework esp-idf per stabilire la connessione e l’uso degli eventi per sincronizzare i vari tasks del nostro programma.

Oggi vedremo come configurare il chip esp32 per creare una propria rete wifi, in maniera simile ad un access point. Tale modalità prende infatti il nome di SoftAP.

Indirizzamento IP

Ogni dispositivo collegato ad una rete IP deve avere un proprio indirizzo univoco. E’ possibile assegnare l’indirizzo in maniera statica, o affidarsi ad un servizio (DHCP, Dynamic Host Configuration Protocol – Protocollo di configurazione dinamica dei dispositivi) che li assegna in maniera dinamica. Il servizio DHCP ha il vantaggio di non richiedere – a chi si collega ad una rete – di conoscere a priori la configurazione corretta da applicare (indirizzo IP, maschera di rete, gateway…); per questo normalmente il dispositivo che gestisce la rete offre anche un server DHCP:

ap-05

Anche il framework esp-idf include un server DHCP. Per poterlo rendere disponibile nella nuova rete wifi che andremo a creare dobbiamo:

  • fermare il servizio in caso sia già in esecuzione – tcpip_adapter_dhcps_stop()
  • configurare in maniera statica l’interfaccia di rete del chip esp32 – tcpip_adapter_set_ip_info()
  • avviare il servizio – tcpip_adapter_dhcps_start()
Il framework esp-idf utilizza due diverse interfacce di rete nel caso il chip esp32 sia in station mode o in SoftAP mode (TCPIP_ADAPTER_IF_STA e TCPIP_ADAPTER_IF_AP). Ponete quindi attenzione a quella che configurate in base alla modalità che volete utilizzare.

Per assegnare l’indirizzo 192.168.10.1/24 (/24 corrisponde ad una maschera di rete 255.255.255.0) ed eseguire il server DHCP dobbiamo quindi:

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

SoftAP

Possiamo ora configurare la modalità SoftAP del chip esp32.

Per prima cosa inizializziamo l’event handler (vedremo in seguito quali eventi sono disponibili in questa modalità):

ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

Quindi configuriamo lo stack wifi in modalità access point, con configurazione di default memorizzata nella memoria RAM:

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));

I parametri di configurazione dell’access point sono disponibili nella struct wifi_ap_config_t:

ap-01

  • ssid è il nome (Service Set Identifier) della rete
  • password è la password per il collegamento alla rete (se la modalità di autenticazione la prevede, vedi sotto)
  • ssid_len è la lunghezza (in caratteri) della stringa ssid – può essere lasciata a 0 se tale stringa è null-terminated
  • channel è il canale di trasmissione
  • authmode indica la modalità di autenticazione, vedi sotto
  • ssid_hidden consente di nascondere la rete non trasmettendo il suo SSID in broadcast
  • max_connection è il numero di dispositivi collegati contemporaneamente (max 4)
  • beacon_intereval indica l’intervallo tra la trasmissione di un beacon frame e il successivo

Una volta configurati i parametri, vanno applicati con il metodo esp_wifi_set_config(). Nell’esempio pubblicato su Github, tutti i parametri sono configurabili tramite menuconfig:

ap-02

wifi_config_t ap_config = {
	.ap = {
		.ssid = CONFIG_AP_SSID,
		.password = CONFIG_AP_PASSWORD,
		.ssid_len = 0,
		.channel = CONFIG_AP_CHANNEL,
		.authmode = CONFIG_AP_AUTHMODE,
		.ssid_hidden = CONFIG_AP_SSID_HIDDEN,
		.max_connection = CONFIG_AP_MAX_CONNECTIONS,
		.beacon_interval = CONFIG_AP_BEACON_INTERVAL,			
	},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));

Infine avviamo lo stack wifi con:

ESP_ERROR_CHECK(esp_wifi_start());

Eventi

3 gli eventi principali che sono disponibili in modalità access point:

  • SYSTEM_EVENT_AP_START, quando lo stack ha completato il processo di avvio (iniziato con esp_wifi_start)
  • SYSTEM_EVENT_AP_STACONNECTED, quando un nuovo dispositivo si collega all’access point
  • SYSTEM_EVENT_AP_STADISCONNECTED, quando un dispositivo si disconnette

ap-03

Nell’esempio di questo post gli eventi sono notificati tramite diversi event bits:

case SYSTEM_EVENT_AP_START:
	printf("Access point started\n");
	break;
 
case SYSTEM_EVENT_AP_STACONNECTED:
	xEventGroupSetBits(event_group, STA_CONNECTED_BIT);
	break;
 
case SYSTEM_EVENT_AP_STADISCONNECTED:
	xEventGroupSetBits(event_group, STA_DISCONNECTED_BIT);
	break;

Authentication modes

La modalità SoftAP del chip esp32 supporta diverse modalità di autenticazione:

ap-04

open configura una rete wifi senza alcuna modalità di autenticazione, mentre le altre modalità implementano qualche forma di sicurezza, da quelle più “deboli” (WEP, ormai facilmente violabile) a quelle più sicure (WPA2). Personalmente utilizzo sempre la modalità WPA2_PSK che offre elevata sicurezza e autenticazione tramite password (PSK = PreShared Key, chiave di sicurezza condivisa).

Le diverse modalità di autenticazione impongono criteri di lunghezza della password. In particolare WPA e WPA2 richiedono una password da almeno 8 caratteri; se si specifica una password più corta, il metodo esp_wifi_set_config restituirà un errore.

Elenco dispositivi connessi

E’ possibile ottenere un elenco dei dispositivi connessi all’access point con il metodo esp_wifi_ap_get_sta_list() che aggiorna una struct di tipo wifi_sta_list_t:

wifi_sta_list_t wifi_sta_list;
memset(&wifi_sta_list, 0, sizeof(wifi_sta_list));
ESP_ERROR_CHECK(esp_wifi_ap_get_sta_list(&wifi_sta_list));

Per ottenere i parametri IP (ad esempio l’indirizzo) delle varie stations si può quindi utilizzare il metodo tcpip_adapter_get_sta_list():

tcpip_adapter_sta_list_t adapter_sta_list;
memset(&adapter_sta_list, 0, sizeof(adapter_sta_list));
ESP_ERROR_CHECK(tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list));
for(int i = 0; i < adapter_sta_list.num; i++) {
	tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
	printf("%d - mac: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x - IP: %s\n", i + 1,
		station.mac[0], station.mac[1], station.mac[2],
		station.mac[3], station.mac[4], station.mac[5],
		ip4addr_ntoa(&(station.ip)));
}

Demo

(sottotitoli in italiano disponibili)

10 Comments »

  1. Roland 11/07/2017 at 19:51 - Reply

    Thanks for this tutorial.
    The main.c compiles and I user menuconfig to set the values.
    But If I start the program my wroom32 keeps rebooting telling me the following error:

    ESP_ERROR_CHECK failed: esp_err_t 0xb at 0x400df854
    0x400df854: app_main at /home/roland/Roboter/esp32/esp32-tutorial/12_accesspoint/main/./main.c:168 (discriminator 1)

    file: “/home/roland/Roboter/esp32/esp32-tutorial/12_accesspoint/main/./main.c” line 168
    func: app_main
    expression: esp_wifi_set_config(WIFI_IF_AP, &ap_config)

    Backtrace: 0x400868ac:0x3ffb88f0 0x40086c29:0x3ffb8910 0x400df854:0x3ffb8930 0x400d0ce2:0x3ffb8a00
    0x400868ac: invoke_abort at /home/roland/Roboter/esp32/esp-idf/components/esp32/./panic.c:547

    0x40086c29: _esp_error_check_failed at /home/roland/Roboter/esp32/esp-idf/components/esp32/./panic.c:559

    0x400df854: app_main at /home/roland/Roboter/esp32/esp32-tutorial/12_accesspoint/main/./main.c:168 (discriminator 1)

    0x400d0ce2: main_task at /home/roland/Roboter/esp32/esp-idf/components/esp32/./cpu_start.c:334

    Rebooting…

    What am I doing wrong?
    could you possibly provide me with a working sdkconfig file

    Thank you

    • luca 12/07/2017 at 08:51 - Reply

      Hi, it usually means that you’re using wrong parameters when configuring the AP… for example a password too short for the encryption method you chose.

  2. rahul 25/07/2017 at 09:26 - Reply

    Really good stuff!!!
    but I want to do make this possible by configuring it with Arduino IDE

    • luca 26/07/2017 at 07:37 - Reply

      Hi! My tutorials are about using only the official IDF but you can find many articles on the Internet related to esp32+arduino…

  3. Brian 09/10/2017 at 20:43 - Reply

    Thanks for the great information. Maybe you already have a demo for APSTA but I was not able to locate it on your site. I would like to configure one ESP32 as SoftAP + Station P2P and then another ESP32 in Station mode to connect to the first ESP’s AP. Hope you can point me in the direction.
    Thanks again

    • luca 10/10/2017 at 12:42 - Reply

      Hi Brian, I’m working on it, meanwhile you can use the esp32 forum: some users already posted example about that mode.

  4. satme 16/10/2017 at 15:35 - Reply

    Hi Luca

    too good tutorial. Wounder why no tutorial on ADC. And how we can make the output of ADC linear. Will be very helpful for sensor interface.

    • luca 17/10/2017 at 08:23 - Reply

      Hi, I’m working on a tutorial about ADC, meanwhile you can read some threads in the esp32 forum.

  5. loris 29/10/2017 at 11:46 - Reply

    commento giusto:

    ESP_ERROR_CHECK failed: esp_err_t 0xb at 0x40103848
    0x40103848: app_main at /home/orcim/esp/_work/_luca_dentella/esp32-tutorial/12_accesspoint/main/./main.c:188 (discriminator 1)

    file: “/home/orcim/esp/_work/_luca_dentella/esp32-tutorial/12_accesspoint/main/./main.c” line 188
    func: app_main
    expression: esp_wifi_set_config(WIFI_IF_AP, &ap_config)

    Backtrace: 0x40087618:0x3ffba9d0 0x4008797d:0x3ffba9f0 0x40103848:0x3ffbaa10 0x400d0e53:0x3ffbab10
    0x40087618: invoke_abort at /home/orcim/esp/esp-idf/components/esp32/./panic.c:553

    0x4008797d: _esp_error_check_failed at /home/orcim/esp/esp-idf/components/esp32/./panic.c:565

    0x40103848: app_main at /home/orcim/esp/_work/_luca_dentella/esp32-tutorial/12_accesspoint/main/./main.c:188 (discriminator 1)

    0x400d0e53: main_task at /home/orcim/esp/esp-idf/components/esp32/./cpu_start.c:406

    Rebooting…
    ets Jun 8 2016 00:22:57

    • luca 30/10/2017 at 08:45 - Reply

      ciao, normalmente quell’errore indica che qualche parametro in ap_config non è valido… di solito la password non soddisfa i criteri di sicurezza (lunghezza…) dello standard (WEP, WPA…) che hai scelto.

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