Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Library for configuring/auto(re)connecting W5100/W5200/W5500, ENC28J60 and built-in LAN8742A / LAN8720 Ethernet at runtime using Config Portal. New powerful-yet-simple-to-use feature to enable adding dynamic custom parameters from sketch and input using the same Config Portal. Config Portal will be auto-adjusted to match the number of dynamic pa…

License

Notifications You must be signed in to change notification settings

khoih-prog/Ethernet_Manager_STM32

Repository files navigation

Ethernet_Manager_STM32 Library

arduino-library-badge GitHub release GitHub contributions welcome GitHub issues

Donate to my libraries using BuyMeACoffee



Table of Contents



Why do we need this Ethernet_Manager_STM32 library

Features

  • This is the new library, adding to the current WiFiManager/Ethernet_Manager sets of libraries. It's designed to help you eliminate hardcoding your Credentials in STM32F/L/H/G/WB/MP1 boards using Ethernet shields (W5100, W5200, W5500, ENC28J60, LAN8720, built-in LAN8742A Ethernet). It's currently not supporting SSL. Will support soon.
  • You can update Credentials any time you need to change via Configure Portal. Data are saved in configurable locations in EEPROM.
  • DoubleDetectDetector feature to force Config Portal when double reset is detected within predetermined time, default 10s.
  • Configurable Config Portal Title to be either BoardName or default undistinguishable names.
  • Examples are redesigned to separate Credentials / Defines / Dynamic Params / Code so that you can change Credentials / Dynamic Params quickly for each device. Example MQTT_ThingStream_Ethernet_STM32 will demonstrate how to use the dynamic parameters, entered via Config Portal, to connect to ThingStream MQTT Server at mqtt.thingstream.io.

New recent features:

  • DoubleDetectDetector feature to force Config Portal when double reset is detected within predetermined time, default 10s.
  • Configurable Config Portal Title to be either BoardName or default undistinguishable names.
  • Examples are redesigned to separate Credentials / Defines / Dynamic Params / Code so that you can change Credentials / Dynamic Params quickly for each device

Currently supported Boards

  1. STM32 boards with built-in Ethernet LAN8742A such as :
  1. STM32F/L/H/G/WB/MP1 boards (with 32+K Flash) running W5x00 or ENC28J60 shields)
  • Nucleo-144
  • Nucleo-64
  • Discovery
  • Generic STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7 (with 64+K Flash): x8 and up
  • STM32L0, STM32L1, STM32L4
  • STM32G0, STM32G4
  • STM32H7
  • STM32WB
  • STM32MP1
  • LoRa boards
  • 3-D printer boards
  • Generic Flight Controllers
  • Midatronics boards
  1. STM32 boards using Ethernet LAN8720 such as :
  • Nucleo-144 (F429ZI, NUCLEO_F746NG, NUCLEO_F746ZG, NUCLEO_F756ZG)
  • Discovery (DISCO_F746NG)
  • STM32F4 boards (BLACK_F407VE, BLACK_F407VG, BLACK_F407ZE, BLACK_F407ZG, BLACK_F407VE_Mini, DIYMORE_F407VGT, FK407M1)

Currently Supported Ethernet shields/modules:

  1. Built-in Ethernet LAN8742A using STM32Ethernet library
  2. W5x00 using Ethernet_Generic library
  3. ENC28J60 using EthernetENC or UIPEthernet library
  4. LAN8720 using STM32Ethernet and LwIP libraries.

Not supported boards

These boards are not supported:

  • Some Nucleo-32 (small Flash/memory)
  • Eval (no Serial, just need to redefine in sketch, library and UIPEthernet)
  • Generic STM32F0 (small Flash/memory)
  • Generic STM32F1 (with 64-K Flash): C6
  • Generic STM32F3 : no HardwareSPI.h
  • Electronics Speed Controllers (small Flash/memory)


Prerequisites

  1. Arduino IDE 1.8.19+ for Arduino. GitHub release
  2. Arduino Core for STM32 v2.3.0+ for STM32 boards. GitHub release
  3. EthernetWebServer_STM32 library v1.5.0+. To install. check arduino-library-badge
  4. FlashStorage_STM32 library v1.2.0+ for STM32 boards other than STM32F1. To install. check arduino-library-badge
  5. FlashStorage_STM32F1 library v1.1.0+ for STM32F1 boards with 64KB+ Flash (STM32F1C8, STM32F1CB, etc.). To install. check arduino-library-badge
  6. Functional-Vlpp library v1.0.2+ to use server's lambda function. To install. check arduino-library-badge
  7. DoubleResetDetector_Generic library v1.8.1+. To install. check arduino-library-badge.
  8. For LAN8720 or built-in LAN8742A Ethernet:
  1. For W5x00 Ethernet:
  1. For ENC28J60 Ethernet:

Installation

The suggested way to install is to:

Use Arduino Library Manager

The best way is to use Arduino Library Manager. Search for Ethernet_Manager_STM32, then select / install the latest version. You can also use this link arduino-library-badge for more detailed instructions.

Manual Install

  1. Navigate to Ethernet_Manager_STM32 page.
  2. Download the latest release Ethernet_Manager_STM32-main.zip.
  3. Extract the zip file to Ethernet_Manager_STM32-main directory
  4. Copy the whole Ethernet_Manager_STM32-main folder to Arduino libraries' directory such as ~/Arduino/libraries/.

VS Code & PlatformIO:

  1. Install VS Code
  2. Install PlatformIO
  3. Install Ethernet_Manager_STM32 library by using Library Manager. Search for Ethernet_Manager_STM32 in Platform.io Author's Libraries
  4. Use included platformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at Project Configuration File


Packages' Patches

1. For STM32 boards to use LAN8720

To use LAN8720 on some STM32 boards

  • Nucleo-144 (F429ZI, NUCLEO_F746NG, NUCLEO_F746ZG, NUCLEO_F756ZG)
  • Discovery (DISCO_F746NG)
  • STM32F4 boards (BLACK_F407VE, BLACK_F407VG, BLACK_F407ZE, BLACK_F407ZG, BLACK_F407VE_Mini, DIYMORE_F407VGT, FK407M1)

you have to copy the files stm32f4xx_hal_conf_default.h and stm32f7xx_hal_conf_default.h into STM32 stm32 directory (~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system) to overwrite the old files.

Supposing the STM32 stm32 core version is 2.2.0. These files must be copied into the directory:

  • ~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F4xx/stm32f4xx_hal_conf_default.h for STM32F4.
  • ~/.arduino15/packages/STM32/hardware/stm32/2.2.0/system/STM32F7xx/stm32f7xx_hal_conf_default.h for Nucleo-144 STM32F7.

Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz, these files must be copied into the corresponding directory:

  • ~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F4xx/stm32f4xx_hal_conf_default.h
  • `~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F7xx/stm32f7xx_hal_conf_default.h

2. For STM32 boards to use Serial1

To use Serial1 on some STM32 boards without Serial1 definition (Nucleo-144 NUCLEO_F767ZI, Nucleo-64 NUCLEO_L053R8, etc.) boards, you have to copy the files STM32 variant.h into STM32 stm32 directory (~/.arduino15/packages/STM32/hardware/stm32/2.3.0). You have to modify the files corresponding to your boards, this is just an illustration how to do.

Supposing the STM32 stm32 core version is 2.3.0. These files must be copied into the directory:

  • ~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/STM32F7xx/F765Z(G-I)T_F767Z(G-I)T_F777ZIT/NUCLEO_F767ZI/variant.h for Nucleo-144 NUCLEO_F767ZI.
  • ~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/STM32L0xx/L052R(6-8)T_L053R(6-8)T_L063R8T/NUCLEO_L053R8/variant.h for Nucleo-64 NUCLEO_L053R8.

Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz, these files must be copied into the corresponding directory:

  • ~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/STM32F7xx/F765Z(G-I)T_F767Z(G-I)T_F777ZIT/NUCLEO_F767ZI/variant.h
  • ~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/STM32L0xx/L052R(6-8)T_L053R(6-8)T_L063R8T/NUCLEO_L053R8/variant.h

Libraries' Patches

1. For application requiring 2K+ HTML page

If your application requires 2K+ HTML page, the current Ethernet library must be modified if you are using W5200/W5500 Ethernet shields. W5100 is not supported for 2K+ buffer. If you use boards requiring different CS/SS pin for W5x00 Ethernet shield, for example ESP32, ESP8266, nRF52, etc., you also have to modify the following libraries to be able to specify the CS/SS pin correctly.

2. For Ethernet library

To fix Ethernet library, just copy these following files into the Ethernet library directory to overwrite the old files:

3. For EthernetLarge library

To fix EthernetLarge library, just copy these following files into the EthernetLarge library directory to overwrite the old files:

4. For Ethernet2 library

To fix Ethernet2 library, just copy these following files into the Ethernet2 library directory to overwrite the old files:

To add UDP Multicast support, necessary for the UPnP_Generic library:

5. For Ethernet3 library

  1. To fix Ethernet3 library, just copy these following files into the Ethernet3 library directory to overwrite the old files:

6. For UIPEthernet library

To be able to compile and run on nRF52 boards with ENC28J60 using UIPEthernet library, you have to copy these following files into the UIPEthernet utility directory to overwrite the old files:



HOWTO Fix Multiple Definitions Linker Error

The current library implementation, using xyz-Impl.h instead of standard xyz.cpp, possibly creates certain Multiple Definitions Linker error in certain use cases.

You can use

#include <Ethernet_Manager_STM32.hpp>               //https://github.com/khoih-prog/Ethernet_Manager_STM32

in many files. But be sure to use the following #include <NTPClient_Generic.h> in just 1 .h, .cpp or .ino file, which must not be included in any other file, to avoid Multiple Definitions Linker Error

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include <Ethernet_Manager_STM32.h>                //https://github.com/khoih-prog/Ethernet_Manager_STM32

Check multiFileProject for a demo how to avoid multiple-definitions linker error for multiple-file project



Configuration Notes

1. How to select which built-in Ethernet or shield to use

Select one and only one Ethernet library to use as follows:

  • Standard W5x00 Ethernet_Generic Library

Standard W5x00 using Ethernet_Generic library is used by default, in the sketch, just be sure to comment out or leave these #defines to be false :

// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  false
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      false
#define USE_UIP_ETHERNET      false
#define USE_CUSTOM_ETHERNET   false

To use built-in LAN8742A

// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  true
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      false
#define USE_UIP_ETHERNET      false
#define USE_CUSTOM_ETHERNET   false

To use LAN8720

#define USING_LAN8720         true

// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  true
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      false
#define USE_UIP_ETHERNET      false
#define USE_CUSTOM_ETHERNET   false

To use W5x00 Ethernet, for example using Ethernet_Generic library

// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  true
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      false
#define USE_UIP_ETHERNET      false
#define USE_CUSTOM_ETHERNET   false

To use ENC28J60 Ethernet, using EthernetENC library (NEW and Better)

// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  false
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      true
#define USE_UIP_ETHERNET      false
#define USE_CUSTOM_ETHERNET   false

To use ENC28J60 Ethernet, using UIPEthernet library

// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  false
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      false
#define USE_UIP_ETHERNET      true
#define USE_CUSTOM_ETHERNET   false
  • To use another Ethernet library For example, Ethernet_XYZ library uses Ethernet_XYZ.h
// Only one if the following to be true
#define USE_BUILTIN_ETHERNET  false
#define USE_ETHERNET_GENERIC  false
#define USE_ETHERNET_ENC      false
#define USE_UIP_ETHERNET      false
#define USE_CUSTOM_ETHERNET   true

....

#elif USE_CUSTOM_ETHERNET
  //#include "Ethernet_XYZ.h"
  #include "EthernetLarge.h"
  #warning Using Custom Ethernet library. You must include a library and initialize.
  #define SHIELD_TYPE           "Custom Ethernet & Ethernet_XYZ Library"
#else
  #define USE_ETHERNET_GENERIC          true
  #include "Ethernet_Generic.h"
  #warning Using Ethernet_Generic lib
  #define SHIELD_TYPE           "W5x00 & Ethernet_Generic Library"
#endif  
...

#include <Ethernet_Manager_STM32.h>

Important:

  • The Ethernet_Shield_W5200, EtherCard, EtherSia libraries are not supported. Don't use unless you know how to modify those libraries.
  • Requests to support for any future custom Ethernet library will be ignored. Use at your own risk.

2. How to select another CS/SS pin to use

The default CS/SS pin is 10 for all boards.

If the default pin is not correct, the easiest way is to change is to select the CS/SS pin (e.g. 22) to use as follows:

// To override the default CS/SS pin. Don't use unless you know exactly which pin to use
#define USE_THIS_SS_PIN   22

3. How to increase W5x00 TX/RX buffer

  • For Ethernet_Generic library only, simply use as follows to have large buffer similar to EthernetLarge library
#define ETHERNET_LARGE_BUFFERS
  • For Ethernet3 library only, use as follows
  // Use  MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer
  #ifndef ETHERNET3_MAX_SOCK_NUM
    #define ETHERNET3_MAX_SOCK_NUM      4
  #endif
  
  Ethernet.setCsPin (USE_THIS_SS_PIN);
  Ethernet.init (ETHERNET3_MAX_SOCK_NUM);

How to use default Credentials and have them pre-loaded onto Config Portal

See this example and modify as necessary

  1. To load Default Credentials
bool LOAD_DEFAULT_CONFIG_DATA = true;
  1. To use system default to load "blank" when there is no valid Credentials
bool LOAD_DEFAULT_CONFIG_DATA = false;
  1. Example of Default Credentials
/// Start Default Config Data //////////////////

/*
typedef struct Configuration
{
  char header         [16];
  char static_IP      [16];
  char board_name     [24];
  int  checkSum;
} Ethernet_Configuration;
*/

#define TO_LOAD_DEFAULT_CONFIG_DATA      true

#if TO_LOAD_DEFAULT_CONFIG_DATA

bool LOAD_DEFAULT_CONFIG_DATA = false;

Ethernet_Configuration defaultConfig =
{
  //char header[16], dummy, not used
#if USE_SSL
  "Eth_SSL",
#else
  "Eth_NonSSL",
#endif

  // char static_IP      [16];
  //"192.168.2.230",
  // Use dynamic DHCP IP
  "",
  //char board_name     [24];
  "STM32-Ethernet",
  // terminate the list
  //int  checkSum, dummy, not used
  0
  /////////// End Default Config Data /////////////
};

#else

bool LOAD_DEFAULT_CONFIG_DATA = false;

Ethernet_Configuration defaultConfig;

#endif    // TO_LOAD_DEFAULT_CONFIG_DATA

/////////// End Default Config Data /////////////


How to use

1. Basic usage

  • Include in your sketch
// Must be before #include <Ethernet_Manager.h>
#include <Ethernet_Manager.h>

Ethernet_Manager ethernet_manager;

2. Add custom parameters

  • To add custom parameters, just add
#ifndef dynamicParams_h
#define dynamicParams_h

#include "defines.h"

// USE_DYNAMIC_PARAMETERS defined in defined.h

/////////////// Start dynamic Credentials ///////////////

/**************************************
  #define MAX_ID_LEN                5
  #define MAX_DISPLAY_NAME_LEN      16

  typedef struct
  {
  char id             [MAX_ID_LEN + 1];
  char displayName    [MAX_DISPLAY_NAME_LEN + 1];
  char *pdata;
  uint8_t maxlen;
  } MenuItem;
**************************************/

#if USE_DYNAMIC_PARAMETERS

  #define MAX_MQTT_SERVER_LEN      34
  char MQTT_Server  [MAX_MQTT_SERVER_LEN + 1]   = "default-mqtt-server";
  
  #define MAX_MQTT_PORT_LEN        6
  char MQTT_Port   [MAX_MQTT_PORT_LEN + 1]  = "1883";
  
  #define MAX_MQTT_USERNAME_LEN      34
  char MQTT_UserName  [MAX_MQTT_USERNAME_LEN + 1]   = "default-mqtt-username";
  
  #define MAX_MQTT_PW_LEN        34
  char MQTT_PW   [MAX_MQTT_PW_LEN + 1]  = "default-mqtt-password";
  
  #define MAX_MQTT_SUBS_TOPIC_LEN      34
  char MQTT_SubsTopic  [MAX_MQTT_SUBS_TOPIC_LEN + 1]   = "default-mqtt-SubTopic";
  
  #define MAX_MQTT_PUB_TOPIC_LEN       34
  char MQTT_PubTopic   [MAX_MQTT_PUB_TOPIC_LEN + 1]  = "default-mqtt-PubTopic";
  
  MenuItem myMenuItems [] =
  {
    { "mqtt", "MQTT Server",      MQTT_Server,      MAX_MQTT_SERVER_LEN },
    { "mqpt", "Port",             MQTT_Port,        MAX_MQTT_PORT_LEN   },
    { "user", "MQTT UserName",    MQTT_UserName,    MAX_MQTT_USERNAME_LEN },
    { "mqpw", "MQTT PWD",         MQTT_PW,          MAX_MQTT_PW_LEN },
    { "subs", "Subs Topics",      MQTT_SubsTopic,   MAX_MQTT_SUBS_TOPIC_LEN },
    { "pubs", "Pubs Topics",      MQTT_PubTopic,    MAX_MQTT_PUB_TOPIC_LEN },
  };
  
  uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem);  //MenuItemSize;

#else

  MenuItem myMenuItems [] = {};
  
  uint16_t NUM_MENU_ITEMS = 0;
#endif

/////// // End dynamic Credentials ///////////

#endif      //dynamicParams_h

3. Not using custom parameters

  • If you don't need to add dynamic parameters, use the following in sketch
#define USE_DYNAMIC_PARAMETERS      false

4. To open Config Portal

  • When you want to open a config portal, just add
ethernet_manager.begin();

5. To use custom HTML Style

const char NewCustomsStyle[] /*PROGMEM*/ = "<style>div,input{padding:5px;font-size:1em;}input{width:95%;}body{text-align: center;}\
button{background-color:blue;color:white;line-height:2.4rem;font-size:1.2rem;width:100%;}fieldset{border-radius:0.3rem;margin:0px;}</style>";

...

ethernet_manager.setCustomsStyle(NewCustomsStyle);

6. To use custom Head Elements

ethernet_manager.setCustomsHeadElement("<style>html{filter: invert(10%);}</style>");

7. To use CORS Header

ethernet_manager.setCORSHeader("Your Access-Control-Allow-Origin");


Important Notes for using Dynamic Parameters' ids

  1. These ids (such as "mqtt" in example) must be unique.

Please be noted that the following reserved names are already used in library:

"ip"    for Static IP Address
"nm"    for Board Name


HOWTO use STM32F4 with LAN8720

1. Wiring

This is the Wiring for STM32F4 (BLACK_F407VE, etc.) using LAN8720

LAN8720 PHY <---> STM32F4
TX1 <---> PB_13
TX_EN <---> PB_11
TX0 <---> PB_12
RX0 <---> PC_4
RX1 <---> PC_5
nINT/RETCLK <---> PA_1
CRS <---> PA_7
MDIO <---> PA_2
MDC <---> PC_1
GND <---> GND
VCC <---> +3.3V

2. HOWTO program using STLink V-2 or V-3

Connect as follows. To program, use STM32CubeProgrammer or Arduino IDE with

  • U(S)ART Support: "Enabled (generic Serial)"
  • Upload Method : "STM32CubeProgrammer (SWD)"
STLink <---> STM32F4
SWCLK <---> SWCLK
SWDIO <---> SWDIO
RST <---> NRST
GND <---> GND
5v <---> 5V


3. HOWTO use Serial Port for Debugging

Connect FDTI (USB to Serial) as follows:

FDTI <---> STM32F4
RX <---> TX=PA_9
TX <---> RX=PA_10
GND <---> GND


Examples

  1. AM2315_Ethernet_STM32
  2. DHT11_Ethernet_STM32
  3. Ethernet_STM32
  4. MQTT_ThingStream_Ethernet_STM32
  5. AM2315_Ethernet_STM32_LAN8720
  6. DHT11_Ethernet_STM32_LAN8720
  7. Ethernet_STM32_LAN8720
  8. MQTT_ThingStream_Ethernet_STM32_LAN8720
  9. multiFileProject New


So, how it works?

If no valid config data are stored in EEPROM, it will switch to Configuration Mode. Connect to access point at the IP address displayed on Terminal or Router's DHCP server as in the following picture:

After you connected to, for example, 192.168.2.86, the Browser will display the following picture:

Enter your credentials (Blynk Servers/Tokens and Port). If you prefer static IP, input it (for example 192.168.2.222) in the corresponding field. Otherwise, just leave it blank or nothing to use auto IP assigned by DHCP server.

Then click Save. After the board auto-restarted, you will see if it's connected to your Blynk server successfully as in the following picture:

This Ethernet_Manager_STM32.run() is not a blocking call, so you can use it for critical functions requiring in loop().

In operation, if Ethernet or connection is lost, Ethernet_Manager_STM32.run() will try reconnecting automatically. Therefore, Ethernet_Manager_STM32.run() must be called in the loop() function.

void loop()
{
  Ethernet_Manager_STM32.run();
  ...
}


#include "defines.h"
#include "Credentials.h"
#include "dynamicParams.h"
///////////// Start MQTT ThingStream ///////////////
#include <PubSubClient.h>
// GOT FROM ThingsStream!
#if 0
const char *MQTT_SERVER = "mqtt.thingstream.io";
const char *MQTT_USER = "MQTT_USER";
const char *MQTT_PASS = "MQTT_PASS";
const char *MQTT_CLIENT_ID = "MQTT_CLIENT_ID";
const int MQTT_PORT = 1883; //if you use SSL //1883 no SSL
#endif
const char *MQTT_PREFIX_TOPIC = "esp32-sniffer/";
const char *MQTT_ANNOUNCE_TOPIC = "/status";
const char *MQTT_CONTROL_TOPIC = "/control";
const char *MQTT_BLE_TOPIC = "/ble";
String topic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC;
String subTopic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC;
//////////// End MQTT ThingStream ///////////////
Ethernet_Manager ethernet_manager;
IPAddress localEthernetIP;
///////////// Start MQTT ThingStream ///////////////
String data = "Hello from MQTT_ThingStream on " + String(BOARD_NAME) + " with " + String(SHIELD_TYPE);
const char *pubData = data.c_str();
void mqtt_receive_callback(char* topic, byte* payload, unsigned int length);
unsigned long lastMsg = 0;
// Initialize the SSL client library
// Arguments: EthernetClient, our trust anchors
EthernetClient ethClient;
//PubSubClient client(MQTT_SERVER, atoi(MQTT_PORT), mqtt_receive_callback, ethClient);
PubSubClient* client = NULL;
/*
Called whenever a payload is received from a subscribed MQTT topic
*/
void mqtt_receive_callback(char* topic, byte* payload, unsigned int length)
{
Serial.print(F("\nMQTT Message receive ["));
Serial.print(topic);
Serial.print(F("] "));
for (unsigned int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect()
{
// Loop until we're reconnected
while (!client->connected())
{
Serial.print(F("Attempting MQTT connection to "));
Serial.println(MQTT_SERVER);
// Attempt to connect
int connect_status = client->connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, topic.c_str(), 2, false, "");
if (connect_status)
{
Serial.println(F("...connected"));
client->publish(topic.c_str(), pubData);
Serial.println(F("Published connection message successfully!"));
Serial.print(F("Subcribed to: "));
Serial.println(subTopic);
// ... and resubscribe
client->subscribe(subTopic.c_str());
// for loopback testing
client->subscribe(topic.c_str());
}
else
{
Serial.print(F("failed, rc="));
Serial.print(client->state());
Serial.println(F(" try again in 5 seconds"));
// Wait 5 seconds before retrying
delay(5000);
}
}
}
///////////// End MQTT ThingStream ///////////////
// Use to detect W5100 shield. The linkStatus() is not working with W5100
// in Ethernet and EthernetLarge libraries
bool isW5500 = true;
void heartBeatPrint()
{
static int num = 1;
static int linkStatus = 0;
localEthernetIP = Ethernet.localIP();
#if (USE_ETHERNET_GENERIC)
// To modify Ethernet2 library
linkStatus = Ethernet.link();
ETM_LOGINFO3(F("localEthernetIP = "), localEthernetIP, F(", linkStatus = "), (linkStatus == 1) ? F("LinkON") : F("LinkOFF") );
if ( ( linkStatus == 1 ) && ((uint32_t) localEthernetIP != 0) )
#else
// The linkStatus() is not working with W5100. Just using IP != 0.0.0.0
// Better to use ping for W5100
linkStatus = (int) Ethernet.linkStatus();
ETM_LOGINFO3(F("localEthernetIP = "), localEthernetIP, F(", linkStatus = "), (linkStatus == LinkON) ? F("LinkON") : F("LinkOFF") );
if ( ( (linkStatus == LinkON) || !isW5500 ) && ((uint32_t) localEthernetIP != 0) )
#endif
{
Serial.print(F("H"));
}
else
Serial.print(F("F"));
if (num == 80)
{
Serial.println();
num = 1;
}
else if (num++ % 10 == 0)
{
Serial.print(F(" "));
}
}
void check_status()
{
#define STATUS_CHECK_INTERVAL 10000L
static unsigned long checkstatus_timeout = STATUS_CHECK_INTERVAL;
// Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change.
if ((millis() > checkstatus_timeout))
{
heartBeatPrint();
checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL;
}
}
void initEthernet()
{
#if ( defined(USE_BUILTIN_ETHERNET) && USE_BUILTIN_ETHERNET )
ETM_LOGWARN(F("======== USE_BUILTIN_ETHERNET ========"));
#elif ( defined(USE_UIP_ETHERNET) && USE_UIP_ETHERNET )
ETM_LOGWARN(F("======== USE_UIP_ETHERNET ========"));
#elif USE_ETHERNET_GENERIC
ETM_LOGWARN(F("=========== USE_ETHERNET_GENERIC ==========="));
#elif USE_ETHERNET_ENC
ETM_LOGWARN(F("=========== USE_ETHERNET_ENC ==========="));
#else
ETM_LOGWARN(F("========================="));
#endif
#if !(USE_BUILTIN_ETHERNET )
ETM_LOGWARN(F("Default SPI pinout:"));
ETM_LOGWARN1(F("MOSI:"), MOSI);
ETM_LOGWARN1(F("MISO:"), MISO);
ETM_LOGWARN1(F("SCK:"), SCK);
ETM_LOGWARN1(F("SS:"), SS);
ETM_LOGWARN(F("========================="));
// unknown board, do nothing, use default SS = 10
#ifndef USE_THIS_SS_PIN
#define USE_THIS_SS_PIN 10 // For other boards
#endif
#if defined(BOARD_NAME)
ETM_LOGWARN3(F("Board :"), BOARD_NAME, F(", setCsPin:"), USE_THIS_SS_PIN);
#else
ETM_LOGWARN1(F("Unknown board setCsPin:"), USE_THIS_SS_PIN);
#endif
#endif
#if !(USE_BUILTIN_ETHERNET || USE_UIP_ETHERNET)
#if (defined(ETHERNET_WITH_SD_CARD) && ETHERNET_WITH_SD_CARD)
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
#endif
// For other boards, to change if necessary
#if ( USE_ETHERNET_GENERIC || USE_ETHERNET_ENC )
// Must use library patch for Ethernet, Ethernet2, EthernetLarge libraries
Ethernet.init (USE_THIS_SS_PIN);
#elif USE_CUSTOM_ETHERNET
// You have to add initialization for your Custom Ethernet here
// This is just an example to setCSPin to USE_THIS_SS_PIN, and can be not correct and enough
Ethernet.init(USE_THIS_SS_PIN);
#endif // ( USE_ETHERNET_GENERIC || USE_ETHERNET_ENC )
#endif
#if !(USE_BUILTIN_ETHERNET )
// Just info to know how to connect correctly
#if defined(CUR_PIN_MISO)
ETM_LOGWARN(F("Currently Used SPI pinout:"));
ETM_LOGWARN1(F("MOSI:"), CUR_PIN_MOSI);
ETM_LOGWARN1(F("MISO:"), CUR_PIN_MISO);
ETM_LOGWARN1(F("SCK:"), CUR_PIN_SCK);
ETM_LOGWARN1(F("SS:"), CUR_PIN_SS);
#else
ETM_LOGWARN(F("Currently Used SPI pinout:"));
ETM_LOGWARN1(F("MOSI:"), MOSI);
ETM_LOGWARN1(F("MISO:"), MISO);
ETM_LOGWARN1(F("SCK:"), SCK);
ETM_LOGWARN1(F("SS:"), SS);
#endif
ETM_LOGWARN(F("========================="));
#endif
}
#if USING_CUSTOMS_STYLE
const char NewCustomsStyle[] /*PROGMEM*/ = "<style>div,input{padding:5px;font-size:1em;}input{width:95%;}body{text-align: center;}\
button{background-color:blue;color:white;line-height:2.4rem;font-size:1.2rem;width:100%;}fieldset{border-radius:0.3rem;margin:0px;}</style>";
#endif
void setup()
{
// Debug console
Serial.begin(115200);
while (!Serial);
Serial.print(F("\nStart MQTT_ThingStream_Ethernet_STM32 on ")); Serial.println(BOARD_NAME);
Serial.print(F("Ethernet Shield type : ")); Serial.println(SHIELD_TYPE);
Serial.println(ETHERNET_MANAGER_STM32_VERSION);
Serial.println(DOUBLERESETDETECTOR_GENERIC_VERSION);
initEthernet();
//////////////////////////////////////////////
#if USING_CUSTOMS_STYLE
ethernet_manager.setCustomsStyle(NewCustomsStyle);
#endif
#if USING_CUSTOMS_HEAD_ELEMENT
ethernet_manager.setCustomsHeadElement("<style>html{filter: invert(10%);}</style>");
#endif
#if USING_CORS_FEATURE
ethernet_manager.setCORSHeader("Your Access-Control-Allow-Origin");
#endif
ethernet_manager.begin();
//////////////////////////////////////////////
localEthernetIP = Ethernet.localIP();
if ( (uint32_t) localEthernetIP != 0 )
{
Serial.print(F("Connected! IP address: "));
Serial.println(localEthernetIP);
}
else
{
Serial.println(F("Ethernet not Connected! Please check."));
}
// Detect W5100 only in Ethernet and EthernetLarge libraries
#if (USE_ETHERNET_GENERIC)
isW5500 = (Ethernet.hardwareStatus() == EthernetW5500);
Serial.print(F("Ethernet type is "));
Serial.println(isW5500 ? F("W5500") : F("W5100"));
#endif
Serial.println(F("***************************************"));
Serial.println(topic);
Serial.println(F("***************************************"));
}
#if (USE_DYNAMIC_PARAMETERS)
void displayCredentials()
{
Serial.println(F("\nYour stored Credentials :"));
for (uint16_t i = 0; i < NUM_MENU_ITEMS; i++)
{
Serial.print(myMenuItems[i].displayName);
Serial.print(F(" = "));
Serial.println(myMenuItems[i].pdata);
}
}
void displayCredentialsOnce()
{
static bool displayedCredentials = false;
if (!displayedCredentials)
{
for (uint16_t i = 0; i < NUM_MENU_ITEMS; i++)
{
if (!strlen(myMenuItems[i].pdata))
{
break;
}
if ( i == (NUM_MENU_ITEMS - 1) )
{
displayedCredentials = true;
displayCredentials();
}
}
}
}
#endif
#define MQTT_PUBLISH_INTERVAL_MS 20000L
void loop()
{
static bool inConfigMode = true;
static unsigned long currentMillis;
inConfigMode = ethernet_manager.run();
if (!inConfigMode)
{
#if (USE_DYNAMIC_PARAMETERS)
displayCredentialsOnce();
#endif
if (!client)
{
client = new PubSubClient(MQTT_SERVER, atoi(MQTT_PORT), mqtt_receive_callback, ethClient);
// Note - the default maximum packet size is 256 bytes. If the
// combined length of clientId, username and password exceed this use the
// following to increase the buffer size:
//client->setBufferSize(256);
}
if (!client->connected())
{
reconnect();
}
// Sending Data
currentMillis = millis();
if (currentMillis - lastMsg > MQTT_PUBLISH_INTERVAL_MS)
{
lastMsg = currentMillis;
if (!client->publish(topic.c_str(), pubData))
{
Serial.println(F("Message failed to send."));
}
Serial.print(F("\nMQTT Message Send : "));
Serial.print(topic);
Serial.print(F(" => "));
Serial.println(data);
}
client->loop();
check_status();
}
}

2. File defines.h

#ifndef defines_h
#define defines_h
#if ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
defined(STM32WB) || defined(STM32MP1) )
#if defined(ETHERNET_USE_STM32)
#undef ETHERNET_USE_STM32
#endif
#define ETHERNET_USE_STM32 true
#define USE_DYNAMIC_PARAMETERS true
#else
#error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting.
#endif
// To suppress boolean warnings of old libraries
#define boolean bool
/* Comment this out to disable prints and save space */
#define ETHERNET_MANAGER_STM32_DEBUG_PORT Serial
// Debug Level from 0 to 4
#define _ETHERNET_WEBSERVER_LOGLEVEL_ 0
#define _ETHERNET_MANAGER_STM32_LOGLEVEL_ 2
#define DRD_GENERIC_DEBUG true
// To override the default CS/SS pin. Don't use unless you know exactly which pin to use
// You can define here or customize for each board at same place with BOARD_TYPE
//#define USE_THIS_SS_PIN 22 //21 //5 //4 //2 //15
// Default pin 10 to SS/CS. To change according to your board, if necessary
#define USE_THIS_SS_PIN 10
// Only one if the following to be true
#define USE_BUILTIN_ETHERNET true
#define USE_ETHERNET_GENERIC false
#define USE_ETHERNET_ENC false
#define USE_UIP_ETHERNET false
#define USE_CUSTOM_ETHERNET false
#if defined(STM32F0)
#warning STM32F0 board selected
#define BOARD_TYPE "STM32F0"
#elif defined(STM32F1)
#warning STM32F1 board selected
#define BOARD_TYPE "STM32F1"
#elif defined(STM32F2)
#warning STM32F2 board selected
#define BOARD_TYPE "STM32F2"
#elif defined(STM32F3)
#warning STM32F3 board selected
#define BOARD_TYPE "STM32F3"
#elif defined(STM32F4)
#warning STM32F4 board selected
#define BOARD_TYPE "STM32F4"
#elif defined(STM32F7)
#warning STM32F7 board selected
#define BOARD_TYPE "STM32F7"
#elif defined(STM32L0)
#warning STM32L0 board selected
#define BOARD_TYPE "STM32L0"
#elif defined(STM32L1)
#warning STM32L1 board selected
#define BOARD_TYPE "STM32L1"
#elif defined(STM32L4)
#warning STM32L4 board selected
#define BOARD_TYPE "STM32L4"
#elif defined(STM32H7)
#warning STM32H7 board selected
#define BOARD_TYPE "STM32H7"
#elif defined(STM32G0)
#warning STM32G0 board selected
#define BOARD_TYPE "STM32G0"
#elif defined(STM32G4)
#warning STM32G4 board selected
#define BOARD_TYPE "STM32G4"
#elif defined(STM32WB)
#warning STM32WB board selected
#define BOARD_TYPE "STM32WB"
#elif defined(STM32MP1)
#warning STM32MP1 board selected
#define BOARD_TYPE "STM32MP1"
#else
#warning STM32 unknown board selected
#define BOARD_TYPE "STM32 Unknown"
#endif
#ifndef BOARD_NAME
#define BOARD_NAME BOARD_TYPE
#endif
//////////////////////////////////////////
#define EEPROM_START 0
/////////////////////////////////////////////
// Add customs headers from v1.2.0
#define USING_CUSTOMS_STYLE true
#define USING_CUSTOMS_HEAD_ELEMENT true
#define USING_CORS_FEATURE true
/////////////////////////////////////////////
// Config Timeout 120s (default 60s)
#define CONFIG_TIMEOUT 120000L
#define USE_DYNAMIC_PARAMETERS true
//////////////////////////////////////////
#include <Ethernet_Manager_STM32.h>
#ifndef SHIELD_TYPE
#define SHIELD_TYPE "Unknown Ethernet shield/library"
#endif
#if USE_ETHERNET_GENERIC
// Change to true if using old Ethernet card with built-in SD
#define ETHERNET_WITH_SD_CARD false
#endif
#if (defined(ETHERNET_WITH_SD_CARD) && ETHERNET_WITH_SD_CARD)
#define W5100_CS 10
#define SDCARD_CS 4
#endif
#define ETHERNET_HOST_NAME "STM32-Ethernet"
#endif //defines_h

#ifndef Credentials_h
#define Credentials_h
#include "defines.h"
/// Start Default Config Data //////////////////
/*
typedef struct Configuration
{
char header [16];
char static_IP [16];
char board_name [24];
int checkSum;
} Ethernet_Configuration;
*/
#define TO_LOAD_DEFAULT_CONFIG_DATA true
#if TO_LOAD_DEFAULT_CONFIG_DATA
bool LOAD_DEFAULT_CONFIG_DATA = false;
Ethernet_Configuration defaultConfig =
{
//char header[16], dummy, not used
#if USE_SSL
"Eth_SSL",
#else
"Eth_NonSSL",
#endif
// char static_IP [16];
//"192.168.2.230",
// Use dynamic DHCP IP
"",
//char board_name [24];
"STM32-Ethernet",
// terminate the list
//int checkSum, dummy, not used
0
/////////// End Default Config Data /////////////
};
#else
bool LOAD_DEFAULT_CONFIG_DATA = false;
Ethernet_Configuration defaultConfig;
#endif // TO_LOAD_DEFAULT_CONFIG_DATA
/////////// End Default Config Data /////////////
#endif //Credentials_h

#ifndef dynamicParams_h
#define dynamicParams_h
#include "defines.h"
// USE_DYNAMIC_PARAMETERS defined in defined.h
/////////////// Start dynamic Credentials ///////////////
//Defined in <Ethernet_Manager_STM32_Impl.h>
/**************************************
#define MAX_ID_LEN 5
#define MAX_DISPLAY_NAME_LEN 16
typedef struct
{
char id [MAX_ID_LEN + 1];
char displayName [MAX_DISPLAY_NAME_LEN + 1];
char *pdata;
uint8_t maxlen;
} MenuItem;
**************************************/
#if USE_DYNAMIC_PARAMETERS
#define MAX_MQTT_SERVER_LEN 48
char MQTT_SERVER [MAX_MQTT_SERVER_LEN + 1] = "default-mqtt-server";
#define MAX_MQTT_PORT_LEN 6
char MQTT_PORT [MAX_MQTT_PORT_LEN + 1] = "1883";
#define MAX_MQTT_USERNAME_LEN 34
char MQTT_USER [MAX_MQTT_USERNAME_LEN + 1] = "default-mqtt-username";
#define MAX_MQTT_PW_LEN 48
char MQTT_PASS [MAX_MQTT_PW_LEN + 1] = "default-mqtt-password";
#define MAX_MQTT_CLIENT_ID 48
char MQTT_CLIENT_ID [MAX_MQTT_CLIENT_ID + 1] = "default-mqtt-clientID";
MenuItem myMenuItems [] =
{
{ "mqtt", "MQTT Server", MQTT_SERVER, MAX_MQTT_SERVER_LEN },
{ "mqpt", "Port", MQTT_PORT, MAX_MQTT_PORT_LEN },
{ "user", "MQTT UserName", MQTT_USER, MAX_MQTT_USERNAME_LEN },
{ "mqpw", "MQTT PWD", MQTT_PASS, MAX_MQTT_PW_LEN },
{ "clid", "Client ID", MQTT_CLIENT_ID, MAX_MQTT_CLIENT_ID },
};
uint16_t NUM_MENU_ITEMS = sizeof(myMenuItems) / sizeof(MenuItem); //MenuItemSize;
#else
MenuItem myMenuItems [] = {};
uint16_t NUM_MENU_ITEMS = 0;
#endif
/////// // End dynamic Credentials ///////////
#endif //dynamicParams_h



Debug Terminal Output Samples

1. Ethernet_STM32 on STM32F7 NUCLEO_F767ZI with LAN8742A Ethernet using STM32Ethernet Library

This is the terminal output of an STM32F7 Nucleo-144 NUCLEO_F767ZI board with LAN8742A Ethernet & STM32Ethernet Library, running Ethernet_STM32 example.

1.1. Normal run

Start Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : LAN8742A Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] ======== USE_BUILTIN_ETHERNET ========

(Emulated-)EEPROM size = 16384, start = 0
[ETM] ======= Start Default Config Data =======
[ETM] Header=  , BoardName= 
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= blank
[ETM] StaticIP= blank
[ETM] CCSum=0x 569 ,RCSum=0x 0
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-9C-FB-DB-DD-BA
[ETM] Dynamic IP OK, connected
[ETM] IP: 192.168.2.242
[ETM] begin:Stay in CfgPortal: No CfgDat
Connected! IP address: 192.168.2.242
H
Your stored Credentials :
MQTT Server = blank
Port = blank
MQTT UserName = blank
MQTT PWD = blank
Subs Topics = blank
Pubs Topics = blank
HHHHHH[ETM] h:Updating EEPROM. Please wait for reset
[ETM] h:Rst
H

1.2. Restart after Config Portal

Start Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : LAN8742A Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] ======== USE_BUILTIN_ETHERNET ========

(Emulated-)EEPROM size = 16384, start = 0
[ETM] ======= Start Default Config Data =======
[ETM] Header=  , BoardName= 
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32_ETM
[ETM] StaticIP= 192.168.2.241
[ETM] CCSum=0x 685 ,RCSum=0x 685
[ETM] Header= STM32 , BoardName= STM32_ETM
[ETM] StaticIP= 192.168.2.241
[ETM] Start connectEthernet using Static IP = 192.168.2.241
[ETM] MAC:FE-9F-F8-EF-ED-BA
[ETM] IP: 192.168.2.241
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.241

Your stored Credentials :
MQTT Server = mqtt_server
Port = 1883
MQTT UserName = mqtt_user
MQTT PWD = mqtt_pass
Subs Topics = mqtt_sub
Pubs Topics = mqtt_pub
HHHHHHHHHH HHHHHHHHHH HHHHHH

2. Ethernet_STM32 on STM32F7 NUCLEO_F767ZI with W5500 Ethernet using Ethernet_Generic Library

This is the terminal output of STM32F7 Nucleo-144 NUCLEO_F767ZI board with W5500 Ethernet shield using Ethernet_Generic Library, running Ethernet_STM32 example demonstrating doubleResetDetect feature.

2.1. Normal run with TO_LOAD_DEFAULT_CONFIG_DATA = true

Start Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : W5x00 using Ethernet_Generic Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] =========================
[ETM] Default SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================
[ETM] Board :NUCLEO_F767ZI, setCsPin:10
[ETM] =========================
[ETM] Currently Used SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] CCSum=0x 8ab ,RCSum=0x 8ab
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] Start connectEthernet using Static IP = 192.168.2.222
[ETM] MAC:FE-98-FE-DE-D9-BA

2.2. DRD detected

Start Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : W5x00 using Ethernet_Generic Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] =========================
[ETM] Default SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================
[ETM] Board :NUCLEO_F767ZI, setCsPin:10
[ETM] =========================
[ETM] Currently Used SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d01234
doubleResetDetected
ClearFlag write = 0xd0d04321
[ETM] =====================
[ETM] DRD. Run ConfigPortal
[ETM] =====================
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] CCSum=0x 8ab ,RCSum=0x 8ab
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] Start connectEthernet using Static IP = 192.168.2.222
[ETM] MAC:FE-9A-FD-D6-D9-BA

W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 10
W5100::init: W5500, SSIZE =4096
[ETM] IP: 192.168.2.222
[ETM] begin:Stay in CfgPortal: DRD
Connected! IP address: 192.168.2.222
Ethernet type is W5500

Your stored Credentials :
MQTT Server = mqtt_server
Port = 1883
MQTT UserName = mqtt_user
MQTT PWD = mqtt_pass
Subs Topics = mqtt_sub
Pubs Topics = mqtt_pub
H[ETM] h:Updating EEPROM. Please wait for reset
[ETM] h:Rst
H

2.3. Restart after Config Portal

Start Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : W5x00 using Ethernet_Generic Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] =========================
[ETM] Default SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================
[ETM] Board :NUCLEO_F767ZI, setCsPin:10
[ETM] =========================
[ETM] Currently Used SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] CCSum=0x 8ab ,RCSum=0x 8ab
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] Start connectEthernet using Static IP = 192.168.2.222
[ETM] MAC:FE-98-FE-DE-DC-BA

W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 10
W5100::init: W5500, SSIZE =4096
[ETM] IP: 192.168.2.222
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.222
Ethernet type is W5500

Your stored Credentials :
MQTT Server = mqtt_server
Port = 1883
MQTT UserName = mqtt_user
MQTT PWD = mqtt_pass
Subs Topics = mqtt_sub
Pubs Topics = mqtt_pub
Stop doubleResetDetecting
ClearFlag write = 0xd0d04321
HH

3. MQTT_ThingStream_Ethernet_STM32 on STM32F7 NUCLEO_F767ZI with ENC28J60 Ethernet using EthernetENC Library

This is the terminal output of STM32F7 Nucleo-144 NUCLEO_F767ZI board with ENC28J60 using EthernetENC Library, running complex MQTT_ThingStream_Ethernet_STM32 example to demonstrate how to use dynamic parameters, entered via Config Portal, to connect to ThingStream MQTT Server.

3.1. Normal run without correct ThingStream MQTT Credentials

Start MQTT_ThingStream_Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : ENC28J60 using EthernetENC Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] =========================
[ETM] Default SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================
[ETM] Board :NUCLEO_F767ZI, setCsPin:10
[ETM] =========================
[ETM] Currently Used SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= F767ZI_ThingStream
[ETM] StaticIP= 192.168.2.222
[ETM] CCSum=0x a38 ,RCSum=0x a38
[ETM] Invalid Stored Dynamic Data. Ignored
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-9F-F8-DD-D8-8D
[ETM] Dynamic IP OK, connected
[ETM] IP: 192.168.2.74
[ETM] begin:Stay in CfgPortal: No CfgDat
Connected! IP address: 192.168.2.74
***************************************
esp32-sniffer/12345678/ble
***************************************
Stop doubleResetDetecting
ClearFlag write = 0xd0d04321
[ETM] h:Updating EEPROM. Please wait for reset
[ETM] h:Rst

3.2. Got correct ThingStream MQTT Credentials from Config Portal

Start MQTT_ThingStream_Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : ENC28J60 using EthernetENC Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] =========================
[ETM] Default SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================
[ETM] Board :NUCLEO_F767ZI, setCsPin:10
[ETM] =========================
[ETM] Currently Used SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] CCSum=0x 8ab ,RCSum=0x 8ab
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] Start connectEthernet using Static IP = 192.168.2.222
[ETM] MAC:FE-99-FC-DA-DF-BA
[ETM] IP: 192.168.2.222
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.222
***************************************
esp32-sniffer/12345678/ble
***************************************
Attempting MQTT connection to mqtt.thingstream.io
...connected
Published connection message successfully!
Subscribed to: esp32-sniffer/12345678/ble

Your stored Credentials :
MQTT Server = mqtt.thingstream.io
Port = 1883
MQTT UserName = *******
MQTT PWD = *******
Client ID = *********
HStop doubleResetDetecting
ClearFlag write = 0xd0d04321
MQTT Message Send : esp32-sniffer/12345678/ble => Hello from MQTT_ThingStream on NUCLEO_F767ZI with ENC28J60 using EthernetENC Library
HMQTT Message receive [esp32-sniffer/12345678/ble] Hello from MQTT_ThingStream on NUCLEO_F767ZI with ENC28J60 using EthernetENC Library
HHHH

4. Ethernet_STM32 on STM32F7 NUCLEO_F767ZI with W5x00 Ethernet using Ethernet_Generic Library

This is the terminal output of STM32F7 Nucleo-144 NUCLEO_F767ZI board with W5x00 using Ethernet_Generic Library, running Ethernet_STM32 example to demonstrate the link status operation.

4.1. Normal run

Start Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : W5x00 using Ethernet_Generic Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] =========================
[ETM] Default SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================
[ETM] Board :NUCLEO_F767ZI, setCsPin:10
[ETM] =========================
[ETM] Currently Used SPI pinout:
[ETM] MOSI:11
[ETM] MISO:12
[ETM] SCK:13
[ETM] SS:10
[ETM] =========================

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] CCSum=0x 8ab ,RCSum=0x 8ab
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.222
[ETM] Start connectEthernet using Static IP = 192.168.2.222
[ETM] MAC:FE-98-FF-D6-D9-BA

W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 10
W5100::init: W5500, SSIZE =8192
[ETM] IP: 192.168.2.222
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.222
Ethernet type is W5500

Your stored Credentials :
MQTT Server = mqtt_server
Port = 1883
MQTT UserName = mqtt_user
MQTT PWD = mqtt_pass
Subs Topics = mqtt_sub
Pubs Topics = mqtt_pub
Stop doubleResetDetecting
ClearFlag write = 0xd0d04321
HHFFHHH    **<==== Check connection report by removing Ethernet Cable**

5. MQTT_ThingStream_Ethernet_STM32 on STM32F7 NUCLEO_F767ZI with LAN8742A Ethernet using STM32Ethernet Library

This is the terminal output of STM32F7 Nucleo-144 NUCLEO_F767ZI board with LAN8742A using STM32Ethernet Library, running complex MQTT_ThingStream_Ethernet_STM32 example to demonstrate how to use dynamic parameters, entered via Config Portal, to connect to ThingStream MQTT Server.

5.1. Normal run without correct ThingStream MQTT Credentials

Start MQTT_ThingStream_Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : LAN8742A Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] ======== USE_BUILTIN_ETHERNET ========

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.188
[ETM] CCSum=0x 8b6 ,RCSum=0x 8b6
[ETM] Invalid Stored Dynamic Data. Ignored
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-9A-F4-DC-DE-88
[ETM] Dynamic IP OK, connected
[ETM] IP: 192.168.2.69
[ETM] begin:Stay in CfgPortal: No CfgDat
Connected! IP address: 192.168.2.69
***************************************
esp32-sniffer/12345678/ble
***************************************
Stop doubleResetDetecting
ClearFlag write = 0xd0d04321
[ETM] h:Updating EEPROM. Please wait for reset
[ETM] h:Rst

5.2. Got correct ThingStream MQTT Credentials from Config Portal

Start MQTT_ThingStream_Ethernet_STM32 on NUCLEO_F767ZI
Ethernet Shield type : LAN8742A Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] ======== USE_BUILTIN_ETHERNET ========

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] ======= Start Default Config Data =======
[ETM] Header= Eth_NonSSL , BoardName= STM32-Ethernet
[ETM] StaticIP= 
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.188
[ETM] CCSum=0x 8b6 ,RCSum=0x 8b6
[ETM] Header= STM32 , BoardName= STM32-Ethernet
[ETM] StaticIP= 192.168.2.188
[ETM] Start connectEthernet using Static IP = 192.168.2.188
[ETM] MAC:FE-99-FF-DF-DB-BA
[ETM] IP: 192.168.2.188
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.188
***************************************
esp32-sniffer/12345678/ble
***************************************
Stop doubleResetDetecting
ClearFlag write = 0xd0d04321
Attempting MQTT connection to mqtt.thingstream.io
...connected
Published connection message successfully!
Subscribed to: esp32-sniffer/12345678/ble
H
Your stored Credentials :
MQTT Server = mqtt.thingstream.io
Port = 1883
MQTT UserName = mqtt_user_name
MQTT PWD = mqtt_password
Client ID = mqtt_clientID

MQTT Message Send : esp32-sniffer/12345678/ble => Hello from MQTT_ThingStream on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library

MQTT Message receive [esp32-sniffer/12345678/ble] Hello from MQTT_ThingStream on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library
HH
MQTT Message Send : esp32-sniffer/12345678/ble => Hello from MQTT_ThingStream on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library

MQTT Message receive [esp32-sniffer/12345678/ble] Hello from MQTT_ThingStream on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library
HH
MQTT Message Send : esp32-sniffer/12345678/ble => Hello from MQTT_ThingStream on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library

MQTT Message receive [esp32-sniffer/12345678/ble] Hello from MQTT_ThingStream on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library
HH

6. MQTT_ThingStream_Ethernet_STM32_LAN8720 on STM32F4 BLACK_F407VE with LAN8720 Ethernet using STM32Ethernet Library

This is the terminal output of STM32F4 BLACK_F407VE with LAN8720 Ethernet using STM32Ethernet Library, running complex MQTT_ThingStream_Ethernet_STM32_LAN8720 example to demonstrate how to use dynamic parameters, entered via Config Portal, to connect to ThingStream MQTT Server.

6.1. Normal run without correct ThingStream MQTT Credentials

Start MQTT_ThingStream_Ethernet_STM32_LAN8720 on BLACK_F407VE
Ethernet Shield type : LAN8720 Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] ======== USE_BUILTIN_ETHERNET ========

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d01234
doubleResetDetected
ClearFlag write = 0xd0d04321
[ETM] =====================
[ETM] DRD. Run ConfigPortal
[ETM] =====================
[ETM] EEPROMsz:4096
[ETM] EEPROM Length():16384
[ETM] CCSum=0x77e,RCSum=0x77e
[ETM] ChkCrR:CrCCsum=0x215e,CrRCsum=0x215e
[ETM] CrCCSum=215e,CrRCSum=215e
[ETM] Valid Stored Dynamic Data
[ETM] ======= Start Stored Config Data =======
[ETM] Header=STM32, BoardName=STM32-Ethernet
[ETM] StaticIP=
[ETM] Start connectEthernet using DHCP
[ETM] MAC:FE-98-FD-D6-DB-BA
[ETM] Dynamic IP OK, connected
[ETM] IP:192.168.2.149
[ETM] bg: isForcedConfigPortal = false
[ETM] bg:Stay forever in CP:DRD/MRD
Connected! IP address: 192.168.2.149
***************************************
esp32-sniffer/12345678/ble
***************************************
[ETM] h:Updating EEPROM. Please wait for reset
[ETM] SaveEEPROM,Sz=16384,DataSz=248,WCSum=0x8a9
[ETM] CrCCSum=0x2785
[ETM] h:Rst

6.2. Got correct ThingStream MQTT Credentials from Config Portal

Start MQTT_ThingStream_Ethernet_STM32_LAN8720 on BLACK_F407VE
Ethernet Shield type : LAN8720 Ethernet & STM32Ethernet Library
Ethernet_Manager_STM32 v1.3.2
DoubleResetDetector_Generic v1.8.1
[ETM] ======== USE_BUILTIN_ETHERNET ========

(Emulated-)EEPROM size = 16384, start = 0
Flag read = 0xd0d04321
No doubleResetDetected
SetFlag write = 0xd0d01234
[ETM] EEPROMsz:4096
[ETM] EEPROM Length():16384
[ETM] CCSum=0x8a9,RCSum=0x8a9
[ETM] ChkCrR:CrCCsum=0x2785,CrRCsum=0x2785
[ETM] CrCCSum=2785,CrRCSum=2785
[ETM] Valid Stored Dynamic Data
[ETM] ======= Start Stored Config Data =======
[ETM] Header=STM32, BoardName=STM32-Ethernet
[ETM] StaticIP=192.168.2.220
[ETM] Start connectEthernet using Static IP =192.168.2.220
[ETM] MAC:FE-98-FD-D6-DF-BA
[ETM] IP:192.168.2.220
[ETM] begin:Ethernet Connected.
Connected! IP address: 192.168.2.220
***************************************
esp32-sniffer/12345678/ble
***************************************

Your stored Credentials :
MQTT Server = mqtt.thingstream.io
Port = 1883
MQTT UserName = user_name
MQTT PWD = password
Client ID = device:12345678-1234-1234-1234-123456789abc
Attempting MQTT connection to mqtt.thingstream.io
...connected
Published connection message successfully!
Subscribed to: esp32-sniffer/12345678/ble
HStop doubleResetDetecting
ClearFlag write = 0xd0d04321

MQTT Message Send : esp32-sniffer/12345678/ble => Hello from MQTT_ThingStream on BLACK_F407VE with LAN8720 Ethernet & STM32Ethernet Library
H
MQTT Message receive [esp32-sniffer/12345678/ble] Hello from MQTT_ThingStream on BLACK_F407VE with LAN8720 Ethernet & STM32Ethernet Library


Debug

Debug is enabled by default on Serial.

You can also change the debugging level from 0 to 4

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

// Debug Level from 0 to 4
#define _ETHERNET_WEBSERVER_LOGLEVEL_           0
#define _ETHERNET_MANAGER_STM32_LOGLEVEL_       2

#define DRD_GENERIC_DEBUG                       true

Troubleshooting

If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards.

Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions.



Issues

Submit issues to: Ethernet_Manager_STM32 issues


TO DO

  1. Same features for other boards with new Ethernet shields.
  2. Add SSL/TLS feature.
  3. Bug Searching and Killing
  4. Support more non-compatible Ethernet Libraries such as Ethernet_Shield_W5200, EtherCard, EtherSia.

DONE

  1. Permit EEPROM size and location configurable to avoid conflict with others.
  2. More flexible to configure reconnection timeout.
  3. For fresh config data, don't need to wait for connecting timeout before entering config portal.
  4. If the config data not entered completely (Serves, HardwarePort and Blynk tokens), entering config portal
  5. Change Synch XMLHttpRequest to Async
  6. Reduce memory usage.
  7. Support ENC28J60 as well as W5100/W5200/W5500 Ethernet shields
  8. Add checksums
  9. Support STM32F/L/H/G/WB/MP1 boards
  10. Easy-to-use Dynamic Parameters without the necessity to write complicated ArduinoJSon functions
  11. Permit to input special chars such as % and # into data fields.
  12. DoubleDetectDetector to force Config Portal when double reset is detected within predetermined time, default 10s.
  13. Configurable Config Portal Title
  14. Re-structure all examples to separate Credentials / Defines / Dynamic Params / Code so that you can change Credentials / Dynamic Params quickly for each device.
  15. Add support to new EthernetENC library for ENC28J60.
  16. Add Table of Contents and Version String
  17. Configurable Customs HTML Headers, including Customs Style, Customs Head Elements, CORS Header
  18. Add support to Ethernet LAN8720 using STM32Ethernet library, for boards such as Nucleo-144 (F429ZI, NUCLEO_F746NG, NUCLEO_F746ZG, NUCLEO_F756ZG), Discovery (DISCO_F746NG) and STM32F4 boards (BLACK_F407VE, BLACK_F407VG, BLACK_F407ZE, BLACK_F407ZG, BLACK_F407VE_Mini, DIYMORE_F407VGT, FK407M1)
  19. Use new Ethernet_Generic library as default for W5x00.
  20. Add example multiFileProject to demo how to avoid multiple-definitions linker error for multiple-file project

Contributions and Thanks

  1. Thanks to Miguel Alexandre Wisintainer for initiating, inspriring, working with, developing, debugging and testing.
tcpipchip
⭐️ Miguel Wisintainer


Contributing

If you want to contribute to this project:

  • Report bugs and errors
  • Ask for enhancements
  • Create issues and pull requests
  • Tell other people about this library

License

  • The library is licensed under MIT

Copyright

Copyright (c) 2020- Khoi Hoang

About

Library for configuring/auto(re)connecting W5100/W5200/W5500, ENC28J60 and built-in LAN8742A / LAN8720 Ethernet at runtime using Config Portal. New powerful-yet-simple-to-use feature to enable adding dynamic custom parameters from sketch and input using the same Config Portal. Config Portal will be auto-adjusted to match the number of dynamic pa…

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published