1 (edited by CP 2019-05-10 20:36:02)

Topic: How can i change wifi credentials without flashing code?

Any suggestions on manually configuring wifi credentials without flashing updated code.
i am using a Nodemcu with RemoteXY cloud feature

i have tried to integrate WifiManager library.   https://github.com/tzapu/WiFiManager
This library allows setup of wifi credentials via an open broadcasted access point which then directs to a browser upon connecting. from this browser the wifi ssid and password can be set. Even after resetting the nodemcu it will automatically reconnect using the last saved ssid and pass. its a really good addition to any project.

My Problem:
i Integrated the wifimanager library into my RemoteXY code.
i am able to connect to the Wifimanager access point and configure credentials in browser as it should. After a few seconds i can successfully view my stats on the remotexy app. However, if the nodemcu is reset then it does not recall the last saved credentials from wifimanager library, it seems to look at the RemoteXY library for the hardcoded SSid and pass, i have even tried leaving it blank.  The process of configuring credentials through wifi manager has to be repeated on wifi loss or device reset for it to work again.

Any alternative recommendations?

/* 
   -- TankControllerv1 -- 
    
   This source code of graphical user interface  
   has been generated automatically by RemoteXY editor. 
   To compile this code using RemoteXY library 2.3.3 or later version  
   download by link http://remotexy.com/en/library/ 
   To connect using RemoteXY mobile app by link http://remotexy.com/en/download/                    
     - for ANDROID 4.1.1 or later version; 
     - for iOS 1.2.1 or later version; 
     
   This source code is free software; you can redistribute it and/or 
   modify it under the terms of the GNU Lesser General Public 
   License as published by the Free Software Foundation; either 
   version 2.1 of the License, or (at your option) any later version.     
*/ 

////////////////////////////////////////////// 
//        RemoteXY include library          // 
////////////////////////////////////////////// 

// RemoteXY select connection mode and include library  
#define REMOTEXY_MODE__ESP8266WIFI_LIB_CLOUD
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h"          //https://github.com/tzapu/WiFiManager


#include <RemoteXY.h> 


// RemoteXY connection settings  
#define REMOTEXY_WIFI_SSID "" 
#define REMOTEXY_WIFI_PASSWORD ""
#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com" 
#define REMOTEXY_CLOUD_PORT 6376 
#define REMOTEXY_CLOUD_TOKEN "37eaf6e21f4291d8852669b5b9a" 




// RemoteXY configurate   
#pragma pack(push, 1) 
uint8_t RemoteXY_CONF[] = 
  { 255,0,0,72,0,63,1,8,24,2,
  65,6,25,56,5,5,13,9,9,9,
  66,1,61,9,37,27,42,6,7,16,
  192,26,65,6,87,56,5,5,19,8,
  9,9,66,1,2,9,36,27,45,24,
  27,18,192,26,67,4,78,51,20,4,
  10,16,20,5,31,26,11,67,4,18,
  51,20,4,53,14,20,5,31,26,11,
  129,0,2,58,11,3,15,5,18,6,
  13,80,117,109,112,32,49,0,129,0,
  62,58,11,3,53,4,18,6,13,80,
  117,109,112,32,50,0,129,0,11,2,
  12,4,39,5,10,4,13,84,97,110,
  107,32,49,0,129,0,72,3,12,4,
  53,6,12,4,13,84,97,110,107,32,
  50,0,67,4,18,46,20,4,22,38,
  20,4,31,26,11,67,4,78,46,20,
  4,37,45,20,4,31,26,11,129,0,
  1,47,11,3,-1,45,11,3,13,70,
  108,111,119,32,77,101,116,101,114,0,
  129,0,1,52,11,3,0,49,11,3,
  13,83,116,97,116,117,115,0,129,0,
  61,47,11,3,53,45,11,3,13,70,
  108,111,119,32,77,101,116,101,114,0,
  129,0,61,52,11,3,53,48,11,3,
  13,83,116,97,116,117,115,0,129,0,
  61,41,11,3,53,38,11,3,13,76,
  101,118,101,108,32,40,109,41,0,67,
  4,18,41,20,4,14,35,20,4,31,
  26,11,67,4,78,41,20,4,53,35,
  20,4,31,26,11,129,0,1,41,11,
  3,-2,40,11,3,13,76,101,118,101,
  108,32,40,109,41,0 }; 
   
// this structure defines all the variables of your control interface  
struct { 

    // output variable
  uint8_t led_1_r; // =0..255 LED Red brightness 
  uint8_t led_1_g; // =0..255 LED Green brightness 
  int8_t level_2; // =0..100 level position 
  uint8_t led_2_r; // =0..255 LED Red brightness 
  uint8_t led_2_g; // =0..255 LED Green brightness 
  int8_t level_1; // =0..100 level position 
  char text_6[11];  // string UTF8 end zero 
  char text_3[11];  // string UTF8 end zero 
  char text_2[11];  // string UTF8 end zero 
  char text_5[11];  // string UTF8 end zero 
  char text_1[11];  // string UTF8 end zero 
  char text_4[11];  // string UTF8 end zero 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY; 
#pragma pack(pop) 


///////////////////////////////////////////// 
//           END RemoteXY include          // 
///////////////////////////////////////////// 

void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
}




void setup()  
{ 
   // put your setup code here, to run once:
  Serial.begin(115200);

  
  RemoteXY_Init ();  

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset settings - for testing
  //wifiManager.resetSettings();

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if(!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  } 

  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");
 

  // TODO you setup code 
   
} 

void loop()  
{  

  int temp= 3;
char stringtemp[] = "WARNING"; 

RemoteXY_Handler (); 

     RemoteXY.led_1_g = 250;  // 50% brightness 
  RemoteXY.led_2_r = 250;  // 25% brightness 
    RemoteXY.level_1 = 30; // =0..100 level position 
     RemoteXY.level_2 = 80; // =0..100 level position 


      dtostrf(1, 0, 1, RemoteXY.text_1);
      dtostrf(temp, 0, 1, RemoteXY.text_4);    
      sprintf(RemoteXY.text_6, stringtemp); 
      sprintf(RemoteXY.text_3, "OK"); 
     // dtostrf(WARNING, 0, 1, RemoteXY.text_6);
  // TODO you loop code 
  // use the RemoteXY structure for data transfer 


}

2 (edited by Guillaume 2019-05-10 23:33:31)

Re: How can i change wifi credentials without flashing code?

Welcome,

You can create your own remotexy module, mainly changing the initModule() function to do whatever you want. I will show you an example:

Original module:

class CRemoteXY : public CRemoteXY_API {

  protected:
  uint16_t port;
  char * wifiSsid;
  char * wifiPassword;
  
  WiFiServer *server;
  WiFiClient client; 
  
  uint8_t wifiStatus;
  uint32_t serverTimeOut;
  
  uint8_t sendBuffer[REMOTEXY_SEND_BUFFER_LENGTH];
  uint16_t sendBufferCount; 
  uint16_t sendBytesAvailable;  

  public:
  CRemoteXY (const void * _conf, void * _var, const char * _accessPassword, const char * _wifiSsid, const char * _wifiPassword, uint16_t _port) {
    port = _port;
    wifiSsid = (char *) _wifiSsid;
    wifiPassword = (char *) _wifiPassword;
    serverTimeOut = 0;
    init (_conf, _var, _accessPassword);    
  }
  
  uint8_t initModule () {  
    delay(100);
    WiFi.disconnect();
    WiFi.softAPdisconnect(true);
#if defined(REMOTEXY_WIFI__POINT)
    /* access point */
    WiFi.mode(WIFI_AP);
    WiFi.softAP(wifiSsid, wifiPassword);
#if defined(REMOTEXY__DEBUGLOGS)
    DEBUGLOGS_write ("IP: ");
    REMOTEXY__DEBUGLOGS.print (WiFi.softAPIP());
#endif
#else    
    /* station */
    WiFi.mode(WIFI_STA);
    WiFi.begin(wifiSsid, wifiPassword);
    delay(1000);
    
#if defined(REMOTEXY__DEBUGLOGS)
    DEBUGLOGS_write("Started connecting to access point...");
#endif    
#endif
    client.stop();
    server = new WiFiServer (port);
    server->begin();    
    server->setNoDelay(true);
#if defined(REMOTEXY__DEBUGLOGS)
    DEBUGLOGS_write ("Server started");
#endif
    return 1;
  }

 
Custom module:

class myRemoteXY : public CRemoteXY_API
{

protected:

    uint16_t port;

    WiFiServer *server;
    WiFiClient client; 

    uint8_t wifiStatus;
    uint32_t serverTimeOut;

    uint8_t sendBuffer[REMOTEXY_SEND_BUFFER_LENGTH];
    uint16_t sendBufferCount; 
    uint16_t sendBytesAvailable;  

public:

    void begin( const void * _conf, void * _var, const char * _accessPassword, uint16_t _port )
    {
        port = _port;
        serverTimeOut = 0;
        init( _conf, _var, _accessPassword );
    }

    uint8_t initModule()
    {
        client.stop();

        if ( server == nullptr )
        {
            server = new WiFiServer( port );
        }

        server->begin();
        server->setNoDelay( true );

        #if defined REMOTEXY__DEBUGLOGS
            REMOTEXY__DEBUGLOGS.println( "Server started" );
        #endif

        return 1;
    }
    
    // etc

Which I then use like this (for example):

myRemoteXY remoteXY;

void onWiFiConnected()
{
    remoteXY.begin( remoteXY_config, &remoteXY_struct, "", remoteXY_port);
}

Note that the customized module doesn't call WiFi.begin etc, I do that myself in the main program so I have full control of it.

3

Re: How can i change wifi credentials without flashing code?

@Guillaume

Thanks for the welcoming and prompt guidance.
I will work with it and post feedback soon.

4

Re: How can i change wifi credentials without flashing code?

@ CP

I have the same problem and my skills dot not let me understand the recommandations of Guillaume to implement the functionalities you were looking for. Have you succeed in a solution with or without these recommandations? COuld you help me (Or Guillaume) to implement this one ?

What I Don't understand in the recommandations of guillaume
- where to use the "myRemoteXY" module ?   (myRemoteXY remoteXY;)
- instruction to call "WiFi.begin etc " in the main program => where and how ?

Thanks for reading … and as possible responding :-)
JP

5

Re: How can i change wifi credentials without flashing code?

Jpma, sorry I forgot to reply, you can find another example here http://forum.remotexy.com/viewtopic.php?id=879

6

Re: How can i change wifi credentials without flashing code?

Thanks a lot Guillaume for your usefull contributions to this topic.
JP

7

Re: How can i change wifi credentials without flashing code?

@ Guillaume

With your last contribution (see another topic  http://forum.remotexy.com/viewtopic.php?id=879), I thought I was able to adapt your examples to my project, but the situation is quite different and I wonder now if it's possible in my situation. I'm using a Nano board with a ESP8266 softserial connection, and a wifi link for a Cloud connection (hardserial connections used for monitor; AT commands between nano and ESP and Wifi credentials defined in the nano's sketch.ino)

My need is the same as the subject of this topic : how to configure wifi credentials without flashing updated code ?

I have then to adapt the module esp8266_cloud (=> for example esp8266_cloud_wifi_perso.h) to give the user the possibility to define his wifi credentials (and to define and include this module in the remotexy.h Library) but …. what is possible when using directly a ESP module, using the wifimanager Library seems a bit harder in my configuration.

Questions :
- do you think it's possible in my configuration ?
- if yes, could wifimanager be usefull in this case ? How to use it with AT commands (I Don't think it's possible but who knows …)?
- Or another solution ?

Thank you
PS: i'm not a C specialist and certainly not about wifi configuration

8

Re: How can i change wifi credentials without flashing code?

WifiManager cannot be used in your case, it's only for standalone ESP8266 not running the AT firmware.

I never used ESP8266 with AT commands but I'm almost sure it is possible to do what you want. Try this (UNTESTED):

Copy file module/esp8266_cloud.h, rename as remotexy_esp8266_serialcloud.h, open it and change the class name to CRemoteXY_ESP8266_SerialCloud, and change lines 26 to 32 :
From

#if defined(REMOTEXY_PORT__HARDSERIAL)
  CRemoteXY (const void * _conf, void * _var, const char * _accessPassword, HardwareSerial * _serial, long _serialSpeed, const char * _wifiSsid, const char * _wifiPassword, const char * _cloudServer, uint16_t _cloudPort, const char * _cloudToken) {
    initSerial (_serial, _serialSpeed);
#elif defined(REMOTEXY_PORT__SOFTSERIAL)
  CRemoteXY (const void * _conf, void * _var, const char * _accessPassword, uint8_t _serialRx, uint8_t _serialTx, long _serialSpeed, const char * _wifiSsid, const char * _wifiPassword, const char * _cloudServer, uint16_t _cloudPort, const char * _cloudToken) {
    initSerial (_serialRx, _serialTx, _serialSpeed);
#endif

To

#if defined(REMOTEXY_PORT__HARDSERIAL)
  void begin(const void * _conf, void * _var, const char * _accessPassword, HardwareSerial * _serial, long _serialSpeed, const char * _wifiSsid, const char * _wifiPassword, const char * _cloudServer, uint16_t _cloudPort, const char * _cloudToken) {
    initSerial (_serial, _serialSpeed);
#elif defined(REMOTEXY_PORT__SOFTSERIAL)
  void begin(const void * _conf, void * _var, const char * _accessPassword, uint8_t _serialRx, uint8_t _serialTx, long _serialSpeed, const char * _wifiSsid, const char * _wifiPassword, const char * _cloudServer, uint16_t _cloudPort, const char * _cloudToken) {
    initSerial (_serialRx, _serialTx, _serialSpeed);
#endif

Example sketch (UNTESTED):

#include <SoftwareSerial.h>
#define REMOTEXY_PORT__SOFTSERIAL
#include <remotexy_esp8266_serialcloud.h>
CRemoteXY_ESP8266_SerialCloud remotexy;

#pragma pack(push, 1)
const uint8_t PROGMEM remotexyConfig[] =
{
  255,0,0,0,0,16,0,8,13,1, // Header
  129,0,25,47,15,6,17,72,101,108,108,111,0 // Label "Hello"
};

struct
{
  uint8_t connect_flag;
} remotexyStruct;

#pragma pack(pop)



void setup() 
{
  remotexy.begin( remotexyConfig, &remotexyStruct, "", 2, 3, 9600, "SSID", "PASSWORD", "cloud.remotexy.com", 6376, "CLOUD_TOKEN" );
}

void loop()
{
  remotexy.handler();
}

When you want to change SSID just call remotexy.begin again. It could be vastly improved, it's just an untested example to give you an idea...

9

Re: How can i change wifi credentials without flashing code?

Tx a lot Guillaume. As I have to stay home with these Covid19 problems, i'll certainly have time to analyse and try your suggestions… I'll come back with the results

10

Re: How can i change wifi credentials without flashing code?

@ Guillaume (French is also possible if you prefer ... it's also my mother language :-))

I've followed your suggestions by copying / modifying the file module/esp8266_cloud.h as remotexy_esp8266_serialcloud.h.
- by modify the class name to CRemoteXY_ESP8266_SerialCloud (could you confirm this line ?: class CRemoteXY_ESP8266_SerialCloud : public CRemoteXY_AT {)
- by changing lines 26 to 32 as suggested

I've then created the suggested sketch (named : "Test_wifi_credentials"), but when I try to verify the compilation of the sketch I get this error message:

"C:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-4-b40a506/bin/xtensa-lx106-elf-g++" -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-IC:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\hardware\\esp8266\\2.6.3/tools/sdk/include" "-IC:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\hardware\\esp8266\\2.6.3/tools/sdk/lwip2/include" "-IC:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\hardware\\esp8266\\2.6.3/tools/sdk/libc/xtensa-lx106-elf/include" "-IC:\\Users\\MARECH~1\\AppData\\Local\\Temp\\arduino_build_630005/core" -c -w -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=gnu++11 -ffunction-sections -fdata-sections -fno-exceptions -w -x c++ -E -CC -DNONOSDK22x_190703=1 -DF_CPU=80000000L -DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DARDUINO=10812 -DARDUINO_ESP8266_GENERIC -DARDUINO_ARCH_ESP8266 "-DARDUINO_BOARD=\"ESP8266_GENERIC\"" -DLED_BUILTIN=2 -DFLASHMODE_DOUT -DESP8266 "-IC:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\hardware\\esp8266\\2.6.3\\cores\\esp8266" "-IC:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\hardware\\esp8266\\2.6.3\\variants\\generic" "-IC:\\Users\\MarechalJP\\Documents\\ArduinoData\\packages\\esp8266\\hardware\\esp8266\\2.6.3\\libraries\\SoftwareSerial\\src" "C:\\Users\\MARECH~1\\AppData\\Local\\Temp\\arduino_build_630005\\sketch\\Test_wifi_credentials.ino.cpp" -o nul
Alternatives for remotexy_esp8266_serialcloud.h: []Test_wifi_credentials:3:42: fatal error: remotexy_esp8266_serialcloud.h: No such file or directory


ResolveLibrary(remotexy_esp8266_serialcloud.h)
#include <remotexy_esp8266_serialcloud.h>

  -> candidates: []
                                          ^

compilation terminated.

Utilisation de la bibliothèque SoftwareSerial version 6.4.0 dans le dossier: C:\Users\MarechalJP\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.6.3\libraries\SoftwareSerial
exit status 1
remotexy_esp8266_serialcloud.h: No such file or directory


And I don't understand because the file (remotexy_esp8266_serialcloud.h) exists (as an .h files not a .txt one)  in the Remotexy directory within the Arduino's libraries directory

Do you have suggestions to be able to go further ... ?
Tx; Regards
JP

11 (edited by Guillaume 2020-03-31 11:15:22)

Re: How can i change wifi credentials without flashing code?

Essaie

#include <modules/remotexy_esp8266_serialcloud.h>

Mais le mieux c'est de mettre ce fichier ailleurs
https://arduino.stackexchange.com/a/63682

Je n'utilise pas l'IDE Arduino, j'utilise PlatformIO avec VS Code, c'est tellement plus simple...