Light Weight Credentials/WiFiManager for Teensy, SAM DUE, SAMD, STM32 & WiFiNINA

https://github.com/khoih-prog/WiFiManager_NINA_Lite

How To Install Using Arduino Library Manager

This library is a Light Weight Credentials / WiFi Manager for WiFiNINA modules/shields, specially designed to support AVR Mega, STM32, Teensy, SAM DUE, SAMD, etc. boards running WiFiNINA modules/shields, with smaller memory (64+K bytes)

You can also specify static AP and STA IP. Use much less memory compared to full-fledge WiFiManager. Credentials are saved in EEPROM, FlashStorage or DueFlashStorage.

You can use this library when your boards have more than 32K bytes of memory, for example Mega1280, Mega2560.

The web configuration portal, served from the WiFiNINA modules/shields is operating as an access point (AP) with configurable static IP address or use default IP Address of 192.168.4.1

Sample Code

/* Comment this out to disable prints and save space */
#define DEBUG_WIFI_WEBSERVER_PORT Serial
#define WIFININA_DEBUG_OUTPUT     Serial

#define WIFININA_DEBUG    true

#if    ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
      || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
      || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
      || defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) /*|| defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
      || defined(__SAMD51G19A__)*/  )
#if defined(WIFININA_USE_SAMD)
#undef WIFININA_USE_SAMD
#endif
#define WIFININA_USE_SAMD      true
#else
#error This code is intended to run only on the SAMD boards ! Please check your Tools->Board setting.
#endif

#if defined(WIFININA_USE_SAMD)

#if defined(ARDUINO_SAMD_ZERO)
#define BOARD_TYPE      "SAMD Zero"
#elif defined(ARDUINO_SAMD_MKR1000)
#define BOARD_TYPE      "SAMD MKR1000"
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
#define BOARD_TYPE      "SAMD MKRWIFI1010"
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define BOARD_TYPE      "SAMD NANO_33_IOT"
#elif defined(ARDUINO_SAMD_MKRFox1200)
#define BOARD_TYPE      "SAMD MKRFox1200"
#elif ( defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) )
#define BOARD_TYPE      "SAMD MKRWAN13X0"
#elif defined(ARDUINO_SAMD_MKRGSM1400)
#define BOARD_TYPE      "SAMD MKRGSM1400"
#elif defined(ARDUINO_SAMD_MKRNB1500)
#define BOARD_TYPE      "SAMD MKRNB1500"
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
#define BOARD_TYPE      "SAMD MKRVIDOR4000"
#elif defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
#define BOARD_TYPE      "SAMD ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS"
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
#define BOARD_TYPE      "SAMD ADAFRUIT_ITSYBITSY_M4_EXPRESS"
#elif ( defined(__SAMD21G18A__) || (__SAM3X8E__) || (__CPU_ARC__) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
      || defined(__SAMD51G19A__) )
#define BOARD_TYPE      "SAMD Board"
#else
#define BOARD_TYPE      "SAMD Unknown"
#endif
#endif

// Start location in EEPROM to store config data. Default 0
// Config data Size currently is 128 bytes)
#define EEPROM_START      0

#include <WiFiManager_NINA_Lite_SAMD.h>

#define MAX_BLYNK_SERVER_LEN      34
#define MAX_BLYNK_TOKEN_LEN       34

char Blynk_Server1 [MAX_BLYNK_SERVER_LEN]  = "";
char Blynk_Token1  [MAX_BLYNK_TOKEN_LEN]   = "";

char Blynk_Server2 [MAX_BLYNK_SERVER_LEN]  = "";
char Blynk_Token2  [MAX_BLYNK_TOKEN_LEN]   = "";

#define MAX_BLYNK_PORT_LEN        6
char Blynk_Port   [MAX_BLYNK_PORT_LEN]  = "";

#define MAX_MQTT_SERVER_LEN      34
char MQTT_Server  [MAX_MQTT_SERVER_LEN]   = "";

MenuItem myMenuItems [] =
{
  { "sv1", "Blynk Server1", Blynk_Server1,  MAX_BLYNK_SERVER_LEN },
  { "tk1", "Token1",        Blynk_Token1,   MAX_BLYNK_TOKEN_LEN },
  { "sv2", "Blynk Server2", Blynk_Server2,  MAX_BLYNK_SERVER_LEN },
  { "tk2", "Token2",        Blynk_Token2,   MAX_BLYNK_TOKEN_LEN },
  { "pt", "Port",           Blynk_Port,     MAX_BLYNK_PORT_LEN },
  { "mq", "MQTT Server",    MQTT_Server,    MAX_MQTT_SERVER_LEN },
};

uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem);  //MenuItemSize;

void heartBeatPrint(void)
{
  static int num = 1;

  if (WiFi.status() == WL_CONNECTED)
    Serial.print("H");        // H means connected to WiFi
  else
    Serial.print("F");        // F means not connected to WiFi

  if (num == 80)
  {
    Serial.println();
    num = 1;
  }
  else if (num++ % 10 == 0)
  {
    Serial.print(" ");
  }
}

void check_status()
{
  static unsigned long checkstatus_timeout = 0;

  //KH
#define HEARTBEAT_INTERVAL    600000L
  // Print hearbeat every HEARTBEAT_INTERVAL (600) seconds.
  if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
  {
    heartBeatPrint();
    checkstatus_timeout = millis() + HEARTBEAT_INTERVAL;
  }
}

WiFiManager_NINA_Lite* WiFiManager_NINA;

void setup()
{
  // Debug console
  Serial.begin(115200);
  while (!Serial);
  
  Serial.println("\nStart SAMD_WiFiNINA on " + String(BOARD_TYPE));


  WiFiManager_NINA = new WiFiManager_NINA_Lite();

  // Optional to change default AP IP(192.168.4.1) and channel(10)
  //WiFiManager_NINA->setConfigPortalIP(IPAddress(192, 168, 120, 1));
  //WiFiManager_NINA->setConfigPortalChannel(1);

  WiFiManager_NINA->begin();
}

void displayCredentials(void)
{
  Serial.println("Your stored Credentials :");

  for (int i = 0; i < NUM_MENU_ITEMS; i++)
  {
    Serial.println(String(myMenuItems[i].displayName) + " = " + myMenuItems[i].pdata);
  }
}

void loop()
{
  WiFiManager_NINA->run();

  static bool displayedCredentials = false;

  if (!displayedCredentials)
  {
    for (int i = 0; i < NUM_MENU_ITEMS; i++)
    {
      if (!strlen(myMenuItems[i].pdata))
      {
        break;
      }

      if ( i == (NUM_MENU_ITEMS - 1) )
      {
        displayedCredentials = true;
        displayCredentials();
      }
    }
  }

  check_status();
}

This is the terminal output when running SAMD_WiFiNINA example on example on Nano-33 IoT:

  1. Open Config Portal
Start SAMD_WiFiNINA on SAMD NANO_33_IOT
*NN: CrCCsum=6217,CrRCsum=825255525
*NN: CCSum=1983,RCSum=1752461166
*NN: InitEEPROM,sz=1080,Datasz=264
*NN: pdata=blank,len=34
*NN: pdata=blank,len=34
*NN: pdata=blank,len=34
*NN: pdata=blank,len=34
*NN: pdata=blank,len=6
*NN: pdata=blank,len=34
*NN: CrCCSum=3120
*NN: b:OpenPortal
*NN: SSID=WIFININA_E50AB22C,PW=MyWIFININA_E50AB22C
*NN: IP=192.168.4.1,CH=1
Your stored Credentials :
Blynk Server1 = blank
Token1 = blank
Blynk Server2 = blank
Token2 = blank
Port = blank
MQTT Server = blank
FFF
  1. Got valid Credential from Config Portal, then connected to WiFi
Start SAMD_WiFiNINA on SAMD NANO_33_IOT
*NN: CrCCSum=7558,CrRCSum=7558
*NN: CCSum=2104,RCSum=2104
*NN: Hdr=WIFININA,SSID=HueNet1,PW=****
*NN: i=0,id=sv1,data=blynk1.duckdns.org
*NN: i=1,id=tk1,data=your-token1
*NN: i=2,id=sv2,data=blynk2.duckdns.org
*NN: i=3,id=tk2,data=your-token2
*NN: i=4,id=pt,data=8080
*NN: i=5,id=mq,data=mqtt.duckdns.org
*NN: con2WF:start
*NN: con2WF:spentMsec=0
*NN: Con2:HueNet1
*NN: IP=192.168.2.139
*NN: WOK
*NN: con2WF:OK
*NN: IP=192.168.2.139
*NN: b:WOK
Your stored Credentials :
Blynk Server1 = blynk1.duckdns.org
Token1 = your-token1
Blynk Server2 = blynk2.duckdns.org
Token2 = your-token2
Port = 8080
MQTT Server = mqtt.duckdns.org
HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH
HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH

And the Config Portal screens:

1.Main Screen

  1. Input Credentials:

  1. After pressing Save button

Interesting library. I was looking for a Wifi Manager that I can use with MKR WiFi 1010. Does this support that board?

When I try to compile your posted sample code with MKR WiFi 1010 I get this compile error:

libraries\WiFiManager_NINA_Lite\src/WiFiManager_NINA_Lite_SAMD.h:45:10: fatal error: FlashAsEEPROM_SAMD.h: No such file or directory

 #include <FlashAsEEPROM_SAMD.h>                //https://github.com/khoih-prog/FlashStorage_SAMD

          ^~~~~~~~~~~~~~~~~~~~~~

compilation terminated.

Then messages appear after these error messages, which I think appears after I’ve opened Library Adminstration in Arduino IDE, which says (translated from my native language):
Invalid library in C:\Users<my path to libraries>\FlashStorage_SAMD-master: no ‘header’ files (.h) found in C:\Users<my path to libraries>\FlashStorage_SAMD-master
Could this be the reason for the error?

I’ve installed libraries WiFiManager_NINA_Lite and Blynk_WifiNINA_WM (and also FlashStorage separately).

Thanks.

You have to install this library

FlashStorage_SAMD

to compile and run.

Hey, I'm trying to get this to work on my Nano 33 IoT, but after inputting my info into the config portal I can never seem to get past the "Received data from Config Portal" section of the SAMD_WiFiNINA.ino example (using it exactly as it was, putting in info for two of the wifi networks I have too). I don't seem to be getting any error messages either. Another question that I had, but can't test yet until I figure out why I can't get past the above issue, does double reset functionality work for the Nano 33 IoT?

Hi,

Thanks for using the library. To answer your questions

I can never seem to get past the "Received data from Config Portal"

Just tested again and had no such a problem. Could you please retest. Turn on more debug options in defines.h to see what's happening.

And you also have to post the debug terminal output. Without it, no one can guess what's wrong.

#define WIFININA_DEBUG true

  1. DRD is working on Nano 33 IoT.

To see if it's working, turn on DRD debug in defines.h

#define DRD_GENERIC_DEBUG true

The terminal output when running Nano 33 IoT and SAMD_WiFiNINA

Start SAMD_WiFiNINA on SAMD NANO_33_IOT
Flag read = 0xd0d01234
doubleResetDetected
ClearFlag write = 0xd0d04321
*NN: b:OpenPortal
*NN: SSID=WIFININA_51F485,PW=MyWIFININA_51F485
*NN: IP=192.168.4.1,CH=10
WiFi-beginAP3: return1 = 7
WiFi-beginAP3: return2 = 7
F
Your stored Credentials :
Blynk Server1 = account.duckdns.org
Token1 = token1
Blynk Server2 = account.ddns.net
Token2 = token2
Port = 8080
MQTT Server = mqtt.duckdns.org

Hey, thanks for the reply! I sat down to work on the unit today, and it had no issue whatsoever, so it was probably just my computer being a bit wonky. DRD is working perfectly too! Thanks for the help again, absolutely loving the library.

Major Release v1.3.0

  1. Enable scan of WiFi networks for selection in Configuration Portal. Check PR for v1.3.0 - Enable scan of WiFi networks #10. Now you can select optional SCAN_WIFI_NETWORKS, MANUAL_SSID_INPUT_ALLOWED to be able to manually input SSID, not only from a scanned SSID lists and MAX_SSID_IN_LIST (from 2-15)
  2. Minor enhancement to not display garbage when data is invalid

Release v1.2.0

  1. Permit optionally inputting one set of WiFi SSID/PWD by using REQUIRE_ONE_SET_SSID_PW == true
  2. Enforce WiFi Password minimum length of 8 chars
  3. Enhance MultiWiFi connection logic

Now you can enable auto-scan of WiFi networks for selection in Configuration Portal