AsyncUDP_STM32
How To Install Using Arduino Library Manager
Why do we need this Async AsyncUDP_STM32 Library
- Using asynchronous network means that you can handle more than one connection at the same time
- You are called once the packet is ready
- 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.
- Speed is OMG
Initial Releases v1.1.0
1. Initial coding to port the powerful ESPAsyncUDP Library to STM32 boards using built-in LAN8742A Ethernet. More supports will be added gradually later, such as other Ethernet / WiFi shields.
2. Add more examples.
3. Add debugging features.
4. Bump up to v1.1.0 to sync with ESPAsyncUDP Library v1.1.0.
Currently Supported Boards
1. Nucleo-144 (F429ZI, F746ZG, F756ZG, F767ZI)
2. Discovery STM32F746G-DISCOVERY
3. Any STM32 boards with enough flash/memory and already configured to run LAN8742A Ethernet.
Sample Code
This is the AsyncUdpNTPClient example
Code: Select all
/*
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)
*/
#include "defines.h"
#include <time.h>
IPAddress timeWindowsCom = IPAddress(13, 86, 101, 172);
#define NTP_REQUEST_PORT 123
char timeServer[] = "time.nist.gov"; // NTP server
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.println("\nStart AsyncUdpNTPClient on " + String(BOARD_NAME));
// 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(timeWindowsCom, 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);
}
Debug Termimal Output Samples
1. This is terminal debug output when running AsyncUdpNTPClient example 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.
Code: Select all
Start AsyncUdpNTPClient on NUCLEO_F767ZI
You're connected to the network, IP = 192.168.2.187
UDP connected
============= createNTPpacket =============
[UDP] _recv: Call packetHandler with packet from remoteIP = 13.86.101.172 , remotePort = 123
[UDP] To destIP = 192.168.2.187 , destPort = 62510
[UDP] Packet len = 48
Received UDP Packet Type: Unicast
From: 13.86.101.172:123, To: 192.168.2.187:62510, Length: 48
Seconds since Jan 1 1900 = 3808150993
Epoch/Unix time = 1599162193
The UTC/GMT time is Thu 2020-09-03 19:43:13 GMT
...
============= createNTPpacket =============
[UDP] _recv: Call packetHandler with packet from remoteIP = 13.86.101.172 , remotePort = 123
[UDP] To destIP = 192.168.2.187 , destPort = 62510
[UDP] Packet len = 48
Received UDP Packet Type: Unicast
From: 13.86.101.172:123, To: 192.168.2.187:62510, Length: 48
Seconds since Jan 1 1900 = 3808151290
Epoch/Unix time = 1599162490
The UTC/GMT time is Thu 2020-09-03 19:48:10 GMT
============= createNTPpacket =============
[UDP] _recv: Call packetHandler with packet from remoteIP = 13.86.101.172 , remotePort = 123
[UDP] To destIP = 192.168.2.187 , destPort = 62510
[UDP] Packet len = 48
Received UDP Packet Type: Unicast
From: 13.86.101.172:123, To: 192.168.2.187:62510, Length: 48
Seconds since Jan 1 1900 = 3808151349
Epoch/Unix time = 1599162549
The UTC/GMT time is Thu 2020-09-03 19:49:09 GMT