AsyncUDP_STM32 Library
Table of Contents
- Important Change from v1.3.0
- Why do we need this AsyncUDP_STM32 library
- Features
- Why Async is better
- Currently supported Boards
- Changelog
- Prerequisites
- Installation
- Use Arduino Library Manager
- Manual Install
- VS Code & PlatformIO
- Packages' Patches
- 1. For STM32 boards to use LAN8720
- 2. For STM32 boards to use Serial1
- HOWTO Fix
Multiple Definitions
Linker Error
- HOWTO Setting up the Async UDP Client
- HOWTO use STM32F4 with LAN8720
- 1. Wiring
- 2. HOWTO program using STLink V-2 or V-3
- 3. HOWTO use Serial Port for Debugging
- Examples
- 1. AsyncUDPClient
- 2. AsyncUdpNTPClient
- 3. AsyncUdpSendReceive
- 4. AsyncUDPServer
- 5. AsyncUDPMulticastServer
- 6. AsyncUDPClient_LAN8720
- 7. AsyncUdpNTPClient_LAN8720
- 8. AsyncUdpSendReceive_LAN8720
- 9. AsyncUDPServer_LAN8720
- 10. AsyncUDPMulticastServer_LAN8720
- 11. multiFileProject New
- 12. multiFileProject_LAN8720 New
- Example AsyncUdpNTPClient
- 1. File AsyncUdpNTPClient.ino
- 2. File defines.h
- Debug Terminal Output Samples
- 1. AsyncUdpNTPClient on STM32F7 NUCLEO_F767ZI with LAN8742A Ethernet using STM32Ethernet Library
- 2. AsyncUdpNTPClient_LAN8720 on STM32F4 BLACK_F407VE with LAN8720 Ethernet using STM32Ethernet Library
- Debug
- Troubleshooting
- Issues
- TO DO
- DONE
- Contributions and Thanks
- Contributing
- License
- Copyright
Important Change from v1.3.0
Please have a look at HOWTO Fix Multiple Definitions
Linker Error
For Generic STM32F4 series
boards, such as STM32F407VE, using LAN8720, please use STM32 core v2.2.0
as breaking core v2.3.0
creates the compile error. Will fix in the near future.
Why do we need this AsyncUDP_STM32 library
Features
This AsyncUDP_STM32 library is a fully asynchronous UDP library, designed for a trouble-free, multi-connection network environment, for STM32 boards using LAN8720 or builtin LAN8742A Ethernet. The library is easy to use and includes support for Unicast, Broadcast and Multicast environments.
This library is based on, modified from:
- Hristo Gochkov's ESPAsyncUDP
to apply the better and faster asynchronous feature of the powerful ESPAsyncUDP Library into STM32 boards using LAN8720 or builtin LAN8742A Ethernet.
Why Async is better
- Using asynchronous network means that you can handle more than one connection at the same time
- You are called once the request is ready and parsed
- When you send the response, you are immediately ready to handle other connections while the server is taking care of sending the response in the background
- Speed is OMG
- After connecting to a UDP server as an Async Client, you are immediately ready to handle other connections while the Client is taking care of receiving the UDP responding packets in the background.
- You are not required to check in a tight loop() the arrival of the UDP responding packets to process them.
Currently supported Boards
- STM32 boards with built-in Ethernet LAN8742A such as :
- Nucleo-144 (F429ZI, F767ZI)
- Discovery (STM32F746G-DISCOVERY)
- All STM32 boards (STM32F/L/H/G/WB/MP1) with 32K+ Flash, with Built-in Ethernet
- See EthernetWebServer_STM32 Support and Test Results
- 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)
Prerequisites
Arduino IDE 1.8.19+
for Arduino.
Arduino Core for STM32 v2.3.0+
for STM32 boards.
STM32Ethernet library v1.3.0+
for built-in LAN8742A Ethernet on (Nucleo-144, Discovery).
LwIP library v2.1.2+
for built-in LAN8742A Ethernet on (Nucleo-144, Discovery).
Installation
The suggested way to install is to:
Use Arduino Library Manager
The best way is to use Arduino Library Manager
. Search for AsyncUDP_STM32
, then select / install the latest version. You can also use this link for more detailed instructions.
Manual Install
- Navigate to AsyncUDP_STM32 page.
- Download the latest release
AsyncUDP_STM32-master.zip
.
- Extract the zip file to
AsyncUDP_STM32-master
directory
- Copy the whole
AsyncUDP_STM32-master
folder to Arduino libraries' directory such as ~/Arduino/libraries/
.
VS Code & PlatformIO:
- Install VS Code
- Install PlatformIO
- Install AsyncUDP_STM32 library by using Library Manager. Search for AsyncUDP_STM32 in Platform.io Author's Libraries
- 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
For Generic STM32F4 series
boards, such as STM32F407VE
, using LAN8720
, please use STM32 core v2.2.0
as breaking core v2.3.0
creates the compile error.
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/NUCLEO_F767ZI/variant.h
for Nucleo-144 NUCLEO_F767ZI.
~/.arduino15/packages/STM32/hardware/stm32/2.3.0/variants/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/NUCLEO_F767ZI/variant.h
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/NUCLEO_L053R8/variant.h
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 include this .hpp
file
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
#include "AsyncUDP_STM32.hpp" //https://github.com/khoih-prog/AsyncUDP_STM32
in many files. But be sure to use the following .h
file 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 "AsyncUDP_STM32.h" //https://github.com/khoih-prog/AsyncUDP_STM32
Check the new multiFileProject example for a HOWTO
demo.
HOWTO Setting up the Async UDP Client
#include <LwIP.h>
#include <STM32Ethernet.h>
#include <AsyncUDP_STM32.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 };
IPAddress timeWindowsCom = IPAddress(13, 86, 101, 172);
#define NTP_REQUEST_PORT 123
const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
AsyncUDP Udp;
// send an NTP request to the time server at the given address
void createNTPpacket(void)
{
...
}
void sendNTPPacket(void)
{
createNTPpacket();
//Send unicast
Udp.write(packetBuffer, sizeof(packetBuffer));
}
void parsePacket(AsyncUDPPacket packet)
{
...
}
void setup()
{
...
//NTP requests are to port NTP_REQUEST_PORT = 123
if (Udp.connect(timeWindowsCom, NTP_REQUEST_PORT))
{
// Setting up Async packet Handler
Udp.onPacket([](AsyncUDPPacket packet)
{
parsePacket(packet);
});
}
}
void loop()
{
sendNTPPacket();
// wait 60 seconds before asking for the time again
delay(60000);
}
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
- AsyncUDPClient
- AsyncUdpNTPClient
- AsyncUdpSendReceive
- AsyncUDPServer
- AsyncUDPMulticastServer
- AsyncUDPClient_LAN8720
- AsyncUdpNTPClient_LAN8720
- AsyncUdpSendReceive_LAN8720
- AsyncUDPServer_LAN8720
- AsyncUDPMulticastServer_LAN8720
- multiFileProject New
- multiFileProject_LAN8720 New
Example AsyncUdpNTPClient
1. File AsyncUdpNTPClient.ino
|
#include "defines.h" |
|
#include <time.h> |
|
|
|
// 0.ca.pool.ntp.org |
|
IPAddress timeServerIP = IPAddress(208, 81, 1, 244); |
|
// time.nist.gov |
|
//IPAddress timeServerIP = IPAddress(132, 163, 96, 1); |
|
|
|
#define NTP_REQUEST_PORT 123 |
|
|
|
//char timeServer[] = "time.nist.gov"; // NTP server |
|
char timeServer[] = "0.ca.pool.ntp.org"; |
|
|
|
const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message |
|
|
|
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets |
|
|
|
// A UDP instance to let us send and receive packets over UDP |
|
AsyncUDP Udp; |
|
|
|
// send an NTP request to the time server at the given address |
|
void createNTPpacket(void) |
|
{ |
|
Serial.println("============= createNTPpacket ============="); |
|
|
|
// set all bytes in the buffer to 0 |
|
memset(packetBuffer, 0, NTP_PACKET_SIZE); |
|
// Initialize values needed to form NTP request |
|
// (see URL above for details on the packets) |
|
|
|
packetBuffer[0] = 0b11100011; // LI, Version, Mode |
|
packetBuffer[1] = 0; // Stratum, or type of clock |
|
packetBuffer[2] = 6; // Polling Interval |
|
packetBuffer[3] = 0xEC; // Peer Clock Precision |
|
|
|
// 8 bytes of zero for Root Delay & Root Dispersion |
|
packetBuffer[12] = 49; |
|
packetBuffer[13] = 0x4E; |
|
packetBuffer[14] = 49; |
|
packetBuffer[15] = 52; |
|
} |
|
|
|
void parsePacket(AsyncUDPPacket packet) |
|
{ |
|
struct tm ts; |
|
char buf[80]; |
|
|
|
memcpy(packetBuffer, packet.data(), sizeof(packetBuffer)); |
|
|
|
Serial.print("Received UDP Packet Type: "); |
|
Serial.println(packet.isBroadcast() ? "Broadcast" : packet.isMulticast() ? "Multicast" : "Unicast"); |
|
Serial.print("From: "); |
|
Serial.print(packet.remoteIP()); |
|
Serial.print(":"); |
|
Serial.print(packet.remotePort()); |
|
Serial.print(", To: "); |
|
Serial.print(packet.localIP()); |
|
Serial.print(":"); |
|
Serial.print(packet.localPort()); |
|
Serial.print(", Length: "); |
|
Serial.print(packet.length()); |
|
Serial.println(); |
|
|
|
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); |
|
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); |
|
|
|
// combine the four bytes (two words) into a long integer |
|
// this is NTP time (seconds since Jan 1 1900): |
|
unsigned long secsSince1900 = highWord << 16 | lowWord; |
|
|
|
Serial.print(F("Seconds since Jan 1 1900 = ")); |
|
Serial.println(secsSince1900); |
|
|
|
// now convert NTP time into )everyday time: |
|
Serial.print(F("Epoch/Unix time = ")); |
|
|
|
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800: |
|
const unsigned long seventyYears = 2208988800UL; |
|
|
|
// subtract seventy years: |
|
unsigned long epoch = secsSince1900 - seventyYears; |
|
time_t epoch_t = epoch; //secsSince1900 - seventyYears; |
|
|
|
// print Unix time: |
|
Serial.println(epoch); |
|
|
|
// print the hour, minute and second: |
|
Serial.print(F("The UTC/GMT time is ")); // UTC is the time at Greenwich Meridian (GMT) |
|
|
|
ts = *localtime(&epoch_t); |
|
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); |
|
Serial.println(buf); |
|
} |
|
|
|
void sendNTPPacket(void) |
|
{ |
|
createNTPpacket(); |
|
//Send unicast |
|
Udp.write(packetBuffer, sizeof(packetBuffer)); |
|
} |
|
|
|
void setup() |
|
{ |
|
Serial.begin(115200); |
|
while (!Serial); |
|
|
|
Serial.print("nStart AsyncUdpNTPClient on "); Serial.println(BOARD_NAME); |
|
Serial.println(ASYNC_UDP_STM32_VERSION); |
|
|
|
#if (_ASYNC_UDP_STM32_LOGLEVEL_ > 2) |
|
Serial.print("STM32 Core version v"); Serial.print(STM32_CORE_VERSION_MAJOR); |
|
Serial.print("."); Serial.print(STM32_CORE_VERSION_MINOR); |
|
Serial.print("."); Serial.println(STM32_CORE_VERSION_PATCH); |
|
#endif |
|
|
|
// start the ethernet connection and the server |
|
// Use random mac |
|
uint16_t index = millis() % NUMBER_OF_MAC; |
|
|
|
// Use Static IP |
|
//Ethernet.begin(mac[index], ip); |
|
// Use DHCP dynamic IP and random mac |
|
Ethernet.begin(mac[index]); |
|
|
|
// you're connected now, so print out the data |
|
Serial.print(F("You're connected to the network, IP = ")); |
|
Serial.println(Ethernet.localIP()); |
|
|
|
//NTP requests are to port NTP_REQUEST_PORT = 123 |
|
if (Udp.connect(timeServerIP, NTP_REQUEST_PORT)) |
|
//if (Udp.connect(timeServer, NTP_REQUEST_PORT)) |
|
{ |
|
Serial.println("UDP connected"); |
|
|
|
Udp.onPacket([](AsyncUDPPacket packet) |
|
{ |
|
parsePacket(packet); |
|
}); |
|
} |
|
} |
|
|
|
void loop() |
|
{ |
|
sendNTPPacket(); |
|
|
|
// wait 60 seconds before asking for the time again |
|
delay(60000); |
|
} |
2. File defines.h
|
/* |
|
Currently support |
|
1) STM32 boards with built-in Ethernet (to use USE_BUILTIN_ETHERNET = true) such as : |
|
- Nucleo-144 (F429ZI, F767ZI) |
|
- Discovery (STM32F746G-DISCOVERY) |
|
- STM32 boards (STM32F/L/H/G/WB/MP1) with 32K+ Flash, with Built-in Ethernet, |
|
- See How To Use Built-in Ethernet at (https://github.com/khoih-prog/EthernetWebServer_STM32/issues/1) |
|
2) STM32F/L/H/G/WB/MP1 boards (with 32+K Flash) running ENC28J60 shields (to use USE_BUILTIN_ETHERNET = false) |
|
3) STM32F/L/H/G/WB/MP1 boards (with 32+K Flash) running W5x00 shields |
|
*/ |
|
|
|
#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) ) |
|
#error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting. |
|
#endif |
|
|
|
#define ASYNC_UDP_STM32_DEBUG_PORT Serial |
|
|
|
// Use from 0 to 4. Higher number, more debugging messages and memory usage. |
|
#define _ASYNC_UDP_STM32_LOGLEVEL_ 1 |
|
|
|
|
|
#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 |
|
|
|
#include <LwIP.h> |
|
#include <STM32Ethernet.h> |
|
|
|
#include <AsyncUDP_STM32.h> |
|
|
|
// Enter a MAC address and IP address for your controller below. |
|
#define NUMBER_OF_MAC 20 |
|
|
|
byte mac[][NUMBER_OF_MAC] = |
|
{ |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, |
|
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, |
|
}; |
|
|
|
// Select the static IP address according to your local network |
|
IPAddress ip(192, 168, 2, 232); |
|
|
|
#endif //defines_h |
Debug Terminal Output Samples
1. AsyncUdpNTPClient on STM32F7 NUCLEO_F767ZI with LAN8742A Ethernet using STM32Ethernet Library
This is terminal debug output when running AsyncUdpNTPClient on STM32F7 Nucleo-144 NUCLEO_F767ZI.. It connects to NTP Server time.windows.com (IP=13.86.101.172) using AsyncUDP_STM32 library, and requests NTP time every 60s. The packet is then received and processed asynchronously to print current UTC/GMT time.
Start AsyncUdpNTPClient on NUCLEO_F767ZI
AsyncUdp_STM32 v1.3.0
STM32 Core version v2.3.0
You're connected to the network, IP = 192.168.2.157
UDP connected
============= createNTPpacket =============
Received UDP Packet Type: Unicast
From: 208.81.1.244:123, To: 192.168.2.157:62510, Length: 48
Seconds since Jan 1 1900 = 3864858437
Epoch/Unix time = 1655869637
The UTC/GMT time is Wed 2022-06-22 03:47:17 GMT
============= createNTPpacket =============
Received UDP Packet Type: Unicast
From: 208.81.1.244:123, To: 192.168.2.157:62510, Length: 48
Seconds since Jan 1 1900 = 3864858497
Epoch/Unix time = 1655869697
The UTC/GMT time is Wed 2022-06-22 03:48:17 GMT
============= createNTPpacket =============
Received UDP Packet Type: Unicast
From: 208.81.1.244:123, To: 192.168.2.157:62510, Length: 48
Seconds since Jan 1 1900 = 3864858557
Epoch/Unix time = 1655869757
The UTC/GMT time is Wed 2022-06-22 03:49:17 GMT
2. AsyncUdpNTPClient_LAN8720 on STM32F4 BLACK_F407VE with LAN8720 Ethernet using STM32Ethernet Library
This is terminal debug output when running AsyncUdpNTPClient_LAN8720 on STM32F4 BLACK_F407VE with LAN8720 Ethernet using STM32Ethernet Library. It connects to NTP Server time.windows.com (IP=13.86.101.172) using AsyncUDP_STM32 library, and requests NTP time every 60s. The packet is then received and processed asynchronously to print current UTC/GMT time.
Start AsyncUdpNTPClient_LAN8720 on BLACK_F407VE
AsyncUdp_STM32 v1.3.0
STM32 Core version v2.3.0
You're connected to the network, IP = 192.168.2.151
UDP connected
============= createNTPpacket =============
Received UDP Packet Type: Unicast
From: 208.81.1.244:123, To: 192.168.2.157:62510, Length: 48
Seconds since Jan 1 1900 = 3864858616
Epoch/Unix time = 1655869816
The UTC/GMT time is Wed 2022-06-22 03:50:16 GMT
============= createNTPpacket =============
Received UDP Packet Type: Unicast
From: 208.81.1.244:123, To: 192.168.2.157:62510, Length: 48
Seconds since Jan 1 1900 = 3864858676
Epoch/Unix time = 1655869876
The UTC/GMT time is Wed 2022-06-22 03:51:16 GMT
============= createNTPpacket =============
Received UDP Packet Type: Unicast
From: 208.81.1.244:123, To: 192.168.2.157:62510, Length: 48
Seconds since Jan 1 1900 = 3864858735
Epoch/Unix time = 1655869935
The UTC/GMT time is Wed 2022-06-22 03:52:15 GMT
Debug
Debug is enabled by default on Serial. To disable, use level 0
#define ASYNC_UDP_STM32_DEBUG_PORT Serial
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _ASYNC_UDP_STM32_LOGLEVEL_ 0
You can also change the debugging level from 0 to 4
#define ASYNC_UDP_STM32_DEBUG_PORT Serial
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _ASYNC_UDP_STM32_LOGLEVEL_ 4
Troubleshooting
If you get compilation errors, more often than not, you may need to install a newer version of Arduino IDE, the Arduino STM32
core or depending libraries.
Sometimes, the library will only work if you update the STM32
core to the latest version because I am always using the latest cores /libraries.
Issues
Submit issues to: AsyncUDP_STM32 issues
TO DO
- Fix bug. Add enhancement
- Add support to more Ethernet / WiFi shield
- Add support to more STM32 boards.
DONE
- Initial port to STM32 using builtin LAN8742A Etnernet. Tested on STM32F7 Nucleo-144 F767ZI.
- Add more examples.
- Add debugging features.
- 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)
- Fix multiple-definitions linker error
- Update examples for new STM32 core v2.3.0
- Add example multiFileProject and multiFileProject_LAN8720 to demo for multiple-file project to avoid
multiple-definitions
linker error
Contributions and Thanks
- Based on and modified from Hristo Gochkov's ESPAsyncUDP. Many thanks to Hristo Gochkov for great ESPAsyncUDP Library
- Relied on Frederic Pillon's STM32duino LwIP Library.
- Thanks to good work of Miguel Wisintainer for working with, developing, debugging and testing.
️️ Hristo Gochkov
|
️ Frederic Pillon
|
tcpipchip
|
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