AsyncUDP_STM32 for STM32 using builtin LAN8742A Ethernet
Posted: Fri Sep 04, 2020 3:13 am
AsyncUDP_STM32
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
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.
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