Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SmartConfig fails connection - appears not saving SSID #1100

Closed
mickeypop opened this issue Feb 12, 2018 · 45 comments
Closed

SmartConfig fails connection - appears not saving SSID #1100

mickeypop opened this issue Feb 12, 2018 · 45 comments

Comments

@mickeypop
Copy link

mickeypop commented Feb 12, 2018

Hardware:

Board:                                        ESP32 Core Dev Module, Generic Modules, and ESP32-VROOM
Core Installation/update date:  I do git update weekly, this update 2/10/18
IDE name:                                   Arduino IDE, 1.8.5
Flash Frequency:                        80Mhz
Upload Speed:                           921600

Description:

I may have found what is failing, but not sure how to fix this.
Note the print statements between "SmartConfig done." and "Waiting for WiFi".

Verbose Log shows SSID: myplace was passed but appears not to be saving. This is reproduced on 4 different boards.

Reading NVR the password is stored correctly but SSID does not seem to be saved, more so its blank.
This seems to be the fault resulting in connection failure.

Like others; the "Waiting for WiFi" loop never exits with AUTH_FAIL.

Note i added 2 extra log statements to the _smartConfigCallback() for better info

		log_d("bssid_set: %d", sta_conf->bssid_set);
		log_d("BSSID: %x", sta_conf->bssid); 

BASIC demo sketch with just a few prints added (indented)

#include "WiFi.h"
void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_AP_STA);
  WiFi.beginSmartConfig();

  Serial.println("Waiting for SmartConfig.");
  while (!WiFi.smartConfigDone()) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("SmartConfig done.");

	Serial.print( "\n\tREADING NVR\n");
	Serial.printf( "\tSSID = %s\n"   , WiFi.SSID().c_str() );
	Serial.printf( "\tPSK  = %s\n\n" , WiFi.psk().c_str()  );

  Serial.println("Waiting for WiFi");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print("WiFi Connected.\nIP Address: ");
  Serial.println(WiFi.localIP());
}
void loop() {
}

=== Verbose Log ==============

ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:956
load:0x40078000,len:0
load:0x40078000,len:11904
entry 0x40078a3c
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 13 - AP_STOP
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 14 - AP_STACONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 14 - AP_STACONNECTED
Waiting for SmartConfig.
.........[D][WiFiSTA.cpp:621] _smartConfigCallback(): Status: FIND_CHANNEL
...............[D][WiFiSTA.cpp:621] _smartConfigCallback(): Status: GETTING_SSID_PSWD
[D][WiFiSTA.cpp:624] _smartConfigCallback(): Type: ESPTOUCH
.....[D][WiFiSTA.cpp:621] _smartConfigCallback(): Status: LINK
[D][WiFiSTA.cpp:627] _smartConfigCallback(): SSID: myplace
[D][WiFiSTA.cpp:629] _smartConfigCallback(): bssid_set: 131
.
SmartConfig done.

	READING NVR
	SSID = 
	PSK  = J************e

	Waiting for WiFi
....[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 201 - AUTH_FAIL
..........................

My modified WiFiSTAClass::_smartConfigCallback( )

void WiFiSTAClass::_smartConfigCallback(uint32_t st, void* result) {
    smartconfig_status_t status = (smartconfig_status_t) st;
    log_d("Status: %s", sc_status_strings[st % 5]);
    if (status == SC_STATUS_GETTING_SSID_PSWD) {
        smartconfig_type_t * type = (smartconfig_type_t *)result;
        log_d("Type: %s", sc_type_strings[*type % 3]);
    } else if (status == SC_STATUS_LINK) {
        wifi_sta_config_t *sta_conf = reinterpret_cast<wifi_sta_config_t *>(result);
        log_d("SSID: %s", (char *)(sta_conf->ssid));
		
		log_d("bssid_set: %d", sta_conf->bssid_set);
		log_d("BSSID: %x", sta_conf->bssid);
		
        esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t *)sta_conf);
        esp_wifi_connect();
        _smartConfigDone = true;
    } else if (status == SC_STATUS_LINK_OVER) {
        if(result){
            ip4_addr_t * ip = (ip4_addr_t *)result;
            log_d("Sender IP: " IPSTR, IP2STR(ip));
        }
        WiFi.stopSmartConfig();
    }
}

@mickeypop
Copy link
Author

UPDATE
on a whim i scanned an found 2 example sketches were not updated.

I renamed the esp32 folder and did full clone.

It's working now

@dhernandezgt
Copy link

Hi Mickey how are your doing?

I am testing SmartConfig on ESP32 but have the problem you reported here.
I am able to config SSID/pass on ESP32 dev kit but after I reboot it configuration deleted and I have to use APP again for set confirgaration.
I copy your modified WiFiSTAClass::_smartConfigCallback( ) on .cpp file but still continue without store configuration
Would you share your solution for issue please?

thanks in advance

@mickeypop
Copy link
Author

mickeypop commented May 28, 2018

@dhernandezgt

for it to reconnect automatically on boot, you have to read in the stored WiFi settings and
run the WiFi.begin() with the stored settings

this should offer a complete SmartConfig / WiFi skeleton
- it deals with when to run SmartConfig, WiFi UP and DOWN
- Automatic reconnect and secondary credentials storage to prevent repeated writes to flash

i used WS8212 LEDs for the flasher and makes for too much code here.
Left notes to where i used the flasher if you want indicators.
ESP32Ticker library set the timing for flashing leds if you want a good esp32 ticker.

My approach to the flasher was to leave the ticker running and set a variable true or false to start and stop the LED.

#include "FS.h"
#include "esp_system.h"
#include <esp_wifi.h>
#include <string.h>
#include <WiFi.h>
#include <Preferences.h>  // WiFi storage

  const  char* rssiSSID;       // NO MORE hard coded set AP, all SmartConfig
  const  char* password;
  String PrefSSID, PrefPassword;  // used by preferences storage

  int  WFstatus;
  int UpCount; = 0;
  int32_t rssi;           // store WiFi signal strength here
  String getSsid;
  String getPass;
  String  MAC;

  // SSID storage
       Preferences preferences;  // declare class object
  // END SSID storage
  
void setup() {
  Serial.begin(115200);
  Serial.printf("\tWiFi Setup -- \n"  ); 

  wifiInit();       // get WiFi connected
  IP_info();
  MAC = getMacAddress();

  delay(2000);
} //  END setup()
  
void loop()
{
  if ( WiFi.status() ==  WL_CONNECTED )      // Main connected loop

  { 
		// ANY MAIN LOOP CODE HERE

  }   // END Main connected loop()
  else
  {            // WiFi DOWN

     //  wifi down start LED flasher here

         WFstatus = getWifiStatus( WFstatus );

     WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );
     int WLcount = 0;
     while (WiFi.status() != WL_CONNECTED && WLcount < 200 )
     {
      delay( 100 );
         Serial.printf(".");

         if (UpCount >= 60)  // keep from scrolling sideways forever
         {
            UpCount = 0;
               Serial.printf("\n");
         }
         ++UpCount;
         ++WLcount;
     }

    if( getWifiStatus( WFstatus ) == 3 )   //wifi returns
    { 
		// stop LED flasher, wifi going up
    }
     delay( 1000 );
  }  // END WiFi down 
} // END loop()
  
void wifiInit()  // 
{
   WiFi.mode(WIFI_AP_STA);   // required to read NVR before WiFi.begin()

   // load credentials from NVR, a little RTOS code here
   wifi_config_t conf;
   esp_wifi_get_config(WIFI_IF_STA, &conf);  // load wifi settings to struct comf
   rssiSSID = reinterpret_cast<const char*>(conf.sta.ssid);
   password = reinterpret_cast<const char*>(conf.sta.password);

    //  Serial.printf( "%s\n", rssiSSID );
    //  Serial.printf( "%s\n", password );

   // Open Preferences with "wifi" namespace. Namespace is limited to 15 chars
   preferences.begin("wifi", false);
       PrefSSID          =  preferences.getString("ssid", "none");      //NVS key ssid
       PrefPassword  =  preferences.getString("password", "none");  //NVS key password
   preferences.end();

   // keep from rewriting flash if not needed
   if( !checkPrefsStore() )    	// see is NV and Prefs are the same
   {  						// not the same, setup with SmartConfig
      if( PrefSSID == "none" )  // New...setup wifi
      {
        initSmartConfig(); 
        delay( 3000);
        ESP.restart();   // reboot with wifi configured
      }
   } 

   // I flash LEDs while connecting here

   WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );

   int WLcount = 0;
   while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) // can take > 100 loops depending on router settings
   {
     delay( 100 );
        Serial.printf(".");
     ++WLcount;
   }
  delay( 3000 );

  //  stop the led flasher here

  }  // END wifiInit()

// match WiFi IDs in NVS to Pref store,  assumes WiFi.mode(WIFI_AP_STA);  was executed
bool checkPrefsStore()   
{
    bool val = false;
    String NVssid, NVpass, prefssid, prefpass;

    NVssid = getSsidPass( "ssid" );
    NVpass = getSsidPass( "pass" );

    // Open Preferences with my-app namespace. Namespace name is limited to 15 chars
    preferences.begin("wifi", false);
        prefssid  =  preferences.getString("ssid", "none");     //NVS key ssid
        prefpass  =  preferences.getString("password", "none"); //NVS key password
    preferences.end();

    if( NVssid.equals(prefssid) && NVpass.equals(prefpass) )
      { val = true; }

  return val;
}

// optionally call this function any way you want in your own code
// to remap WiFi to another AP using SmartConfig mode.   Button, condition etc.. 
void initSmartConfig() 
{
   // start LED flasher
  int loopCounter = 0;

  WiFi.mode( WIFI_AP_STA );       //Init WiFi, start SmartConfig
      Serial.printf( "Entering SmartConfig\n" );

  WiFi.beginSmartConfig();

  while (!WiFi.smartConfigDone()) 
  {
     // flash led to indicate not configured
          Serial.printf( "." );
     if( loopCounter >= 40 )  // keep from scrolling sideways forever
     {
         loopCounter = 0;
         Serial.printf( "\n" );
     }
     delay(600);
    ++loopCounter;
  }
  loopCounter = 0;

  // stopped flasher here

   Serial.printf("\nSmartConfig received.\n Waiting for WiFi\n\n");
   delay(2000 );
	  
  while( WiFi.status() != WL_CONNECTED )    	// check till connected
  { 
    delay(500);
  }
  IP_info();  // connected lets see IP info

  preferences.begin("wifi", false);      // put it in storage
     preferences.putString( "ssid"         , getSsid);
     preferences.putString( "password", getPass);
  preferences.end();

    delay(300);
}  // END SmartConfig()

void IP_info()
{
   getSsid = WiFi.SSID();
   getPass = WiFi.psk();
   rssi = getRSSI(  rssiSSID );
   WFstatus = getWifiStatus( WFstatus );
   MAC = getMacAddress();

      Serial.printf( "\n\n\tSSID\t%s, ", getSsid.c_str() );
      Serial.print( rssi);  Serial.printf(" dBm\n" );  // printf??
      Serial.printf( "\tPass:\t %s\n", getPass.c_str() ); 
      Serial.print( "\n\n\tIP address:\t" );  Serial.print(WiFi.localIP() );
      Serial.print( " / " );
      Serial.println( WiFi.subnetMask() );
      Serial.print( "\tGateway IP:\t" );  Serial.println( WiFi.gatewayIP() );
      Serial.print( "\t1st DNS:\t" );     Serial.println( WiFi.dnsIP() );
      Serial.printf( "\tMAC:\t\t%s\n", MAC.c_str() );
}

int getWifiStatus( int WiFiStatus  )
{
  WiFiStatus = WiFi.status();
  Serial.printf("\tStatus %d",  WiFiStatus );
  switch( WiFiStatus )
  {
    case WL_IDLE_STATUS :                         // WL_IDLE_STATUS     = 0,
          Serial.printf(", WiFi IDLE \n");
          break;
    case WL_NO_SSID_AVAIL:                        // WL_NO_SSID_AVAIL   = 1,
          Serial.printf(", NO SSID AVAIL \n");
          break;
    case WL_SCAN_COMPLETED:                       // WL_SCAN_COMPLETED  = 2,
          Serial.printf(", WiFi SCAN_COMPLETED \n");
          break;
    case WL_CONNECTED:                            // WL_CONNECTED       = 3,
          Serial.printf(", WiFi CONNECTED \n");
          break;
    case WL_CONNECT_FAILED:                       // WL_CONNECT_FAILED  = 4,
          Serial.printf(", WiFi WL_CONNECT FAILED\n"); 
          break;
    case WL_CONNECTION_LOST:                      // WL_CONNECTION_LOST = 5,
          Serial.printf(", WiFi CONNECTION LOST\n");
          WiFi.persistent(false);                 // don't write FLASH
          break;
    case WL_DISCONNECTED:                         // WL_DISCONNECTED    = 6
          Serial.printf(", WiFi DISCONNECTED ==\n");
          WiFi.persistent(false);                 // don't write FLASH when reconnecting
          break;
  }
  return WiFiStatus;
}
// END getWifiStatus()

// Get the station interface MAC address.
// @return String MAC
String getMacAddress(void)
{
    WiFi.mode(WIFI_AP_STA);                    // required to read NVR before WiFi.begin()
    uint8_t baseMac[6];
    esp_read_mac( baseMac, ESP_MAC_WIFI_STA ); // Get MAC address for WiFi station
    char macStr[18] = { 0 };
    sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
    return String(macStr);
}
// END getMacAddress()


// Return RSSI or 0 if target SSID not found
// const char* SSID = "YOUR_SSID";  // declare in GLOBAL space
// call:  int32_t rssi = getRSSI( SSID );
int32_t getRSSI( const char* target_ssid ) 
{
  byte available_networks = WiFi.scanNetworks();

  for (int network = 0; network < available_networks; network++) 
  {
    if ( strcmp(  WiFi.SSID( network).c_str(), target_ssid ) == 0) 
    {
      return WiFi.RSSI( network );
    }
  }
  return 0;
} //  END  getRSSI()


// Requires; #include <esp_wifi.h>
// Returns String NONE, ssid or pass arcording to request 
// ie String var = getSsidPass( "pass" );
String getSsidPass( String s )
{
  String val = "NONE";  // return "NONE" if wrong key sent
  s.toUpperCase();
  if( s.compareTo("SSID") == 0 )
  {
     wifi_config_t conf;
     esp_wifi_get_config( WIFI_IF_STA, &conf );
     val = String( reinterpret_cast<const char*>(conf.sta.ssid) );
  }
  if( s.compareTo("PASS") == 0 )
  {
     wifi_config_t conf;
     esp_wifi_get_config( WIFI_IF_STA, &conf );
     val = String( reinterpret_cast<const char*>(conf.sta.password) );
  }
 return val;
}

@dhernandezgt
Copy link

hi Mickey,

thanks for your code and your fast response, a little more complex, I have a question about *.h sources and another for variables in code. please have a look on them.

  1. the sources file I don't have some of them such as FS.h, esp_system.h, string.h and Preferences.h. do they belong to different packages?
#include "FS.h"
#include "esp_system.h"
#include <esp_wifi.h>
#include <string.h>
#include <WiFi.h>
#include <Preferences.h> // WiFi storage
  1. I tried to pass on Arduino IDE but it pop up with a variable does not declared onto scope. it is UpCount and probably WLcount else

image

the part of code is:

WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );
int WLcount = 0;
while (WiFi.status() != WL_CONNECTED && WLcount < 200 )
{
delay( 100 );
Serial.printf(".");

     if (UpCount >= 60)  // keep from scrolling sideways forever
     {
        UpCount = 0;
           Serial.printf("\n");
     }
     ++UpCount;
  ++WLcount;
}

Regards.

DH

@mickeypop
Copy link
Author

mickeypop commented May 28, 2018

1 the .h files are part of the espressif clone you did to setup arduino

2 put UpCount at top of your code near int WFstatus

int UpCount = 0;

@dhernandezgt
Copy link

hi Mickey,

After set UpCount variable compiling continues but display another error shows below. I tried to use same approach (it is not variable I guess it because it attached to a method) without successful.

image

thanks again for your support, regards.

DH

@mickeypop
Copy link
Author

mickeypop commented May 28, 2018

sorry about that. I put that skeleton together fairly fast from other code.
any time you see an <object>.<function> it's part of a Class.
ie preferences.getString(...);

So Preferences preferences; declares the object "preferences"

put this in top section of code below the .h declarations and before setup()

  **// SSID storage
         Preferences preferences;  // declare class object
  // END SSID storage**

@dhernandezgt
Copy link

dhernandezgt commented May 29, 2018 via email

@vinot
Copy link

vinot commented Jun 16, 2018

Hi all,
thank you so much Mickey, I still don't know how, but you resolved it ( I was also trying to save ssid/pass to recover it after rebooting the esp through nvs). What surprise me is, after load and test (very quick) your sketch, I upload my sketch (without modifications) and, after several reboots, esp loads ssid/pass at first time.

thank you again
toni

@mickeypop
Copy link
Author

mickeypop commented Jun 16, 2018

vinot
Glad you like it

You want to see what it can do?

While it is running unplug your router and watch.
In about 15-30 seconds it will see the wifi is down.

Plug it back in and in about 40 seconds it will reconnect automatically and be back on line.

@vinot
Copy link

vinot commented Jun 17, 2018

hi Mickey

definetly I'm going to spend the necessary time to understand all your code. We are developing a simple hardware (virtual feet) for VR and esp32 seems to be a good way, even it's more complex than others mcu, but also more powerful.

thank you again

@rodrigoazor
Copy link

Hi Mickey,

Sory... can you help me ?
sem titulo

@mickeypop
Copy link
Author

@rodrigoazor

not seeing your code, esp_system.h has got to be missing
ESP_MAC_WIFI_STA is declared as a typedef there.

just add it to the top of your code in global space;
#include "esp_system.h"

==========
Separately just for info;
look at my getMacAddress() in the skeleton code above.
first line sets mode, this is critically important.
WiFi.mode( WIFI_AP_STA ); // required to read NVR before WiFi.begin() or mode set

if you don't have wifi connected before a call to esp_read_mac() it will fail and the compiler will catch it.

have wifi.mode set before esp_read_mac() and it should work

if WiFi services are not setup several data areas are not accessible. SSID, PASS, MAC, INDEX etc...
once the WiFi is connected(sets mode) or the mode is set they open up.

@waged
Copy link

waged commented Aug 13, 2018

Hi Dr.mickeypop , I've used your code and it's really working fine but the problem now that sometimes in the code the ESP32 stuck in that message: DROWNPIN FIRED
What do you think it's the problem ?
Thanks in Advance 👍

@mickeypop
Copy link
Author

mickeypop commented Aug 13, 2018

@waged

"DROWNPIN FIRED" is not in any of my code and just did a search of the SDK with no results.
is that possibly a typo?

a couple of questions;

  • is that declared in your code somewhere?
  • is it in a loop, repeating or just posted occasionally?
  • does it print unce and hang or recover?

if you can, send it to; mickey ( user domain seperator ) (my domain)(the little point) com
Sorry about the cryptic email but too many robots collect if they are posted directly.

I'll give it a look if you want.
my domain; datasoftllc

Not having your code I am going to make a big assumption;

  • you have 1 or more inputs and are declared pinMode( PinName, INPUT); .
  • it triggers when you or some other source comes "Near" the ESP, especially moving

ESP8266 and ESP32 have very high impedance on their pins.
Without a pullup resistance they will "Float" and act like an antenna causing false input.

One of two approaches fall here;

  • add a phyisical pullup resistor
  • simplest pinMode( PinName, INPUT_PULLUP);

INPUT_PULLUP will turn on an internal pullup and stop the floating.

@waged
Copy link

waged commented Aug 14, 2018

Hi Dr.Mickeypop ,
Yeah It's the problem of the input PIN was floating, Thanks for your support but there's one thing , what would be the scenario if i want to join other wifi and want to configure the module to AP again ?
like the esp-12 code:
wifi = init_wifi(WIFI_SSID, WIFI_PASSPHARSE, SMARTCONFIG_BUTTON_PIN);
Thanks 💯 %

@mickeypop
Copy link
Author

@waged

sorry i forgot a way to call up mapping to a different AP after the initial setup.
As noted in an earlier post i put the template together in less than an hour.

It started SmartConfig Mode if the credentials had not been set yet.
Since you already have them set it does not run automatically.

Wifi was mapped using initSmartConfig(); just call that function any way you want, button press, condition etc...

Once in SmartConfig mode just connect to an AP as before.

Just remember the smartphone/tablet needs to be connected to the AP you are mapping it to.

@waged
Copy link

waged commented Aug 16, 2018

@mickeypop
Thanks A LOT it's really very good piece of code :) really thanks <3

@mickeypop
Copy link
Author

glad it helps

@copercini
Copy link
Contributor

@mickeypop Could you please create a pull request with your code? this is VERY helpful, but hard to find, this will help more people the same way that helped me too =) Thanks anyway

@mickeypop
Copy link
Author

@copercini
not sure why yet but it won't let me make a new pull request.

if i could find out WHO to contact i would send it to be added to the examples

@komputerboy
Copy link

@mickeypop
Thanks it works very well.
But, i have question, could smart config save another custom data beside SSID and password?

@mickeypop
Copy link
Author

mickeypop commented Feb 3, 2019

@komputerboy

theoretically yes but you would have to write your own library and sending software.

SmartConfig was invented in 1993 by Texas Instruments to send a specially formatted packet by UDP to a network. Any device in promiscuous mode that recognizes the packet structure can be configured.
When that device sees the format it is looking for it is parsed and the network credentials are installed.

This technique could be used for just about anything if the sending and receiving software was written.

@komputerboy
Copy link

@mickeypop

Well, Unfortunately I'm not good at programming. So, I will looking for another method.
Thanks for your Reply and Great Explanation,

@mickeypop
Copy link
Author

mickeypop commented Feb 4, 2019

@komputerboy

There are many examples on the web of using UDP to turn on LEDs, relays etc....
A whole library may not be needed but you may need to deal with the sending software solution.

It's just that the SmartConfig was written with one purpose in mind though the method can be used elsewhere just not that library.

Keep in mind; UDP sends by the MAC address of a device not the IP.

Can you post more complete info on what you are tying to do?

Would a simple blind web URL on the device work as well?
Simple BLIND URL
**```
#include "esp_system.h"
#include <esp_wifi.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h> //https://github.com/bbx10/WebServer_tng
#include <WiFiUdp.h> // needed for UDP and SmartConfig

WebServer server ( 80 );      // declare the server

void setup()
{
        server.begin();   // start web server
        Udp.begin(8888);   // you can set other port, though this is default 
        server.on( "/pal", handlePal );   // create URL  and link it to handlePal()
}

void loop()
{  // do whatever here
}


// accept and save valid palette number
void handlePal()       // send  http://192.168.1.212/pal?n=N  where N is the pallete color index
{
  String Value = server.arg(0);
  Serial.println( Value );

  // do anything you need with Value now that you have it

    server.send ( 200, "", "" );  // leave last  returns 200 Accknowledge but no web page ( BLIND)
} // END handlePal()


@komputerboy
Copy link

komputerboy commented Feb 6, 2019

@mickeypop

Thanks for Your Responses.

Well, I want to make a "pairing/configuring" task on ESP32 with my smartphone. But not only configure SSID and PASWORD of WiFi but also some custom data and save it to ESP32. So, i dont have to "hardcoded" my program.

So, my data will be like this:

  • SSID
  • Password
  • Custom Data1
  • Custom Data2

I've done configuring SSID and PASSWORD using Your SmartConfig's Program. But what about the Custom data?

But, for now I use another method, using database -> Google Firebase. So my program will be like this:

  1. ESP32 boot on smartconfig
  2. Smartphone connected to desired Wifi, and start smartconfig
  3. ESP32 received SSID and PASSWORD and then connect to WiFi
  4. When pairing is succesfull, then smartphone send Custom Data to Firebase
  5. ESP32 connect to Firebase and read Custom Data.
  6. Save ALL of Data to NVS
    (This process take time only about 30 sec)

But, if someone know another robust method, I gladly to know that

@sansillusion
Copy link

Wifimanager is a library that does that, look here : https://github.com/tzapu/WiFiManager#custom-parameters

@Dexter-SSE
Copy link

Hi Mickey
Awesome Code, You saved me from a big trouble.
Your code is working great on ESP32.
I just want to know can this code be implemented on esp8266.
When I tried to compile it for nodeMCU 12E it show error

NODEMCU:2:24: error: esp_system.h: No such file or directory

#include "esp_system.h"

                    ^

compilation terminated.

exit status 1
esp_system.h: No such file or directory

Can you help me out
Regards

@mickeypop
Copy link
Author

mickeypop commented Sep 24, 2019

the skeleton i posted is not ESP8266 friendly unfortunately.

#include "esp_system.h" is specific to RTOS wrapper

Arduino on the ESP8266 does not use the RTOS like the 32 does.
Also you will note i use the preferences.h library and it does not support the 8266 at all.

If you look at the structure of the skeleton code an ESP8266 rewrite would require rewrite all preferences code to say SPIFFS and JSON also every ESP32 specific code would need replaced or removed.

The wifi library is good however, i do several calls outside of the library to RTOS directly, bypassing the wifi library.
This was done because the wifi library cannot get credentials from NV Ram until it is connected and i need to test and read it on boot BEFORE connecting. RTOS can, wifi lib cannot.

    ie;      esp_wifi_get_config(....)    // those functions starting with esp_ are RTOS and ESP32 specific

in order to test stored from changed credentials, i needed to read the credentials before re-storing over the same to save the life of the flash. It should be noted you can only re-write flash around 10,000 times before it trashes the flash permanently trashing the MCU.
.

@Dexter-SSE
Copy link

Hi Mickey
Thanks for the reply, Now Have concentrated my complete development process yo ESP32 only and it is going well.
I am facing another Issue with the fact even after autoconfig is over and wifi credentials are saved, there is a Access Point available on searching for Wifi from any phone named as ESP_4D736D which is also Open and sometime esp32 after powered on for longer period start showing this
"dhcps: send_offer>>udp_sendto result 0"
in serial monitor and stop functioning properly.
Is there a way that once Autoconfig is over this Access Point is disabled and Esp32 remain in Station Mode.
Regards

@mickeypop
Copy link
Author

mickeypop commented Oct 7, 2019

Dexter-SSE

in wifiInit(), i set WiFi.mode(WIFI_AP_STA); to read NVR before WiFi.begin().
this was needed to read the credentials and compare before connect change to save the life of the FLASH.

Once you know wifi is up execute WiFi.mode(WIFI_STA); to disable AP mode.

That should stop it and still leave the station connected.

@Dexter-SSE
Copy link

Hi Mickey
Here I am again and this time i really need to implement this code(AutoConfig) on esp8266 but not even getting close to it get it working on esp8266, Have you ever able to get it done in esp12e ,
Need help
Regards

@sharmashrey48
Copy link

Hi Mickey
Thanks a lot for solving this Issue. I'm having an issue with providing new wifi credentials to the ESP32. I want to change my wifi network and now every time i restart esp32 it doesn't takes the new wifi credentials from the app and show the previous stored password only.
will you please help me with this issue ?
Thank you so much again.

@mickeypop
Copy link
Author

@sharmashrey48
look at the skeleton code i posted May 27, 2018
attach initSmartConfig() to a button or whatever and you can remap with SmartConfig app

simple check during boot
i mapped mine with a check to a button in setup() if LOW it started initSmartConfig()

@sharmashrey48
Copy link

@mickeypop sorry my bad, I missed that. It worked. Thank you so much for the code and thanks again for helping me out. Have a nice day :)

@christophepersoz
Copy link

christophepersoz commented Feb 3, 2020

Hello @mickeypop,

I tried your sketch about SmartConfig (#1100 (comment)), as the one provided in the Arduino ESP 1.0.4 does not work on my network. The sketch compile is OK, but the connection does not occurs. I'm using the app provided by Espressif (Esptouch) on my iPhone to send the SSID/Pass to the ESP but I only got is:

.	WiFi Setup -- 
Entering SmartConfig
.........................................
........................................
........................................
........................................
........................................

I tried different method on WiFi.mode(); but neither WIFI_AP_STA or WIFI_STA seems working. My Wifi network is configured in 2.4Ghz and 5Ghz, but that does not change anything.

Do you have any clue about what could be wrong?
thanks in advance!

  • Update -
    I decide to reconfigure my router to provide 2 different network, one 2.4Ghz and an another on 5Ghz to be sure that the AP used is compatible with the ESP, SmartConfig as well as ESPtouch.
    Things going better, as it seems that ESPtouch can reach the ESP32, but something make it crash.
    Here what I'm getting on serial output:
WiFi Setup -- 
Entering SmartConfig
.........................................
........................................
........................................
........................................
........................................
..............................E (138395) wifi: wifi ipc: failed to post wifi task
assertion "res == coreID || res == portMUX_FREE_VAL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.inc.h", line 105, function: vPortCPUAcquireMutexIntsDisabledInternal
abort() was called at PC 0x40102a43 on core 0

Backtrace: 0x4008c434:0x3ffb5060 0x4008c665:0x3ffb5080 0x40102a43:0x3ffb50a0 0x40089b95:0x3ffb50d0 0x400888b4:0x3ffb5100 0x400889ed:0x3ffb5140 0x4008506d:0x3ffb5160 0x40085161:0x3ffb5190 0x4010b01e:0x3ffb51b0 0x4010e28d:0x3ffb54c0 0x40084376:0x3ffb54f0 0x400e369d:0x3ffb5540 0x400fd399:0x3ffb5570 0x40100853:0x3ffb55a0 0x40101e59:0x3ffb5610 0x400fd8e5:0x3ffb5670 0x4013992a:0x3ffb5690 0x4008f5cd:0x3ffb56b0 0x40088b7d:0x3ffb56f0

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac

I also notice that the sketch provided as WiFiSmartConfig.ino is also crashing as soon as the data provided by ESPtouch are received, here the other log for this sketch:

Waiting for SmartConfig.
...............E (7859) wifi: wifi ipc: failed to post wifi task
CORRUPT HEAP: Bad head at 0x3ffbbcb4. Expected 0xabba1234 got 0x3ffbdaf4
assertion "head != NULL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap/multi_heap_poisoning.c", line 214, function: multi_heap_free
abort() was called at PC 0x401012bf on core 0

Backtrace: 0x4008c434:0x3ffb5450 0x4008c665:0x3ffb5470 0x401012bf:0x3ffb5490 0x4008c0a9:0x3ffb54c0 0x40084b12:0x3ffb54e0 0x40084f19:0x3ffb5500 0x4000bec7:0x3ffb5520 0x400e1fd1:0x3ffb5540 0x400fbc11:0x3ffb5570 0x400ff0cb:0x3ffb55a0 0x401006d5:0x3ffb5610 0x400fc15d:0x3ffb5670 0x401380f2:0x3ffb5690 0x4008f5cd:0x3ffb56b0 0x40088b7d:0x3ffb56f0

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac

It is not the same error, but both seems related to wifi ipc
Does that ring a bell to you or to anybody else?

Thanks!

@mickeypop
Copy link
Author

@christophepersoz
The skeleton code i provided has worked on 14 projects, 9 of them commercial without fail.

Either your compile environment or your code have a conflict.
Without your code there is little i can check here.

One issue; the PATH to the library is not a typical arduino setup path for espressif RTOS.
How did you setup the esp32 libraries?
normal install your sketches folder/hardware/espressif/esp32

Go to https://github.com/me-no-dev/EspExceptionDecoder and install the EspExceptionDecoder in the tools folder as shown.

Then cut and paste the BackTrace from the terminal output and it will show where your code has a conflict. It looks thru your ELF file to find what is going on.

It has saved my bacon several times.

@lbernstone
Copy link
Contributor

Please don't hijack issues. Your problem is not the same as the OP. Open a new issue and follow the issue template. You MUST include a decoded backtrace. If you cannot get the exception decoder working, please open an issue in that repository.

@christophepersoz
Copy link

My apologies, I open a new issue here #3711
and removed my last post here.

@johnwargo
Copy link

1 the .h files are part of the espressif clone you did to setup arduino

2 put UpCount at top of your code near int WFstatus

int UpCount = 0;

@mickeypop sorry to ask this so long after this was closed, but I'm trying to find the preferences file, where can I find it? You mention the espressif clone, which one? I'm looking at the arduino-esp32 repo and can't find it.

@lbernstone
Copy link
Contributor

Preferences is an arduino-esp32 included library.

@mickeypop
Copy link
Author

@johnwargo
you don't need to access the files directly, just include preferences.h and call the class

when you clone ESP32 from espressif the preferences library is included
the path on my install;
C:\Users\Mickey\Documents\Arduino\hardware\espressif\esp32\libraries\Preferences\src

hope it helps

@johnwargo
Copy link

@mickeypop thanks.

@Huzaifa-Ahmad55
Copy link

hi @mickeypop how to expand smartconfig response? like some random string with mac and ip address.

@mickeypop
Copy link
Author

@Huzaifa-Ahmad55
if you look at the template above in wifiInit() i look to see if SmartConfig is needed.

if it is connected the leds change green for a few seconds then out, if failed red.

in setup wifiInit() is called right before IPinfo()

either way you get the IP and many other parameters or the failure notice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests