Having trouble getting an ESP8266 module to connect to router using WIFI API

I decided to jump into using the Network interface API, using WiFi.

I have quickly learnt through my failures that the WiFi connectivity API is at odds with the rest of the connectivity API’s. For example, I cannot use async callbacks. Is this correct?

There also seem to be other quirks but I will leave it be for now.

The problem I am having is that I am having little success connecting my humble ESP8266-07 module to my router.

When using the standard WiFi example, as referenced below, I get the scan results without problem.

Early on, I had a spot of beginners luck and had 1 successful connect using the example provided in the WiFi documentation, where I received the IP address and the rest of the connection parameters etc: Wi-Fi - API references and tutorials | Mbed OS 6 Documentation

But now I am at a loss after the nth failed attempt.

So when I use the command:
int ret = wifi.connect(MBED_CONF_APP_WIFI_SSID,MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);

It generally always returns 0 almost immediately (unless I have a wiring issue when it returns a -3012 or NSAPI_ERROR_DEVICE_ERROR) .

In my experience when connecting a wifi module to a router, when using blocking logic, you should not get an immediate response as a router typically takes a good few seconds to check all credentials and assign an IP address etc. Usually first connect is slower etc. I note that the default timeout in the esp8266 code is 15 seconds. So it expects a delay.

So how do I fault find this sort of thing?

For example, there does not seem to be an obvious way of confirming if the password is correct etc. I tried testing this with arbitrary passwords and it seems that all you get is NSAPI_ERROR_IN_PROGRESS or NSAPI_ERROR_ALREADY error types. Is this a safe test condition as not sure what these error codes really mean.

I then tried adding in wifi.attach(&status_callback); to see what responses I get.

I only ever receive one callback event, which NSAPI_STATUS_DISCONNECTED. No other callback is triggered. Should you get more etc.

So I am wondering what is a proven method to fault find WiFi SDK issues or otherwise here.

In my experience when using AT commands, like with cellular devices, it often relates to how your code interprets the AT response and the time given to wait for a response. Is it likely to be the same here. I am not sure where I would start. I assume it is ESP8266.cpp.

Any feedback is gladly welcomed.

Thanks.

Hello Gerriko,

So when I use the command:
int ret = wifi.connect(MBED_CONF_APP_WIFI_SSID,MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);

It generally always returns 0 almost immediately (unless I have a wiring issue when it returns a -3012 or NSAPI_ERROR_DEVICE_ERROR) .

The following works for me on NUCLEO-F411RE:

...

//#if TARGET_UBLOX_EVK_ODIN_W2
//#include "OdinWiFiInterface.h"
//OdinWiFiInterface wifi;
//#else
//#if !TARGET_FF_ARDUINO
//#error [NOT_SUPPORTED] Only Arduino form factor devices are supported at this time
//#endif
#include "ESP8266Interface.h"
//ESP8266Interface wifi(D1, D0);   // Does not work: Collides with printf
//ESP8266Interface wifi(p28,p27);  // LPC1768
ESP8266Interface wifi(PB_6,PB_7);  // NUCLEO_F411RE
//#endif

...

int ret = wifi.connect(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID, MBED_CONF_NSAPI_DEFAULT_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);

...

With the following mbed_app.json:

{
    "target_overrides": {
        "*": {
            "platform.stdio-baud-rate": 115200,
            "nsapi.default-wifi-ssid": "\"xxxx\"",
            "nsapi.default-wifi-password": "\"yyyy\"",
            "nsapi.default-wifi-security": "WPA_WPA2",
            "esp8266.provide-default": false
        }
    }
}

Replace xxxx with real ssid and yyyy with real password as appropriate.

Hmmm, I think we are using exactly the same command here…

int ret = wifi.connect(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID, MBED_CONF_NSAPI_DEFAULT_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);

is the same as

int ret = wifi.connect(MBED_CONF_APP_WIFI_SSID,MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);

which would be the same as using

#define MYSSID     ssid4myrouter
#define MYPASSWORD     myuniquepassword

int ret = wifi.connect(MYSSID, MYPASSWORD, NSAPI_SECURITY_WPA_WPA2);

I know it should work… and I did spot it working once.

I am just seeking some guidance on how best to debug this library as it’s difficult not having worked through it. I assume there is some debug trace setting I could use.

They seem the same but there is a subtle difference. My macros include the words NSAPI_DEFAULT instead of APP and such macros are used in the mbed source code for configuration (in contrary to the macros used in the demo). When I use the same macros as you are using then I get the same result as you (the demo does not work correctly).

MBED_CONF_APP_WIFI_SSID != MBED_CONF_NSAPI_DEFAULT_WIFI_SSID
MBED_CONF_APP_WIFI_PASSWORD  != MBED_CONF_NSAPI_DEFAULT_WIFI_PASSWORD

There is a file mbed-os-6.15.1/connectivity/drivers/wifi/esp8266-driver/README.md providing some additional information. But I think the restrictions should be corrected as below:

Restrictions

  • The ESP8266 Wi-Fi module does not allow the TCP socket to accept a client.
  • Setting up a TCP server is not possible.

That’s very interesting.

I am busy testing the ESP8266 driver to help me understand what happens at that level. I did insert "nsapi.default-wifi-ssid" and "nsapi.default-wifi-password" into my mbed_app.json file just to create a template.

Even though I was not using any of the interface drivers, it did cause an error when compiling NetworkInterfaceDefaults.cpp.

I knew it would cause an error, if used, because my wifi password includes an ASCII " char (0x22) and currently the Mbed OS code cannot handle this character properly (it’s flagged as an issue in GitHub)… it creates a gap and you then get error: expected ‘)’.

I am slowly trawling through the ESP8266 driver.

I am looking at the connect function
nsapi_error_t ESP8266::connect(const char *ap, const char *passPhrase)

The response logic seems at odds with the standard format.

Usually all commands and responses are handled in this manner - I’m using AT as an example:

ready = _parser.send("AT") && _parser.recv("OK\n");
if (ready) { ...  }

However, with the connect command it is as follows, which in my opinion is the reason for receiving an immediate response (it’s saying the send command was sent ok) when I shouldn’t be:

    bool res = _parser.send("AT+CWJAP_CUR=\"%s\",\"%s\"\r\n", ap, passPhrase);
    
    if (!res || !_parser.recv("OK\n")) {
    .....
   }

Would this logic not be better

if (res && !_parser.recv("OK\n")) {
 .....
}

Oh yes, as an aside observation, surely all AT commands except for AT itself require a CRNL. I don’t see that being used here in the ESP8266 driver.

It is not needed because It is done by the parser itself, it is set here

BR, Jan

1 Like

I’m looking at ATCmdParser.h and all I can see is it being stored in const char *_output_delimiter;

I cannot see how it is used with the send command. Maybe someone can explain the macro…

bool send(const char *command, ...) MBED_PRINTF_METHOD(1, 2);

It turns out it is my router. I still have no idea why it keeps triggering the NSAPI_STATUS_DISCONNECTED error.

To help with testing, I changed a setting on my mobile phone to operate as a mobile hotspot and my esp8266 firmware worked fine. Another nice thing is that the status event triggers works too.

I did some further testing. Turns out my router is fine. I hooked up a USB FTDI converter board to the ESP8266 module and manually entered all the commands, following the steps used in esp8266/esp8266_interface API. They all worked and I was able to connect first time and every time I repeated the test. I then ran my mbed OS program again using my phone as the wifi hotspot, as before. However, this time I had changed the password to include a " char within the password and this caused the same problem. I was not able to connect.