Request for QNEthernet library testers

Greetings, colleagues. I’ve claimed that my QNEthernet library works on other platforms besides Teensy. I’ve tested a little bit with the W5500 driver, but would love it if there were others using non-Teensy platforms that could try this out.

The library should be a drop-in replacement for the regular Arduino-style Ethernet library, but there’s a few minor changes that are described in the Readme. There’s a feature list near the bottom (and in the table of contents).

I’m inviting anyone who’s interested to test out this library and give me some feedback. See GitHub - ssilverman/QNEthernet: An lwIP-based Ethernet library for Teensy 4.1 and other platforms or the Arduino Library Manager.

Notes:

  1. Define QNETHERNET_ENABLE_PING_SEND as 1 for the Ping and SimplePing examples or to implement your own ping code (src/qnethernet_opts.h)
  2. Define QNETHERNET_ENABLE_RAW_FRAME_SUPPORT as 1 for the RawFrameMonitor example or to implement your own raw frame code (src/qnethernet_opts.h)
  3. Currently, I’ve only got a W5500 driver implemented (and incomplete ENC28J60, W5100, and LAN8650 because I haven’t worked with them as much); to use, define QNETHERNET_DRIVER_W5500 in your project compile flags
  4. Let me know if there’s other drivers you’d need, and, if I can find some hardware, I can test with that
  5. The Readme has lots of information
1 Like

Hi Shawn. what are the current hardware and C++ compiler version requirements of QNEthernet?

Great question. Version 0.33.1 requires C++14 or later, but the next release will require C++11 or later. (The latest on GitHub is C++11 or later.)

As for the hardware requirements, that depends on the driver. The current W5500 driver requires SPI. There’s also a way to plug in a hardware random number generator if the platform supports it.

Note: the SPI pins are configurable with the SPI class and the chip select pin can be specified.

Note 2: the W5500 driver uses the “raw” mode, where all the socket handling is done by the library instead of the chip.

and the memory and CPU requirements to run LWIP?
a while ago a I tested it with Arduino SAMD21 boards and didn't work. It worked with Adafruit's SAMD51 boards.
and before that my W5500 port worked with Black Pill STM32 F411, but I think it would not work with Blue Pill STM32F103

I’m uncertain at the moment. I can do some builds and see what the representative sizes are. I don’t have much additional hardware.

It might help if you add links to any dependencies in the readme.md. Trying to compile for e.g. AVR boards is a nightmare (tried Ping and SimpleGttpClient). For the latter

In file included from C:\Users\bugge\AppData\Local\Temp\.arduinoIDE-unsaved2025118-12352-1rf5j5n.yrfr\SimpleHTTPClient\SimpleHTTPClient.ino:9:0:
c:\Users\bugge\OneDrive\Documents\Arduino\libraries\QNEthernet\src/QNEthernet.h:10:10: fatal error: cerrno: No such file or directory
 #include <cerrno>
          ^~~~~~~~
compilation terminated.
exit status 1

Compilation error: exit status 1

I'm not that familiar with libraries (except for using them) but when installing libraries in IDE 2.x one often gets a popup to allow the user to install the dependencies as well; you can consider that. E.g. in the library.properties file of the Adafruit SSD1306 library you can find depends=Adafruit GFX Library.

For sizes you don't need hardware; you can just install a platform package and needed libraries and compile.
For testing you do need it; I don't have ethernet hardware so can't test.

Thanks for that. You’ve inspired me to start a list of minimum requirements and to put that in the Readme:

  1. C++11
  2. [Determine minimum sizes] (see sentence prior to “I don’t have much additional hardware” :slight_smile:)

So far, the library doesn’t depend on anything else.

Note: cerrno is a standard C++ header.

It might be but not installed for AVR boards. avr-gcc uses C++ 11. So that might be the problem?
Same applies for ctime as used in SNTPClient.

So I think that at this moment the statement on https://docs.arduino.cc/libraries/qnethernet/ indicates that "it's compatible with all architectures" is a bit premature :wink: I think that it's automatically extracted from the following line in library.properties

architectures=*

There is also a problem with examples of one installs the library through library manager.
Values are mangled; e.g. from the SNTPClient example

// 01-Jan-1900 00:00:00 -> 01-Jan-1970 00:00:00
constexpr uint32_t kEpochDiff = 2'208'988'800;

// Epoch -> 07-Feb-2036 06:28:16
constexpr uint32_t kBreakTime = 2'085'978'496;

This does not happen if I install the zip (directly downloaded from github) using sketch ► include library → add zip library. I have no idea what is happening there.

When you install the library via Library Manager, you get the release version.

When you install it via the ZIP file downloaded from GitHub, you get the version from whichever Git ref you have selected on GitHub (the tip of the master branch by default).

The problem you noticed was fixed only recently:

That fix was made after the time of the latest release, so this is why you get the fix when you install the development version downloaded from GitHub, but not when you install the release version via Library Manager.

Thanks for that. I should have known, will try not to forget the next time.

The architectures property isn’t very useful a lot of the time. In short, sometimes architectures=* is the only valid option, even if not all architectures are supported.

An example of non-suitability: The Teensy platform, even though it’s based on ARM processors, uses AVR as its “declared architecture type”. I can’t use avr because that would indicate that a library is for AVR processors, which isn’t necessarily true.

I just did a few basic measurements with adafruit_feather_m4 and blackpill_f411ce (PlatformIO board names). I’m seeing usage of approximately 55Ki of flash and 3-10Ki of RAM, plus some heap. I didn’t dive in to see which optimization options were being used, but I’m using the defaults.

Hi,

I am using QNEthernet lib + Arduino Modbus TCP on Teensy board.
For some reason, the Modbus TCP client register read is very slow, about 250ms.

On another board with ESP8266 wifi, the read is about 20-30ms.

I do not know whether it is due to the small size of data packet, any flags in QNEthernet lib to reduce the lag?

Thanks.

Thank you for the question. Try calling flush() after sending data. Basically, data isn’t sent after write unless the buffer is full or a timer expires, about 250ms.

See also: QNEthernet/README.md at master · ssilverman/QNEthernet · GitHub (“Write immediacy” section)

Thanks for the quick reply. That makes a lot of sense. However, not sure how to fix in my code. This call modbusTCPClient.holdingRegisterRead() takes 250ms. To manually flush(), I need to somehow modify the modbusTCPClient library.

Is there anyway to reduce the timer to 30ms?

Thanks.

In that same Readme section, "Write immediacy", it mentions the QNETHERNET_FLUSH_AFTER_WRITE macro. Find qnethernet_opts.h in the QNEthernet library's source tree, and change that to 1 from 0. I think disabling Nagle's algorithm may help, but it might have less of an impact. That QNETHERNET_FLUSH_AFTER_WRITE solution isn't the preferred way, but it will enable you to work with libraries that can't be easily modified to flush after sending data.

Some more context: It’s next to impossible in the Arduino IDE to set build flags per project, unfortunately. In addition, Teensyduino doesn’t support the “Arduino way” platform.local.txt (without some changes, also outlined in the QNEthernet library’s Readme). But even if it did, there’s still no way that I know of to set per-project build settings.

I just released version 0.34.0.