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

Commit 441cbb9

Browse files
authored
v2.1.0 to fix multiple-definitions linker error
#### Releases v2.1.0 1. Fix multiple-definitions linker error. Check [Multiple definitions #1](#1) 2. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project to avoid `multiple-definitions` linker error
1 parent 0e8d81f commit 441cbb9

13 files changed

+412
-355
lines changed

CONTRIBUTING.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p
1414

1515
Please ensure to specify the following:
1616

17-
* Arduino IDE version (e.g. 1.8.16) or Platform.io version
18-
* `ESP32` Core Version (e.g. ESP32 v2.0.1)
17+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
18+
* `ESP32` Core Version (e.g. ESP32 v2.0.3)
1919
* Contextual information (e.g. what you were trying to achieve)
2020
* Simplest possible steps to reproduce
2121
* Anything that might be relevant in your opinion, such as:
@@ -26,10 +26,10 @@ Please ensure to specify the following:
2626
### Example
2727

2828
```
29-
Arduino IDE version: 1.8.16
30-
ESP32 Core Version 2.0.1
29+
Arduino IDE version: 1.8.19
30+
ESP32 Core Version 2.0.3
3131
OS: Ubuntu 20.04 LTS
32-
Linux xy-Inspiron-3593 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
32+
Linux xy-Inspiron-3593 5.13.0-51-generic #58~20.04.1-Ubuntu SMP Tue Jun 14 11:29:12 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3333
3434
Context:
3535
I encountered an endless loop while trying to connect to Local WiFi.
@@ -49,3 +49,4 @@ There are usually some outstanding feature requests in the [existing issues list
4949
### Sending Pull Requests
5050

5151
Pull Requests with changes and fixes are also welcome!
52+

README.md

Lines changed: 56 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/AsyncUDP_WT32_ETH01.svg)](http://github.com/khoih-prog/AsyncUDP_WT32_ETH01/issues)
88

99

10-
<a href="https://www.buymeacoffee.com/khoihprog6" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
10+
<a href="https://www.buymeacoffee.com/khoihprog6" title="Donate to my libraries using BuyMeACoffee"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Donate to my libraries using BuyMeACoffee" style="height: 50px !important;width: 181px !important;" ></a>
11+
<a href="https://www.buymeacoffee.com/khoihprog6" title="Donate to my libraries using BuyMeACoffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-orange.svg?logo=buy-me-a-coffee&logoColor=FFDD00" style="height: 20px !important;width: 200px !important;" ></a>
1112

1213
---
1314
---
1415

1516
## Table of Contents
1617

17-
18+
* [Important Change from v2.1.0](#Important-Change-from-v210)
1819
* [Why do we need this AsyncUDP_WT32_ETH01 library](#why-do-we-need-this-asyncudp_wt32_eth01-library)
1920
* [Features](#features)
2021
* [Why Async is better](#why-async-is-better)
@@ -38,6 +39,7 @@
3839
* [ 3. AsyncUdpSendReceive](examples/AsyncUdpSendReceive)
3940
* [ 4. AsyncUDPServer](examples/AsyncUDPServer)
4041
* [ 5. AsyncUDPMulticastServer](examples/AsyncUDPMulticastServer)
42+
* [ 6. **multiFileProject**](examples/multiFileProject) **New**
4143
* [Example AsyncUdpNTPClient](#example-asyncudpntpclient)
4244
* [File AsyncUdpNTPClient.ino](#file-asyncudpntpclientino)
4345
* [Debug Terminal Output Samples](#debug-terminal-output-samples)
@@ -53,6 +55,15 @@
5355
* [License](#license)
5456
* [Copyright](#copyright)
5557

58+
59+
---
60+
---
61+
62+
### Important Change from v2.1.0
63+
64+
Please have a look at [HOWTO Fix `Multiple Definitions` Linker Error](#howto-fix-multiple-definitions-linker-error)
65+
66+
5667
---
5768
---
5869

@@ -89,10 +100,10 @@ to apply the better and faster **asynchronous** feature of the **powerful** [Asy
89100

90101
## Prerequisites
91102

92-
1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest)
93-
2. [`ESP32 Core 2.0.2+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
103+
1. [`Arduino IDE 1.8.16+` for Arduino](https://www.arduino.cc/en/Main/Software)
104+
2. [`ESP32 Core 2.0.3+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
94105

95-
3. [`WebServer_WT32_ETH01 library 1.4.1+`](https://github.com/khoih-prog/WebServer_WT32_ETH01). To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/WebServer_WT32_ETH01.svg?)](https://www.ardu-badge.com/WebServer_WT32_ETH01).
106+
3. [`WebServer_WT32_ETH01 library 1.5.0+`](https://github.com/khoih-prog/WebServer_WT32_ETH01). To install, check [![arduino-library-badge](https://www.ardu-badge.com/badge/WebServer_WT32_ETH01.svg?)](https://www.ardu-badge.com/WebServer_WT32_ETH01).
96107
---
97108

98109
### Installation
@@ -114,7 +125,7 @@ The best way is to use `Arduino Library Manager`. Search for `AsyncUDP_WT32_ETH0
114125

115126
1. Install [VS Code](https://code.visualstudio.com/)
116127
2. Install [PlatformIO](https://platformio.org/platformio-ide)
117-
3. Install [**AsyncUDP_WT32_ETH01** library](https://platformio.org/lib/show/12542/AsyncUDP_WT32_ETH01) by using [Library Manager](https://platformio.org/lib/show/12542/AsyncUDP_WT32_ETH01/installation). Search for AsyncUDP_WT32_ETH01 in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22)
128+
3. Install [**AsyncUDP_WT32_ETH01** library](https://registry.platformio.org/libraries/AsyncUDP_WT32_ETH01) by using [Library Manager](https://registry.platformio.org/libraries/AsyncUDP_WT32_ETH01/installation). Search for AsyncUDP_WT32_ETH01 in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22)
118129
4. Use included [platformio.ini](platformio/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](https://docs.platformio.org/page/projectconf.html)
119130

120131
---
@@ -129,6 +140,33 @@ To fix [`ESP32 compile error`](https://github.com/espressif/arduino-esp32), just
129140
- [Server.h](LibraryPatches/esp32/cores/esp32/Server.h)
130141

131142

143+
144+
---
145+
---
146+
147+
148+
### HOWTO Fix `Multiple Definitions` Linker Error
149+
150+
The current library implementation, using `xyz-Impl.h` instead of standard `xyz.cpp`, possibly creates certain `Multiple Definitions` Linker error in certain use cases.
151+
152+
You can include this `.hpp` file
153+
154+
```
155+
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
156+
#include "AsyncUDP_WT32_ETH01.hpp" //https://github.com/khoih-prog/AsyncUDP_WT32_ETH01
157+
```
158+
159+
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
160+
161+
```
162+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
163+
#include "AsyncUDP_WT32_ETH01.h" //https://github.com/khoih-prog/AsyncUDP_WT32_ETH01
164+
```
165+
166+
Check the new [**multiFileProject** example](examples/multiFileProject) for a `HOWTO` demo.
167+
168+
169+
132170
---
133171
---
134172

@@ -262,181 +300,14 @@ void loop()
262300
3. [AsyncUdpSendReceive](examples/AsyncUdpSendReceive)
263301
4. [AsyncUDPServer](examples/AsyncUDPServer)
264302
5. [AsyncUDPMulticastServer](examples/AsyncUDPMulticastServer)
265-
303+
6. [**multiFileProject**](examples/multiFileProject) **New**
266304
---
267305
268306
### Example [AsyncUdpNTPClient](examples/AsyncUdpNTPClient)
269307
270308
#### File [AsyncUdpNTPClient.ino](examples/AsyncUdpNTPClient/AsyncUdpNTPClient.ino)
271309
272-
273-
```cpp
274-
#define ASYNC_UDP_WT32_ETH01_DEBUG_PORT Serial
275-
276-
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
277-
#define _ASYNC_UDP_WT32_ETH01_LOGLEVEL_ 2
278-
279-
#include <AsyncUDP_WT32_ETH01.h>
280-
281-
/////////////////////////////////////////////
282-
283-
// Select the IP address according to your local network
284-
IPAddress myIP(192, 168, 2, 232);
285-
IPAddress myGW(192, 168, 2, 1);
286-
IPAddress mySN(255, 255, 255, 0);
287-
288-
// Google DNS Server IP
289-
IPAddress myDNS(8, 8, 8, 8);
290-
291-
/////////////////////////////////////////////
292-
293-
#include <time.h>
294-
295-
// 0.ca.pool.ntp.org
296-
IPAddress timeServerIP = IPAddress(208, 81, 1, 244);
297-
// time.nist.gov
298-
//IPAddress timeServerIP = IPAddress(132, 163, 96, 1);
299-
300-
#define NTP_REQUEST_PORT 123
301-
302-
const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message
303-
304-
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
305-
306-
// A UDP instance to let us send and receive packets over UDP
307-
AsyncUDP Udp;
308-
309-
// send an NTP request to the time server at the given address
310-
void createNTPpacket(void)
311-
{
312-
Serial.println("============= createNTPpacket =============");
313-
314-
// set all bytes in the buffer to 0
315-
memset(packetBuffer, 0, NTP_PACKET_SIZE);
316-
// Initialize values needed to form NTP request
317-
// (see URL above for details on the packets)
318-
319-
packetBuffer[0] = 0b11100011; // LI, Version, Mode
320-
packetBuffer[1] = 0; // Stratum, or type of clock
321-
packetBuffer[2] = 6; // Polling Interval
322-
packetBuffer[3] = 0xEC; // Peer Clock Precision
323-
324-
// 8 bytes of zero for Root Delay & Root Dispersion
325-
packetBuffer[12] = 49;
326-
packetBuffer[13] = 0x4E;
327-
packetBuffer[14] = 49;
328-
packetBuffer[15] = 52;
329-
}
330-
331-
void parsePacket(AsyncUDPPacket packet)
332-
{
333-
struct tm ts;
334-
char buf[80];
335-
336-
memcpy(packetBuffer, packet.data(), sizeof(packetBuffer));
337-
338-
Serial.print("Received UDP Packet Type: ");
339-
Serial.println(packet.isBroadcast() ? "Broadcast" : packet.isMulticast() ? "Multicast" : "Unicast");
340-
Serial.print("From: ");
341-
Serial.print(packet.remoteIP());
342-
Serial.print(":");
343-
Serial.print(packet.remotePort());
344-
Serial.print(", To: ");
345-
Serial.print(packet.localIP());
346-
Serial.print(":");
347-
Serial.print(packet.localPort());
348-
Serial.print(", Length: ");
349-
Serial.print(packet.length());
350-
Serial.println();
351-
352-
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
353-
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
354-
355-
// combine the four bytes (two words) into a long integer
356-
// this is NTP time (seconds since Jan 1 1900):
357-
unsigned long secsSince1900 = highWord << 16 | lowWord;
358-
359-
Serial.print(F("Seconds since Jan 1 1900 = "));
360-
Serial.println(secsSince1900);
361-
362-
// now convert NTP time into )everyday time:
363-
Serial.print(F("Epoch/Unix time = "));
364-
365-
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
366-
const unsigned long seventyYears = 2208988800UL;
367-
368-
// subtract seventy years:
369-
unsigned long epoch = secsSince1900 - seventyYears;
370-
time_t epoch_t = epoch; //secsSince1900 - seventyYears;
371-
372-
// print Unix time:
373-
Serial.println(epoch);
374-
375-
// print the hour, minute and second:
376-
Serial.print(F("The UTC/GMT time is ")); // UTC is the time at Greenwich Meridian (GMT)
377-
378-
ts = *localtime(&epoch_t);
379-
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
380-
Serial.println(buf);
381-
}
382-
383-
void sendNTPPacket(void)
384-
{
385-
createNTPpacket();
386-
//Send unicast
387-
Udp.write(packetBuffer, sizeof(packetBuffer));
388-
}
389-
390-
void setup()
391-
{
392-
Serial.begin(115200);
393-
while (!Serial);
394-
395-
Serial.print("\nStarting AsyncUdpNTPClient on " + String(ARDUINO_BOARD));
396-
Serial.println(" with " + String(SHIELD_TYPE));
397-
Serial.println(WEBSERVER_WT32_ETH01_VERSION);
398-
Serial.println(ASYNC_UDP_WT32_ETH01_VERSION);
399-
400-
Serial.setDebugOutput(true);
401-
402-
// To be called before ETH.begin()
403-
WT32_ETH01_onEvent();
404-
405-
//bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO,
406-
// eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE);
407-
//ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_TYPE, ETH_CLK_MODE);
408-
ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER);
409-
410-
// Static IP, leave without this line to get IP via DHCP
411-
//bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = 0, IPAddress dns2 = 0);
412-
ETH.config(myIP, myGW, mySN, myDNS);
413-
414-
WT32_ETH01_waitForConnect();
415-
416-
// Client address
417-
Serial.print("AsyncUdpNTPClient started @ IP address: ");
418-
Serial.println(ETH.localIP());
419-
420-
//NTP requests are to port NTP_REQUEST_PORT = 123
421-
if (Udp.connect(timeServerIP, NTP_REQUEST_PORT))
422-
{
423-
Serial.println("UDP connected");
424-
425-
Udp.onPacket([](AsyncUDPPacket packet)
426-
{
427-
parsePacket(packet);
428-
});
429-
}
430-
}
431-
432-
void loop()
433-
{
434-
sendNTPPacket();
435-
436-
// wait 60 seconds before asking for the time again
437-
delay(60000);
438-
}
439-
```
310+
https://github.com/khoih-prog/AsyncUDP_Teensy41/blob/79a2019f3482e6902406bacffd483bcdf6921195/examples/AsyncUdpNTPClient/AsyncUdpNTPClient.ino#L12-L199
440311
441312
---
442313
@@ -450,8 +321,8 @@ This is terminal debug output when running [AsyncUdpNTPClient](https://github.co
450321
451322
```
452323
Starting AsyncUdpNTPClient on ESP32_DEV with ETH_PHY_LAN8720
453-
WebServer_WT32_ETH01 v1.4.1 for core v2.0.0+
454-
AsyncUdp_WT32_ETH01 v2.0.3 for core v2.0.0+
324+
WebServer_WT32_ETH01 v1.5.0 for core v2.0.0+
325+
AsyncUdp_WT32_ETH01 v2.1.0 for core v2.0.0+
455326
ETH Started
456327
ETH Connected
457328
ETH MAC: A8:03:2A:A1:61:73, IPv4: 192.168.2.95
@@ -483,8 +354,8 @@ The UTC/GMT time is Mon 2021-11-29 16:46:10 GMT
483354
484355
```
485356
Starting AsyncUdpNTPClient on ESP32_DEV with ETH_PHY_LAN8720
486-
WebServer_WT32_ETH01 v1.4.1 for core v2.0.0+
487-
AsyncUdp_WT32_ETH01 v2.0.3 for core v2.0.0+
357+
WebServer_WT32_ETH01 v1.5.0 for core v2.0.0+
358+
AsyncUdp_WT32_ETH01 v2.1.0 for core v2.0.0+
488359
ETH MAC: A8:03:2A:A1:61:73, IPv4: 192.168.2.232
489360
FULL_DUPLEX, 100Mbps
490361
AsyncUdpNTPClient started @ IP address: 192.168.2.232
@@ -518,8 +389,8 @@ This is terminal debug output when running [AsyncUDPSendReceive](https://github.
518389
519390
```
520391
Starting AsyncUDPSendReceive on ESP32_DEV with ETH_PHY_LAN8720
521-
WebServer_WT32_ETH01 v1.4.1 for core v2.0.0+
522-
AsyncUdp_WT32_ETH01 v2.0.3 for core v2.0.0+
392+
WebServer_WT32_ETH01 v1.5.0 for core v2.0.0+
393+
AsyncUdp_WT32_ETH01 v2.1.0 for core v2.0.0+
523394
ETH MAC: A8:03:2A:A1:61:73, IPv4: 192.168.2.232
524395
FULL_DUPLEX, 100Mbps
525396
AsyncUDPSendReceive started @ IP address: 192.168.2.232
@@ -595,7 +466,10 @@ Submit issues to: [AsyncUDP_WT32_ETH01 issues](https://github.com/khoih-prog/Asy
595466
3. Add debugging features.
596467
4. Auto detect ESP32 core to use for WT32_ETH01
597468
5. Fix bug in WT32_ETH01 examples to reduce connection time
598-
469+
6. Fix `multiple-definitions` linker error.
470+
7. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project
471+
472+
599473
---
600474
---
601475

changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
## Table of Contents
1313

1414
* [Changelog](#changelog)
15+
* [Releases v2.1.0](#releases-v210)
1516
* [Releases v2.0.3](#releases-v203)
1617
* [Releases v2.0.2](#releases-v202)
1718
* [Releases v2.0.1](#releases-v201)
@@ -22,6 +23,11 @@
2223

2324
## Changelog
2425

26+
#### Releases v2.1.0
27+
28+
1. Fix multiple-definitions linker error. Check [Multiple definitions #1](https://github.com/khoih-prog/AsyncUDP_WT32_ETH01/issues/1)
29+
2. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project to avoid `multiple-definitions` linker error
30+
2531
### Releases v2.0.3
2632

2733
##### Warning: Releases v2.0.3+ can be used and autodetect ESP32 core v2.0.0+ or v1.0.6- for WT32_ETH01
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/****************************************************************************************************************************
2+
multiFileProject.cpp
3+
AsyncUDP_WT32_ETH01 is a Async UDP library for the WT32_ETH01 (ESP32 + LAN8720)
4+
5+
Based on and modified from ESPAsyncUDP Library (https://github.com/me-no-dev/ESPAsyncUDP)
6+
Built by Khoi Hoang https://github.com/khoih-prog/AsyncUDP_WT32_ETH01
7+
Licensed under MIT license
8+
*****************************************************************************************************************************/
9+
10+
// To demo how to include files in multi-file Projects
11+
12+
#include "multiFileProject.h"

0 commit comments

Comments
 (0)