Page 1 of 1

WiFi connecting to Raspberry Pi AP

Posted: Thu May 10, 2018 9:44 pm
by PaulVdBergh
Hi All,

This is the next step of this story.

I've set up an RPi as access point (SSID "IoT_and_Trains"), can connect to it with an android device, tested with an ESP-WROVER-KIT and this ESP_WifiScan application. The ESPWifiscan's output:

Code: Select all

Number of access points found: 10
======================================================================
             SSID             |    RSSI    |           AUTH           
======================================================================
                devolo-8f4    |     -19    |        WIFI_AUTH_WPA2_PSK
          devolo-guest-8f4    |     -19    |            WIFI_AUTH_OPEN
            IoT_and_Trains    |     -32    |        WIFI_AUTH_WPA2_PSK
                    polder    |     -61    |    WIFI_AUTH_WPA_WPA2_PSK
                              |     -62    |        WIFI_AUTH_WPA2_PSK
              PROXIMUS_FON    |     -79    |            WIFI_AUTH_OPEN
             WiFi-2.4-39C0    |     -79    |        WIFI_AUTH_WPA2_PSK
      Proximus Smart Wi-Fi    |     -79    |                   Unknown
                    polder    |     -87    |    WIFI_AUTH_WPA_WPA2_PSK
                              |     -97    |        WIFI_AUTH_WPA2_PSK
This proves that the AP is visible to the ESP module.
I started a new project based on the IDF-Template and modified main.cpp as follows:

Code: Select all

/*
 * main.cpp
 *
 *  Created on: May 10, 2018
 *      Author: paulvdbergh
 */


#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"

#include "esp_log.h"
static char tag[] = "app_main";

#include <string.h>

#define RPI_SSID "IoT_and_Trains"
#define RPI_SSID_PWD "IoTTESP32"

esp_err_t event_handler(void *ctx, system_event_t *event)
{
	switch(event->event_id)
	{
		case SYSTEM_EVENT_WIFI_READY:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_WIFI_READY");
			break;
		}

		case SYSTEM_EVENT_SCAN_DONE:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_SCAN_DONE");
			break;
		}

		case SYSTEM_EVENT_STA_START:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_START");
			break;
		}

		case SYSTEM_EVENT_STA_STOP:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_STOP");
			break;
		}

		case SYSTEM_EVENT_STA_CONNECTED:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_CONNECTED");
			break;
		}

		case SYSTEM_EVENT_STA_DISCONNECTED:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_DISCONNECTED");
			break;
		}

		case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_AUTHMODE_CHANGE");
			break;
		}

		case SYSTEM_EVENT_STA_GOT_IP:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_GOT_IP");
			break;
		}

		case SYSTEM_EVENT_STA_LOST_IP:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_LOST_IP");
			break;
		}

		default:
		{
			ESP_LOGI(tag, "EventHandler received %i", event->event_id);
			break;
		}
	}
    return ESP_OK;
}

extern "C"
void app_main(void)
{
    nvs_flash_init();
    tcpip_adapter_init();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );

    wifi_config_t sta_config;
    memcpy(&sta_config.sta.ssid, RPI_SSID, strlen(RPI_SSID));
    memcpy(&sta_config.sta.password, RPI_SSID_PWD, strlen(RPI_SSID_PWD));
    sta_config.sta.bssid_set = false;

    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );

    gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
    int level = 0;
    while (true) {
        gpio_set_level(GPIO_NUM_4, level);
        level = !level;
        vTaskDelay(300 / portTICK_PERIOD_MS);
    }
}
The problem is that this code works fine, the ESP connects to the access point when the global log level is set to Debug or higher (in make menuconfig). The output of make monitor is attached as LogLevel_debug.txt.

When the global log level is set to info or lower, the connection fails... (see LogLevel_info.txt).

I'm searching for the reason why this happens...

Any suggestions or hints are very welcome.

Thanks in advance,

Paul.

Re: WiFi connecting to Raspberry Pi AP

Posted: Thu May 10, 2018 10:17 pm
by kolban
I read your post and my heart sank. I had that sickening feeling. For years now I have been coding exactly what you described and also writing that up in my book of notes just as you described. With horror, I realized that what I had been using and describing is simply wrong.

Here is what I now believe to be the truth:

When we perform an esp_wifi_start() request, we are requesting that the WiFi subsystem start. I believe that this spawns new tasks in the background. When WiFi has started, we will receive an event in the event handler of either SYSTEM_EVENT_STA_START or SYSTEM_EVENT_AP_START depending on whether we are being a station or access point. Now here is the kicker ... one should **not** attempt to perform further WiFi activities **until** we have received that event. For example:

Code: Select all

esp_wifi_start();
esp_wifi_connect();
is plain dangerous/wrong. This says "Start WiFi and then connect to the access point" ... on the surface, this sounds good ... until we realize that "esp_wifi_start" need not be a synchronous call. Rather ... esp_wifi_start() requests that we start WiFi ... and only when we receive (asynchronously) the SYSTEM_EVENT_STA_START message ... THEN WiFi should be considered started and THEN we can perform the connect. It appears that with full diagnostic logging enabled (which I have always run with), that slows down execution of either the tail end of esp_wifi_start() or the start of esp_wifi_connect() enough that esp_wifi_start() will have completed by the time we reach esp_wifi_connect(). However this is just "luck" and, as you found, when you switch off logging, the race condition (which worked in our favor in the past) is now no longer the case.

Please try your esp_wifi_connect() within the context of the event handler OR create a blocking semaphore which gets unblocked when the event arrives and then allows you to perform the esp_wifi_connect() and report back.

Ive updated my book of notes for inclusion in the June release. Wow!!!

Re: WiFi connecting to Raspberry Pi AP

Posted: Fri May 11, 2018 9:59 am
by PaulVdBergh
Hi Neil,

I tested your suggestion, unfortunately without success :cry: :

In event_handler:

Code: Select all

		case SYSTEM_EVENT_STA_START:
		{
			ESP_LOGI(tag, "SYSTEM_EVENT_STA_START");
		   ESP_ERROR_CHECK( esp_wifi_connect() );
			break;
		}
In app_main:

Code: Select all

    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
//    ESP_ERROR_CHECK( esp_wifi_connect() );

    gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
Even worse, with loglevel set to debug, I once encountered these messages in the log:

Code: Select all

D (391) event: SYSTEM_EVENT_STA_START
I (393) app_main: SYSTEM_EVENT_STA_START
I (2807) wifi: n:7 0, o:1 0, ap:255 255, sta:7 0, prof:1
I (3465) wifi: state: init -> auth (b0)
I (3468) wifi: state: auth -> assoc (0)
I (3473) wifi: state: assoc -> run (10)
I (3474) wifi: state: run -> auth (2c0)
I (3475) wifi: n:7 0, o:7 0, ap:255 255, sta:7 0, prof:1
D (3476) event: SYSTEM_EVENT_STA_DISCONNECTED, ssid:IoT_and_Trains, ssid_len:14, bssid:b8:27:eb:3a:72:60, reason:2
D (3486) tcpip_adapter: if0 start ip lost tmr: enter
D (3491) tcpip_adapter: if0 start ip lost tmr: no need start because netif=0x3ffc35c4 interval=120 ip=0
I (3501) app_main: SYSTEM_EVENT_STA_DISCONNECTED
I only saw this once, can't reproduce...
In particular, the line @3476 was interesting : reason:2
According to the documentation there may be an authorization problem on the RPi side of the story...
I know you've written a book about the RPi, so maybe you can help with this : my access point (on the RPi) is configured as follows: (/etc/hostapd/hostapd.conf)

Code: Select all

interface=wlan0
ssid=IoT_and_Trains
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=IoTTESP32
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=CCMP
country_code=BE
ieee80211n=1
#wme_enabled=1
As a test, I would like to remove the WPA authentication, so that it becomes an open AP without authentication whatsoever, but can't find info about how to configure this. (I used this and this info to setup the AP).
I also saw that most of the other AP's in my neighborhood use channel 7. Changing the RPi to channel 4 didn't solved the symptoms. Is there an option to auto-select a free channel?

Thanks for your very valuable input.

Paul.

Re: WiFi connecting to Raspberry Pi AP

Posted: Fri May 11, 2018 2:22 pm
by fly135
After I get the SYSTEM_EVENT_STA_START I call esp_wifi_connect(), then I do the following....

Code: Select all

ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());

Re: WiFi connecting to Raspberry Pi AP

Posted: Sat May 12, 2018 10:02 am
by PaulVdBergh
Oh well, the problem automagically disappeared :shock: :?

When I boot both devices this morning, everything worked as supposed, no matter what debug level specified :ugeek:
Maybe it was some kind of alien radiation disturbing the systems... :lol: