c++ and simple wifi example

frankket
Posts: 3
Joined: Mon May 14, 2018 7:14 pm

c++ and simple wifi example

Postby frankket » Sun May 20, 2018 6:20 pm

Hi all

I am having a bit of difficulty implementing C++.

I’ve managed to compile and run the ‘simple_Wi-Fi’ example from the Espressif IDF example folder using C in Eclipse. My router shows that the esp32 connects and is allocated a IP address.

I then tried to re-configure the same simple_Wi-Fi example in C++, also using eclipse as per the instructions found in Neil Kolban’s book (thank you Neil! Your book is a gem). I needed to reconfigure the code for storing the SSID and password and the 'extern "C" void app_main', but otherwise the program is pretty much the same as the C version. It compiles fine, flashes and runs but fails to make a connection with my router. If I change everything back to the C version, I am able to connect with my router again.

I’m at a loss as to where the problem might lie. I am sure its something simple....Any help would be greatly appreciated.

Thanks

Frank

User avatar
kolban
Posts: 1521
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: c++ and simple wifi example

Postby kolban » Mon May 21, 2018 1:59 pm

Howdy,
My suggestions would be to take your C++ application to the most minimum version that performs the function and fails and post a link to the source so that we can take a look. Switch on verbose trace and include a link to the output as well. The net of what I read in your post was:

I have a C program that works and the same in C++ that doesn't ... why?

:-)

Unfortunately, without more information ... it would be guesses as to what may or may not be working. Looking at the code fragments will likely tell us much.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

frankket
Posts: 3
Joined: Mon May 14, 2018 7:14 pm

Re: c++ and simple wifi example

Postby frankket » Mon May 21, 2018 8:29 pm

:oops: :oops: :oops: Yes, sorry. Adding some more details would have helped.....

Code: Select all

/* Simple WiFi Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/


#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"

/* The examples use simple WiFi configuration that you can set via
   'make menuconfig'.

   If you'd rather not, just change the below entries to strings with
   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_MODE_AP   FALSE //TRUE:AP FALSE:STA
#define EXAMPLE_ESP_WIFI_SSID      "TP-LINK_6B0878"
#define EXAMPLE_ESP_WIFI_PASS      "MY_PASSWORD"
#define EXAMPLE_MAX_STA_CONN       CONFIG_MAX_STA_CONN

/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int WIFI_CONNECTED_BIT = BIT0;

static const char *TAG = "simple wifi";

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch(event->event_id) {
    case SYSTEM_EVENT_STA_START:
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        ESP_LOGI(TAG, "got ip:%s",
                 ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
        xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
        break;
    case SYSTEM_EVENT_AP_STACONNECTED:
        ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d",
                 MAC2STR(event->event_info.sta_connected.mac),
                 event->event_info.sta_connected.aid);
        break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
        ESP_LOGI(TAG, "station:" MACSTR"leave, AID=%d",
                 MAC2STR(event->event_info.sta_disconnected.mac),
                 event->event_info.sta_disconnected.aid);
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);
        break;
    default:
        break;
    }
    return ESP_OK;
}

void wifi_init_softap()
{
//    wifi_event_group = xEventGroupCreate();
//
//    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));
//    wifi_config_t wifi_config = {
//        .ap = {
//            .ssid = EXAMPLE_ESP_WIFI_SSID,
//            .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
//            .password = EXAMPLE_ESP_WIFI_PASS,
//            .max_connection = EXAMPLE_MAX_STA_CONN,
//            .authmode = WIFI_AUTH_WPA_WPA2_PSK
//        },
//    };
//    if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
//        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
//    }
//
//    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
//    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
//    ESP_ERROR_CHECK(esp_wifi_start());
//
//    ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s",
//             EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}

void wifi_init_sta()
{
    wifi_event_group = xEventGroupCreate();

    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));
//---------------------------------------------------
//        wifi_config_t wifi_config = {
//            .sta = {
//                .ssid = EXAMPLE_ESP_WIFI_SSID,
//                .password = EXAMPLE_ESP_WIFI_PASS
//            },
//        };
 //---------------------------------------
        wifi_config_t wifi_config;
        sprintf (reinterpret_cast<char*>(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID );
        sprintf (reinterpret_cast<char*>(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS);
////-------------------------------------------
    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() );

    ESP_LOGI(TAG, "wifi_init_sta finished.");
    ESP_LOGI(TAG, "connect to ap SSID:%s password:%s",
          wifi_config.sta.ssid, wifi_config.sta.password);
}

extern "C" void app_main(void) {
//void app_main() {
    //Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
   
#if EXAMPLE_ESP_WIFI_MODE_AP
    ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
    wifi_init_softap();
#else
    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    wifi_init_sta();
#endif /*EXAMPLE_ESP_WIFI_MODE_AP*/

}



The output log is :

Code: Select all

I (0) cpu_start: App cpu up.
I (317) heap_init: Initializing. RAM available for dynamic allocation:
D (324) heap_init: New heap initialised at 0x3ffae6e0
I (329) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
D (335) heap_init: New heap initialised at 0x3ffb9240
I (340) heap_init: At 3FFB9240 len 00026DC0 (155 KiB): DRAM
I (346) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (353) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
D (359) heap_init: New heap initialised at 0x4008f5dc
I (364) heap_init: At 4008F5DC len 00010A24 (66 KiB): IRAM
I (370) cpu_start: Pro cpu start user code
D (382) clk: RTC_SLOW_CLK calibration value: 3352550
V (56) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): checking args
V (56) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): Args okay. Resulting flags 0xE
D (61) intr_alloc: Connected src 46 to int 2 (cpu 0)
V (67) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): checking args
V (72) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): Args okay. Resulting flags 0xC0E
D (80) intr_alloc: Connected src 57 to int 3 (cpu 0)
V (86) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): checking args
V (92) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): Args okay. Resulting flags 0x40E
D (100) intr_alloc: Connected src 24 to int 9 (cpu 0)
I (105) cpu_start: Starting scheduler on PRO CPU.
V (0) intr_alloc: esp_intr_alloc_intrstatus (cpu 1): checking args
V (0) intr_alloc: esp_intr_alloc_intrstatus (cpu 1): Args okay. Resulting flags 0x40E
D (10) intr_alloc: Connected src 25 to int 2 (cpu 1)
I (10) cpu_start: Starting scheduler on APP CPU.
D (155) heap_init: New heap initialised at 0x3ffe0440
D (155) heap_init: New heap initialised at 0x3ffe4350
V (165) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): checking args
V (165) intr_alloc: esp_intr_alloc_intrstatus (cpu 0): Args okay. Resulting flags 0xE
D (165) intr_alloc: Connected src 16 to int 12 (cpu 0)
D (185) nvs: nvs_flash_init_custom partition=nvs start=9 count=6
I (275) simple wifi: ESP_WIFI_MODE_STA
D (275) nvs: nvs_open_from_partition misc 1
D (275) nvs: nvs_get_str_or_blob log
D (275) nvs: nvs_set_blob log 24
I (285) wifi: wifi firmware version: c25fd80
I (285) wifi: config NVS flash: enabled
I (285) wifi: config nano formating: disabled
I (295) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (305) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
D (315) nvs: nvs_open_from_partition nvs.net80211 1
D (315) nvs: nvs_get opmode 1
D (325) nvs: nvs_set opmode 1 2
D (325) nvs: nvs_get_str_or_blob sta.ssid
D (325) nvs: nvs_set_blob sta.ssid 36
D (335) nvs: nvs_get_str_or_blob sta.mac
D (335) nvs: nvs_set_blob sta.mac 6
D (335) nvs: nvs_get sta.authmode 1
D (345) nvs: nvs_set sta.authmode 1 1
D (345) nvs: nvs_get_str_or_blob sta.pswd
D (355) nvs: nvs_set_blob sta.pswd 65
D (355) nvs: nvs_get_str_or_blob sta.pmk
D (355) nvs: nvs_set_blob sta.pmk 32
D (365) nvs: nvs_get sta.chan 1
D (365) nvs: nvs_set sta.chan 1 0
D (365) nvs: nvs_get auto.conn 1
D (375) nvs: nvs_set auto.conn 1 1
D (375) nvs: nvs_get bssid.set 1
D (375) nvs: nvs_set bssid.set 1 0
D (385) nvs: nvs_get_str_or_blob sta.bssid
D (385) nvs: nvs_set_blob sta.bssid 6
D (395) nvs: nvs_get sta.lis_intval 2
D (395) nvs: nvs_set sta.lis_intval 2 3
D (395) nvs: nvs_get sta.phym 1
D (405) nvs: nvs_set sta.phym 1 3
D (405) nvs: nvs_get sta.phybw 1
D (405) nvs: nvs_set sta.phybw 1 2
D (415) nvs: nvs_get_str_or_blob sta.apsw
D (415) nvs: nvs_set_blob sta.apsw 2
D (415) nvs: nvs_get_str_or_blob sta.apinfo
D (425) nvs: nvs_set_blob sta.apinfo 700
D (425) nvs: nvs_get sta.scan_method 1
D (435) nvs: nvs_set sta.scan_method 1 0
D (435) nvs: nvs_get sta.sort_method 1
D (435) nvs: nvs_set sta.sort_method 1 0
D (445) nvs: nvs_get sta.minrssi 1
D (445) nvs: nvs_set sta.minrssi 1 -127
D (455) nvs: nvs_get sta.minauth 1
D (455) nvs: nvs_set sta.minauth 1 0
D (455) nvs: nvs_get_str_or_blob ap.ssid
D (465) nvs: nvs_set_blob ap.ssid 36
D (465) nvs: nvs_get_str_or_blob ap.mac
D (465) nvs: nvs_set_blob ap.mac 6
D (475) nvs: nvs_get_str_or_blob ap.passwd
D (475) nvs: nvs_set_blob ap.passwd 65
D (485) nvs: nvs_get_str_or_blob ap.pmk
D (485) nvs: nvs_set_blob ap.pmk 32
D (485) nvs: nvs_get ap.chan 1
D (495) nvs: nvs_set ap.chan 1 1
D (495) nvs: nvs_get ap.authmode 1
D (495) nvs: nvs_set ap.authmode 1 0
D (505) nvs: nvs_get ap.hidden 1
D (505) nvs: nvs_set ap.hidden 1 0
D (505) nvs: nvs_get ap.max.conn 1
D (515) nvs: nvs_set ap.max.conn 1 4
D (515) nvs: nvs_get bcn.interval 2
D (515) nvs: nvs_set bcn.interval 2 100
D (525) nvs: nvs_get ap.phym 1
D (525) nvs: nvs_set ap.phym 1 3
D (525) nvs: nvs_get ap.phybw 1
D (535) nvs: nvs_set ap.phybw 1 2
D (535) nvs: nvs_get ap.sndchan 1
D (535) nvs: nvs_set ap.sndchan 1 1
D (545) nvs: nvs_get lorate 1
D (545) nvs: nvs_set lorate 1 0
D (545) nvs: nvs_set_blob sta.mac 6
D (555) nvs: nvs_set_blob ap.mac 6
I (555) wifi: Init dynamic tx buffer num: 32
I (555) wifi: Init data frame dynamic rx buffer num: 32
I (565) wifi: Init management frame dynamic rx buffer num: 32
I (575) wifi: wifi driver task: 3ffbf1c8, prio:23, stack:4096
I (575) wifi: Init static rx buffer num: 10
I (575) wifi: Init dynamic rx buffer num: 32
D (585) nvs: nvs_set opmode 1 1
D (585) nvs: nvs_set_blob sta.ssid 36
D (595) nvs: nvs_set_blob sta.pswd 65
D (595) nvs: nvs_set bssid.set 1 1
D (595) nvs: nvs_set_blob sta.bssid 6
D (605) nvs: nvs_set sta.lis_intval 2 12112
D (605) nvs: nvs_set sta.scan_method 1 1
D (615) nvs: nvs_set sta.sort_method 1 1
D (615) nvs: nvs_set sta.minrssi 1 -127
D (615) nvs: nvs_set sta.minauth 1 1
D (625) nvs: nvs_set_blob sta.apsw 2
D (625) nvs: nvs_set_blob sta.apinfo 700
D (635) RTC_MODULE: Wi-Fi takes adc2 lock.
D (635) phy_init: loading PHY init data from application binary
D (635) nvs: nvs_open_from_partition phy 0
D (645) phy_init: esp_phy_load_cal_data_from_nvs: failed to open NVS namespace (0x1102)
W (655) phy_init: failed to load RF calibration data (0x1102), falling back to full calibration
I (825) phy: phy_version: 386.0, 67c798f, Mar 14 2018, 16:34:06, 0, 2
D (825) nvs: nvs_open_from_partition phy 1
D (825) nvs: nvs_set_blob cal_data 1904
D (835) nvs: nvs_set_blob cal_mac 6
V (845) phy_init: phy_get_rf_cal_version: 386

D (845) nvs: nvs_set cal_version 4 386
D (845) nvs: nvs_close 3
I (845) wifi: mode : sta (24:0a:c4:10:5f:dc)
D (855) event: SYSTEM_EVENT_STA_START
V (855) event: enter default callback
I (855) simple wifi: wifi_init_sta finished.
V (855) tcpip_adapter: check: local, if=0 fn=0x400e32c8
0x400e32c8: tcpip_adapter_start_api at /home/frankubuntu/esp32/esp-idf/components/tcpip_adapter/tcpip_adapter_lwip.c:1071


V (865) tcpip_adapter: call api in lwip: ret=0x0, give sem
V (875) tcpip_adapter: check: remote, if=0 fn=0x400e32c8
0x400e32c8: tcpip_adapter_start_api at /home/frankubuntu/esp32/esp-idf/components/tcpip_adapter/tcpip_adapter_lwip.c:1071


V (875) event: exit default callback
I (885) simple wifi: connect to ap SSID:TP-LINK_6B0878 password:MY_PASSWORD
D (3295) event: SYSTEM_EVENT_STA_DISCONNECTED, ssid:TP-LINK_6B0878, ssid_len:14, bssid:00:00:00:00:00:00, reason:201
V (3295) event: enter default callback
V (3295) tcpip_adapter: check: local, if=0 fn=0x400e35ec
0x400e35ec: tcpip_adapter_down_api at /home/frankubuntu/esp32/esp-idf/components/tcpip_adapter/tcpip_adapter_lwip.c:1071


D (3305) tcpip_adapter: if0 start ip lost tmr: enter
D (3305) tcpip_adapter: if0 start ip lost tmr: no need start because netif=0x3ffc500c interval=120 ip=0
V (3315) tcpip_adapter: call api in lwip: ret=0x0, give sem
V (3325) tcpip_adapter: check: remote, if=0 fn=0x400e35ec
0x400e35ec: tcpip_adapter_down_api at /home/frankubuntu/esp32/esp-idf/components/tcpip_adapter/tcpip_adapter_lwip.c:1071


V (3335) event: exit default callback
....... and we start repeating ourselves



thanks again

Frank

euripedes
Posts: 6
Joined: Tue May 15, 2018 12:04 pm

Re: c++ and simple wifi example

Postby euripedes » Tue May 22, 2018 11:38 am

Hi, just to point that this don't have anything with C++.

I have the same issue(reported in another topic).

Since you cannot initialize the struct in C style you had to use sprintf to fill the config and after that the wifi stack can't find the AP as pointed by the 201 error in your logs. I have the same effect compiling the simple_wifi as C with the change I pointed.

User avatar
kolban
Posts: 1521
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: c++ and simple wifi example

Postby kolban » Tue May 22, 2018 1:13 pm

In your C code you have the following:

Code: Select all

//    wifi_config_t wifi_config = {
//        .ap = {
//            .ssid = EXAMPLE_ESP_WIFI_SSID,
//            .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
//            .password = EXAMPLE_ESP_WIFI_PASS,
//            .max_connection = EXAMPLE_MAX_STA_CONN,
//            .authmode = WIFI_AUTH_WPA_WPA2_PSK
//        },
//    };


while in your C++ you have:

Code: Select all

        wifi_config_t wifi_config;
        sprintf (reinterpret_cast<char*>(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID );
        sprintf (reinterpret_cast<char*>(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS);


Try the following:

Code: Select all

wifi_config_t wifi_config;
memset(&wifi_config,0, sizeof(wifi_config));
strcpy(wifi_config.ap.ssid, EXAMPLE_ESP_WIFI_SSID);
strcpy(wifi_config.ap.password, EXAMPLE_ESP_WIFI_PASS);
wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;


I think there are two errors.

1. We hadn't initialized the structure to 0.
2. We hadn't set the authmode property.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

euripedes
Posts: 6
Joined: Tue May 15, 2018 12:04 pm

Re: c++ and simple wifi example

Postby euripedes » Tue May 22, 2018 4:16 pm

As pointed above, the error is due to initialization. I was able to make example to run again by loading the current config with esp_wifi_get_config.

frankket
Posts: 3
Joined: Mon May 14, 2018 7:14 pm

Re: c++ and simple wifi example

Postby frankket » Sun May 27, 2018 3:30 pm

Hi all,

Thank you for your replies. Sorry for the delay, but unfortunately my day job kept me away....

Adding memset solved the problem >> (I (3295) simple wifi: got ip:192.168.1.113 :D :D )

Code: Select all

        memset(&wifi_config, 0, sizeof(wifi_config));       
        sprintf (reinterpret_cast<char*>(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID );
        sprintf (reinterpret_cast<char*>(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS);


What I don't fully understand is, since memset doesn't add any "real" data, why does memset correct my problem when my original code successfully stored the SSID and password in wifi_config.sta.ssid and .password? I verified correct storage by:

Code: Select all

    ESP_LOGI(TAG, "connect to ap SSID:%s password:%s",
          wifi_config.sta.ssid, wifi_config.sta.password);
   >>I (585) simple wifi: connect to ap SSID:TP-LINK_6B0878 password:---



Niel, the following code you suggested gave me error messages:

Code: Select all

        strcpy(wifi_config.sta.ssid, EXAMPLE_ESP_WIFI_SSID);
        strcpy(wifi_config.sta.password, EXAMPLE_ESP_WIFI_PASS);
 


Code: Select all

simple_wifi_cpp.cpp:134:30: error: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' [-fpermissive]
       strcpy(wifi_config.sta.ssid, EXAMPLE_ESP_WIFI_SSID);


now that I've got connection I can begin adding the C++ part euripedes .... ;)

many thanks again all.

Frank

Who is online

Users browsing this forum: No registered users and 2 guests