Nano R4 and Ethernet?

Nano R4 and Ethernet?

Anyone aware of wired Ethernet options for Nano R4?

For our sensor controller need the Nano looks attractive as a controller because of its small physical size, low power requirements, QWIIC connector, and its 256kB RAM is probably enough to hold the sketch.

But, oops, cannot seem to find a wired Ethernet shield for the R4. Are there any options out there?

Anyone ever tried this: Mini ENC28J60 Ethernet Shield for Nano SPI Interface LAN Network Module from Dhgate Computer Cables & Connectors - price 4.69 ?

Thank you!

I have used the Mini ENC28J60 Ethernet Shield for Nano with a classic Nano and it works OK
I have not used an R4 but the pinout is designed to be compatible with previous Nano boards so probably worth trying it
I used the EthernetENC library with the classic Nano - no idea if it would work with the R4

if you are looking for a 32bit microcontroller dev board with Ethernet onboard have a look at the ESP32-S3 ETH Development Board with 10/100Mbps RJ45 Ethernet port

Better check the R4 library compatibility list before you buy anything.

1 Like

Hi Horace, The ESP32-S3 ETH looks pretty good, but I've no experience with it.
Would the Arduino IDE be used to program it?
Our sensor has a QWIIC connector. Would it be possible to use a QWIIC connection with the ESP32-S3 ETH?

TY!

yes - have a look at ESP32 Installing using Arduino IDE

there are kits on Amazon, Ebay, etc (search for QWIIC connector) to make up leads from QWIC connectors to Dupont connectors etc
photo of a ESP32-S3 ETH (powered using POE) connected to a BMP280 sensor

BMP280 data was sent over Ethernet using UDP datagrams to a Java program on a PC, e.g.

F:\Waveshare ESP32-S3 ETH Development Board\ESP32-S3-ETH-chat>java UDPchat
chat program: IP address BB-DELL2/192.168.1.65 port 10000
UDP datagram length 64  from IP /192.168.1.106 received:
BMP280 data
Temperature = 24.68 ?°C
Pressure    =  1016.52 hPa

UDP datagram length 64  from IP /192.168.1.106 received:
BMP280 data
Temperature = 24.72 ?°C
Pressure    =  1016.59 hPa

UDP datagram length 64  from IP /192.168.1.106 received:
BMP280 data
Temperature = 24.69 ?°C
Pressure    =  1016.51 hPa

UDP datagram length 64  from IP /192.168.1.106 received:
BMP280 data
Temperature = 24.70 ?°C
Pressure    =  1016.48 hPa

UDP datagram length 64  from IP /192.168.1.106 received:
BMP280 data
Temperature = 24.68 ?°C
Pressure    =  1016.48 hPa


Hi Horace, This looks like a great idea! Pls send a pic or list the pins used on the ESP32-S3 ETH. Could you have used QWIIC wire that has the QWIIC connector on one end and the four pins on the other end, rather than the four separate wires?

Also, look like there is a ribbon cable on your setup? What is it for?

Waveshare documentation is generally very good - see ESP32-S3-ETH WiKi which contains documentation on setting up the board and links to code, schematic, etc
the pin out is

one problem with complex dev boards is determining which GPIO pins are used - the schematic contains a list

showing the Ethernet W5500 GPIOs are 9, 10, 11, 12, 13 and 14
the pinout also shows that GPIOs 16 and 17 are available which are used in the following code for the I2C connection to the BMP280

// UDP chat program Waveshare ESP32-S3 ETH Development Board (W5500)
// **** change IP addresses and ports to suit requirements *****

#include <EthernetESP32.h>
#include <EthernetUdp.h>  // for UDP

// Define Waveshare ESP32-S3-ETHW5500 pin assignments
#define W5500_CS 14    // Chip Select pin
#define W5500_RST 9    // Reset pin
#define W5500_INT 10   // Interrupt pin
#define W5500_MISO 12  // MISO pin
#define W5500_MOSI 11  // MOSI pin
#define W5500_SCK 13   // Clock pin

// W5500Driver(int8_t cs = SS, int8_t irq = -1, int8_t rst = -1)
W5500Driver driver(W5500_CS, W5500_INT, W5500_RST);

// *****   IP of this machine and remote machine *********
IPAddress localIP(192, 168, 1, 174);  // local static localIP address
IPAddress remoteIP(192, 168, 1, 65);  // local static localIP address
unsigned int port = 10000;            // port to receive/transmit


// Enter a MAC address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAA };

unsigned int localPort = 10000;   // local port to listen on
unsigned int remotePort = 10000;  // remote port to transmiit too

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
SPIClass SPI1(SPI);

// BMP280 setup
#include <Wire.h>             // include Wire library, required for I2C devices
#include <Adafruit_Sensor.h>  // include Adafruit sensor library
#include <Adafruit_BMP280.h>  // include adafruit library for BMP280 sensor

// define device I2C address: 0x76 or 0x77 (0x77 is library default address)
#define BMP280_I2C_ADDRESS 0x76

Adafruit_BMP280 bmp280;

#define I2C_SDA 16
#define I2C_SCL 17


void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  delay(2000);
  Serial.println("\nWaveshare ESP32-S3 ETH Development Board (W5500) Ethernet UDP chat program");
  // Check for Ethernet hardware present
  // bool begin(int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, int8_t ss = -1);
  SPI1.begin(W5500_SCK, W5500_MISO, W5500_MOSI, W5500_CS);
  driver.setSPI(SPI1);
  Ethernet.init(driver);

  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac)) {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  } else {
    Serial.println("Failed to configure Ethernet using DHCP");
    Serial.print("\nDefault localIP");
    displayIPaddress(localIP, localPort);
    Serial.println("Failed to configure Ethernet using DHCP - using static IP");
    getIPaddress("local IP address (<return> use default)? ", localIP, localPort);
    Ethernet.begin(mac, localIP);  // static IP initialize Ethernet shield
  }
  Serial.print("My localIP address: ");  // print local localIP address:
  displayIPaddress(Ethernet.localIP(), localPort);
  // Initializes the ethernet UDP library and network settings.
  if (Udp.begin(port)) Serial.println("UDP begin() OK");
  else Serial.println("UDP begin() failed!");

  // get remote IP and port
  Serial.print("\nDefault remoteIP ");
  displayIPaddress(remoteIP, remotePort);
  //getIPaddress("remote IP address (<return> use default)? ", remoteIP, remotePort);
  Serial.print("\nRemote ");
  displayIPaddress(remoteIP, remotePort);

  // initialize BMP280
  Wire.begin(I2C_SDA, I2C_SCL);
  Serial.println(F("Arduino + BMP280"));
  if (!bmp280.begin(BMP280_I2C_ADDRESS)) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1)
      ;
  }
  Serial.println("Found BMP280 sensor!");
}

void loop() {
  char text[100] = { 0 };
  // get temperature, pressure and altitude from library
  float temperature = bmp280.readTemperature();    // get temperature
  float pressure = bmp280.readPressure();          // get pressure
  float altitude_ = bmp280.readAltitude(1013.25);  // get altitude (this should be adjusted to your local forecast)
  // print data on the serial monitor software
  // 1: print temperature
  sprintf(text, "\nBMP280 data\nTemperature = %.2f °C\nPressure    =  %.2f hPa\n",
          temperature, pressure / 100);

  Serial.println(text);                   // start a new line
  Udp.beginPacket(remoteIP, remotePort);  // transmit datagram
  Udp.print(text);
  Udp.endPacket();
  delay(2000);  // wait 2 seconds

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    displayIPaddress(Udp.remoteIP(), Udp.remotePort());
    // read the packet into packetBuffer
    char packetBuffer[100] = { 0 };      // buffer to hold incoming packet,
    Udp.read(packetBuffer, packetSize);  //UDP_TX_PACKET_MAX_SIZE);     // receive datagram
    Serial.print("Contents: ");
    Serial.println(packetBuffer);
    // if (strcmp(packetBuffer, "OK") != 0) {

    // send a reply to the IP address and port that sent us the packet we received
    //   Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    // Udp.write("OK");
    //  Udp.endPacket();
    //}
  }
  delay(10);
}


// read IP address and port from keyboard and check it
void getIPaddress(const char* prompt, IPAddress& defaultIP, unsigned int& defaultPort) {
  IPAddress ip;
  while (1) {  // read  IP (end with new line)
    char text[40] = { 0 };
    Serial.print(prompt);  // prompt and wait for input
    while (Serial.available() == 0) delay(10);
    Serial.readBytesUntil('\n', (char*)text, 40);
    for (int i = 0; i < 40; i++)  // convert IP address
      if (text[i] < ' ') text[i] = 0;
    if (text[0] == 0) return;  // ig just <enter> return  defaultIP;
    //Serial.println(text);
    if (ip.fromString(text)) break;  // if IP OK break while
    Serial.println("\ninvalid IP try again");
  }
  char text[40] = { 0 };
  // read port number
  while (Serial.available()) Serial.read();
  defaultIP = ip;
  Serial.print("\nport ? ");  // prompt and wait for input
  while (Serial.available() == 0) delay(10);
  Serial.readBytesUntil('\n', (char*)text, 40);  // read value
  sscanf(text, "%u", &defaultPort);              // convert value
}

// print IPAdress and port
void displayIPaddress(const IPAddress address, unsigned int port) {
  Serial.print(" IP ");
  Serial.print(address);
  Serial.print(" port ");
  Serial.println(port);
}

the BMP280 did not have a QWIIC connector just pins which I plugged into the breadboard and use DuPont jumper leads to connect to the ESP32S3
you can find ready made QWIIC leads on Amazon, Ebay, etc or use a kit as suggested in my previous post

the ribbon cable is to the OV5640 camera - if you don't require the camera don't install it
the photo of the ESP32S3 ETC board also had the POE module installed - if you don't require POE don't install it

POE is a great thing. I find it useful for all kinds of needs (much better than wall transformers or batteries for many use cases). TY!

TY Horace for all this great info. Really useful. It seems that the ESP32S3 is going to be a better platform for our needs than the Arduini Nano R4 (mainly because there is not a readily available wired Ethernet solution for the R4). Also, the Nano solution required a POE splitter, making one less component with the ESP32S3. TY!

reducing the number of individual modules is a good idea - less to go wrong and reducing interconnection wiring etc

which protocol are you planning to use? e.g. a onboard web server, custom TCP or UDP server/client, etc?
the Waveshare ESP32S3 ETH WiKi has a number of demo programs and there are plenty of example programs for the W5500 online

Sure, just about any W5500 module will work

Hi Horace, The [ESP32-S3 ETH Development Board with 10/100Mbps RJ45 Ethernet port + PoE module] has arrived. Getting it to communicate with the Arduino IDE (Windows 11 with IDE 2.3.7) is proving to be a challenge. The IDE can get the board info, but no luck uploading a sketch. What entry from the Boards Manager do you use for this microcontroller?

Thanks for this suggestion! I've switched over to trying to use MCU ESP32-S3 with a PoE module. Have you experience with the ESP32-S3 MCUs ( Amazon.com: ESP32-S3 Ethernet Development Board, 10/100Mbps RJ45 ETH Port, 240MHz Dual Core Processor, Onboard Type-C Port & TF Card Slot, Support WiFi & BLE & Ethernet Communication, with POE Module : Electronics

select Tools>Board ESP32S3 Dev Module and USB CDC on boot "Enabled"

try this example

// Waveshare example ETH_DHCP
// select Tools>Board ESP32S3 Dev Module
// and USB CDC on boot "Enabled"

/**
 ******************************************************************************
 * @file     ETH_DHCP.ino
 * @brief    Initialize W5500 Ethernet module using DHCP and print the IP address.
 * @version  V1.0
 * @date     2025-07-03
 * @license  MIT
 * @copyright Copyright (c) 2025, Waveshare Electronics CO.,LTD
 *
 * Experiment Objective:
 * Demonstrate how to initialize the W5500 Ethernet module on an Arduino-compatible 
 * board using DHCP, and display the assigned IP address through the serial console.
 *
 * Hardware Resources:
 * 1. ESP32-S3-ETH
 *
 * Experiment Phenomenon:
 * 1. The W5500 Ethernet module is initialized via SPI.
 * 2. The module attempts to obtain an IP address via DHCP.
 * 3. Upon success, the assigned IP address is printed to the serial console.
 *
 * Notes:
 * - Ensure the W5500 module is properly connected with matching SPI pins.
 * - The MAC address can be modified based on network requirements.
 *
 ******************************************************************************
 *
 * Development Platform: Arduino IDE 
 * Support Forum: service.waveshare.com
 * Company Website: www.waveshare.com
 *
 ******************************************************************************
 */

#include <SPI.h>
#include <Ethernet.h>

// Define W5500 pin assignments
#define W5500_CS    14  // Chip Select pin
#define W5500_RST    9  // Reset pin
#define W5500_INT   10  // Interrupt pin
#define W5500_MISO  12  // MISO pin
#define W5500_MOSI  11  // MOSI pin
#define W5500_SCK   13  // Clock pin

// MAC address (can be arbitrary or set according to network requirements)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAA };

EthernetClient client;

void setup() {
  Serial.begin(115200);  // Start serial communication
  while (!Serial) {
    ; // Wait for the serial port to be ready
  }
  delay(2000);
  Serial.println("Waveshare ESP32-S3 ETH Development Board\nusing DHCP");

  // Initialize SPI with specified pin configuration
  SPI.begin(W5500_SCK, W5500_MISO, W5500_MOSI, W5500_CS);

  // Initialize Ethernet using DHCP to obtain an IP address
  Ethernet.init(W5500_CS);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    while (true); // Halt if DHCP configuration fails
  }

  // Print the assigned IP address
  Serial.print("IP Address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  delay(1000); // Wait for 1 second
}

the serial monitor displays

Waveshare ESP32-S3 ETH Development Board
using DHCP
IP Address: 192.168.1.64

and it appears on the routers list of devices

and testing with ping

PS C:\> ping 192.168.1.64

Pinging 192.168.1.64 with 32 bytes of data:
Reply from 192.168.1.64: bytes=32 time=2ms TTL=128
Reply from 192.168.1.64: bytes=32 time=1ms TTL=128
Reply from 192.168.1.64: bytes=32 time=1ms TTL=128
Reply from 192.168.1.64: bytes=32 time=1ms TTL=128

Ping statistics for 192.168.1.64:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 1ms, Maximum = 2ms, Average = 1ms

Here is the Tools->USB Mode option on this version of the IDE (Windows 11 IDE 2.3.7), looks like the choice closest to you recomendation USB CDC on boot "Enabled" ?

Ever since switching from the Nano R4 to this Waveshare ESP32-S3-POE-ETH (supposedly a Nano ESP32 equivalent) this message appears when attempting to upload sketch from Adruino IDE

No DFU capable USB device available
Failed uploading: uploading error: exit status 74

So far, no joy from searching the internet for resolution...

TY in advance for any thoughts :slightly_smiling_face:

try using Tools>Board select ESP32S3 Dev Module then USB CDC on boot "Enabled"

Well, the Tools menu on this end looks different. There is a screen shot of it a few posts back. What ver of IDE is on your end?