Hello friends, I hope you all are doing great. Today, I am going to share the ENC28J60 Ethernet Module Library for Proteus. The ENC28J60 module is the cheapest way to put an Arduino on a wired network: a small blue board with a Microchip ENC28J60 Ethernet controller, a HanRun RJ45 jack and a 2x5 header. Unlike the WIZnet boards, the ENC28J60 knows nothing about TCP or IP - it only sends and receives Ethernet frames. The TCP/IP stack runs on the Arduino itself, inside the EthernetENC library. With this library you can wire the module to your UNO in Proteus, run EthernetENC sketches unchanged and watch every frame go by.
ENC28J60 Ethernet Module Library for Proteus
Latest version: V1.0 (October 2026, this tutorial)
Other Ethernet libraries: Ethernet Shield · Ethernet Shield 2 · W5500 Module · W5100 Module · ENC28J60 Nano Shield · Ethernet Rev3 · LAN8720 Module · WT32-ETH01 · USR-TCP232-T2
Modules: Micro SD · MAX485 RS485 · MCP2515 CAN · DS3231 RTC · DFPlayer Mini
Arduino boards: UNO · Mega 2560 · Mega 1280 · Nano · Pro Mini · Mini (V4.0)
Helping Tools
- Laptop WiFi Monitor: a laptop on the Wi-Fi of your design: a browser, a TCP / UDP terminal and ping
- Mobile WiFi Monitor: a smartphone that opens the pages of your board and sends it commands
- Serial Monitor Advance: a serial terminal window for the UART of your board
This is the thirty-second library of our Wi-Fi / Ethernet series and the fifth of its Ethernet group. Its demo is the classic ENC28J60 project: a web server on a fixed address that switches an LED and shows a reading, opened from our Laptop WiFi Monitor and Mobile WiFi Monitor - and pinged, and tested with a broadcast the chip refuses.
NOTICE: the PANEL pad, the panel and the virtual router are TEP additions; the CLKOUT clock and wake-on-LAN are not simulated (see the limits at the end). The module works with the EthernetENC library. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the ENC28J60 Ethernet Module board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the ENC28J60 Ethernet Module Library for Proteus:
What is the ENC28J60 Ethernet Module?
The ENC28J60 is a stand-alone Ethernet controller from Microchip: a 10 Mbit/s MAC and PHY with an 8 KB packet buffer, driven over SPI. The module puts it on a blue board with a 25 MHz crystal, a HanRun RJ45 MagJack (the transformer and two LEDs inside the socket) and a 2x5 header. It runs from 3.3 V; its inputs take 5 V logic, so it connects straight to an UNO's SPI pins.
| Real ENC28J60 module | This library in Proteus | |
|---|---|---|
| Chip | Microchip ENC28J60, 10 Mbit/s, 8 KB buffer | our model of the ENC28J60, register by register |
| Link | SPI: SCK, SI, SO, CS | the same pins, named beside their ends |
| Other pins | RESET, INT, WOL, CLKOUT, VCC, GND | the same; RESET resets the chip, INT works |
| TCP/IP | on the Arduino (uIP in EthernetENC) | the same - the library's own stack, unchanged |
| Arduino library | EthernetENC (Library Manager) | the same library, unchanged (2.0.5 in the demo) |
| Network | an RJ45 cable to your router | a virtual cable to our router, shared with our Wi-Fi parts |
| LEDs | two on the jack | the same two, plus a PWR LED |
The Pins of the Module
Wire by the names printed beside the pins - makers order the 2x5 header differently. SCK goes to D13, SI (the chip's data in) to MOSI on D11 and SO (its data out) to MISO on D12. CS goes to D10 unless the sketch names another pin with Ethernet.init(). RESET resets the chip while it is LOW and may stay free. INT goes LOW while the chip has something to report, WOL is the wake-on-LAN output and CLKOUT a clock output - EthernetENC uses none of the three. VCC takes 3.3 V and GND closes the circuit.
Where Does the TCP/IP Stack Run?
This is the big difference from the WIZnet modules of our W5500 Ethernet Module Library for Proteus and W5100 Ethernet Module Library for Proteus. A WIZnet chip has the whole TCP/IP stack inside: the sketch opens a socket and the chip handles ARP, the handshakes and the retries. The ENC28J60 does none of that. EthernetENC carries uIP, a tiny TCP/IP stack, and runs it on the UNO: every ARP answer, every TCP acknowledgement and every ping reply is built by the Arduino and written into the chip's buffer over SPI. Two things follow. The stack only runs while the sketch calls the library - with a long delay() in the loop, nothing answers, not even a ping. And it costs flash and RAM: the demo takes 21,170 bytes of flash and 1,036 bytes of RAM. In return the module is cheap, and the frames are all there to see - our panel lists each one.
Features of the ENC28J60 Ethernet Module Library for Proteus
- The module as it looks: the blue board with the HanRun RJ45 jack and its two LEDs, the ENC28J60 in its SOIC-28 and its crystal, a red PWR LED and the 2x5 header; every pin named beside its end.
- The real EthernetENC library: our ENC28J60 answers the library exactly as the chip does - the SPI instructions, the register banks, the buffer, the receive ring and the filters. We ran EthernetENC 2.0.5 with the demo (19 checks) and with a client sketch (7 checks) against the model on the PC, and in Proteus.
- A real frame-level network: ARP, DHCP, DNS, NTP, ping, UDP and TCP travel as Ethernet frames between the Arduino's stack and the rest of the network.
- The ENC28J60's filter: EthernetENC lets only ARP broadcasts in - a UDP broadcast is dropped, as on the real module, and the panel says so.
- A fixed address found by ARP: the LAN asks "who has 192.168.1.60?" when somebody looks for it, and the Arduino's stack answers.
- The link:
Ethernet.linkStatus()reads the PHY - LinkON with the cable in, LinkOFF with it out. - The jack's LEDs as the sketch sets them: EthernetENC writes PHLCON so the green LED shows the link and the yellow one the traffic; the model follows PHLCON.
- The cable: pull it with a click on the jack, the CABLE property or the panel.
- Our Laptop and Mobile WiFi Monitors: a laptop and a phone on the same network, with browsers, terminals and ping - included in the package.
- Our pop-up panel: the phone, the module card, an ETHERNET card, an SPI page with every frame explained, the RESET and INT pins, a Test page, Settings and Help - with our TEP header, not a Windows title bar.
- A compact package: about 3.03 MB, without the C++ source code of the models.
The ENC28J60 Ethernet Module in Proteus
Search ENC28J60 in Pick Devices; the device ENC28J60 ETHERNET MODULE is in TEPENC28J60.LIB. Click the PANEL pad or the ENC28J60 to open the panel, and the RJ45 jack to pull or plug the cable.
Every State of the ENC28J60 Module
We ran the demo and paused the simulation for each picture. First EthernetENC resets the chip, sets its filters, the MAC and the LEDs, and reads its revision - the chip is found 0.12 s after Run:
Download ENC28J60 Ethernet Module Library for Proteus
Click the button below to download ENC28J60-Ethernet-Module-Library-for-Proteus-v1.0.zip (about 3.03 MB, without the C++ source code of the models):
ENC28J60 Ethernet Module Library for Proteus V1.0- README.txt: the device, installation, the demo, the pins, the properties, troubleshooting and the limits.
- Proteus Library Files:
TEPENC28J60.LIB(the module),ArduinoV4TEP.LIB(our Arduino boards V4.0 - the UNO of the demo),TEPLAPTOP.LIBandTEPMOBILE.LIB(our Laptop and Mobile WiFi Monitors). - Proteus Model Files:
TEPNET.DLL(the module, the two monitors and the network) andTEPARDUINO.DLL(the Arduino boards). - Proteus Simulation: the demo project, its HEX file and copies of the DLLs.
- Arduino Code: the demo sketch. The EthernetENC library is not included - install it with the Library Manager.
No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.
How to Install ENC28J60 Ethernet Module Library for Proteus
- Close Proteus and extract the whole zip file, for example to your Desktop.
- Copy the four files from Proteus Library Files into the LIBRARY folder of Proteus (usually
C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY). - Copy
TEPNET.DLLandTEPARDUINO.DLLfrom Proteus Model Files into the MODELS folder - replace older copies (this TEPNET.DLL is the first one that knows the ENC28J60, and it still runs our W5100 and W5500 modules, our Ethernet shields, every Wi-Fi part of the series and the two monitors). - Delete
TEPENC28J60.IDX,ArduinoV4TEP.IDX,TEPLAPTOP.IDXandTEPMOBILE.IDXfrom the LIBRARY folder if they are there. - Start Proteus, press P and search for ENC28J60.
For your own sketches, install EthernetENC in the Arduino IDE (Sketch > Include Library > Manage Libraries, search "EthernetENC") and include EthernetENC.h instead of Ethernet.h - the functions are the same. Then use Sketch > Export Compiled Binary, double-click the UNO in Proteus and set its Program File to the HEX (see How to get the HEX file from Arduino).
Demo: A Web Server with an LED
Open ENC28J60-Web-Server-with-Laptop-and-Mobile.pdsprj. On the left is our UNO V4.0 (ARD1, from our Arduino UNO Library for Proteus V4.0) with its built-in serial monitor, a pot on A0 and an LED on D7, in the middle the ENC28J60 module (U1), and on the right the laptop (PC1) and the phone (MOB1) - no wires to them, they are on the router's network like the real ones.
Four net labels make the SPI connections: SCK, MISO and MOSI from D13, D12 and D11 to SCK, SO and SI, and ETH_CS from D10 to CS. The module's VCC goes to a +3.3V terminal and its GND to ground; RESET, INT, WOL and CLKOUT stay free. R1 (220R) and the LED D1 hang on D7, and RV1 (10k, at 35 %) on A0 gives the reading on the page:
The two tools come from our Laptop WiFi Monitor Library for Proteus and Mobile WiFi Monitor Library for Proteus. In this project both open http://192.168.1.60/ as their home page, the laptop's ping box holds 192.168.1.60 and its UDP terminal listens on port 4210; the laptop is 192.168.1.21 and the phone 192.168.1.41:
The Sketch: EthernetENC and a Fixed Address
The sketch includes EthernetENC instead of the Arduino Ethernet library - that is the only change an Ethernet sketch needs. A MAC address, the fixed IP address and the LED pin follow, and a server on port 80:
#include <SPI.h>
#include <EthernetENC.h>
const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x28, 0x60};
const IPAddress ip(192, 168, 1, 60);
const byte LED_PIN = 7;
EthernetServer server(80);
Ethernet.init() names the chip select pin and Ethernet.begin(mac, ip) starts the chip and the stack with the fixed address - no DHCP, so nothing goes on the wire yet. Ethernet.hardwareStatus() tells whether EthernetENC found the chip:
Ethernet.init(10);
Ethernet.begin(mac, ip);
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println(F("No ENC28J60 found - check SCK, SO, SI, CS and the 3.3V supply"));
while (true) {}
}
Then the sketch reads the link - the ENC28J60 has a PHY register for it, so this works, unlike on a W5100 - and starts the server. Press Run and watch the UNO's monitor:
Serial.println(Ethernet.linkStatus() == LinkON ? F("ON") : F("OFF - is the cable in?"));
server.begin();
ENC28J60 Web Server
Chip: ENC28J60 (EthernetENC: the TCP/IP stack runs on the UNO)
Link: ON
Fixed IP: 192.168.1.60
Web page: http://192.168.1.60/ (JSON: /json)
A Fixed Address and ARP
Look at the panel now. The module is linked and running, but the router has no address for it - the panel says "no address seen yet". That is right: with a fixed address and no DHCP, the UNO has said nothing on the network, so nobody knows where 192.168.1.60 is:
A real network finds a device with ARP: before the first packet to an address, the sender asks everybody "who has 192.168.1.60?" and the owner answers with its MAC address. The ENC28J60 lets ARP broadcasts in, and the UNO's stack answers. So open the laptop's Browser and press Go - the LAN asks, the UNO answers, the page comes:
The SPI page of the panel shows it frame by frame - newest first. Read it from the bottom: EthernetENC's system reset, the filters, the MAC, the PHY, receive on, the LEDs, the revision; then at 5.42 s the LAN's ARP request, the UNO's answer, and the laptop's TCP connection - SYN, SYN-ACK with a maximum segment of 512 bytes, the request, the FIN:
The Request and the Page
loop() does two things: server.available() hands over a client with a request waiting, and the monitor is read. Calling server.available() on every loop is also what keeps uIP running - it is where EthernetENC reads the chip and answers ARP, pings and TCP:
void loop() {
EthernetClient client = server.available();
if (client) serve(client);
monitor();
}
serve() keeps the first line of the request ("GET /on HTTP/1.1") and reads the headers up to the blank line that ends them:
while (client.connected() && millis() - t0 < 2000) {
if (!client.available()) continue;
const char c = client.read();
if (first) {
if (c == '\n') first = false;
else if (c != '\r' && n < sizeof(req) - 1) req[n++] = c;
}
if (c == '\n' && blank) break;
if (c == '\n') blank = true;
else if (c != '\r') blank = false;
}
The path sits between the two spaces of that line. The sketch prints it with the address of the client, from client.remoteIP():
char* path = strchr(req, ' ');
if (path) { ++path; char* end = strchr(path, ' '); if (end) *end = 0; } else path = req;
Serial.print(F("GET "));
Serial.print(path);
Serial.print(F(" from "));
Serial.println(client.remoteIP());
Then the page: a title, the state of the LED, two links and the reading. The voltage is worked out in whole millivolts, rounded:
client.println(F("</p><p><a href=\"/on\">LED ON</a> <a href=\"/off\">LED OFF</a></p>"));
const long mv = ((long)a0 * 5000L + 511L) / 1023L; // (rounded to the millivolt)
client.stop() closes the connection after a short pause - the browser knows the page is complete:
delay(1);
client.stop();
The phone opens the same page from its own Browser:
Switching the LED
The two links are /on and /off. The sketch compares the path and switches the LED, telling the monitor why:
if (!strcmp(path, "/on")) setLed(true, F("the web page"));
else if (!strcmp(path, "/off")) setLed(false, F("the web page"));
void setLed(bool on, const __FlashStringHelper* why) {
ledOn = on;
digitalWrite(LED_PIN, on ? HIGH : LOW);
Tap LED ON on the phone. The page comes back with the new state, the monitor logs the request, and D1 lights up on the sheet:
GET / from 192.168.1.21
GET / from 192.168.1.41
GET /on from 192.168.1.41
LED ON (the web page)
JSON for Programs
A page is for people. For a program - a script on a PC, another board - the sketch answers /json with the same data in one line:
if (!strcmp(path, "/json")) {
client.println(F("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nConnection: close\r\n"));
client.print(F("{\"led\":"));
Type http://192.168.1.60/json in the laptop's browser:
{"led":1,"a0":358,"volts":1.75,"requests":5,"uptime":15}
Ping: the UNO Answers
Open the laptop's Network tab: the module is listed as ENC28J60 Module U1 at 192.168.1.60. Press Ping. Each echo request travels as a frame into the ENC28J60, and the reply is built by uIP on the UNO:
Pinging 192.168.1.60:
Reply from 192.168.1.60: bytes=32 time=7ms TTL=128
Reply from 192.168.1.60: bytes=32 time=7ms TTL=128
Reply from 192.168.1.60: bytes=32 time=7ms TTL=128
Reply from 192.168.1.60: bytes=32 time=7ms TTL=128
Packets: sent = 4, received = 4, lost = 0 (0% loss)
Look at the TTL: 128, the value the laptop put in its request. uIP does not build a new packet for an echo reply - it swaps the addresses and sends the request back, TTL included. A small thing, but it shows the answer really comes from the stack on the Arduino.
Broadcasts and the Receive Filter
The ENC28J60 decides which frames reach its buffer with its receive filters. EthernetENC switches on two: frames sent to the module's own MAC address, and a pattern match that lets in broadcasts that are ARP requests - nothing else that goes to everybody. It saves the UNO from reading every broadcast on a busy network. Try it: in the laptop's Terminal (UDP mode, port 4210) type a line and press Send - it goes to the broadcast address 192.168.1.255:
The panel's SPI page shows what happened to it:
This is a real difference from our W5100 and W5500 modules, which take broadcasts. If an ENC28J60 project must hear the others, send to its own address instead.
The Monitor's Commands
The sketch also reads the UNO's monitor: ON and OFF switch the LED, STATUS prints the address, the link, the LED, A0 and the request count, anything else prints the list:
else if (!strcmp(line, "STATUS")) status();
OFF
LED OFF (the monitor)
STATUS
IP 192.168.1.60, link ON, LED OFF, A0=358, requests 5
HELP
Commands: ON, OFF, STATUS, HELP
The ENC28J60 Ethernet Module Panel
The panel opens at Run, in the look of our TEP Serial Monitor Advance for Proteus - our own TEP header, no Windows title bar. Its first page has a small phone of its own with the CABLE IN and CABLE OUT buttons, and three cards: MODULE with the chip, the MAC address, the frame count and the LEDs as PHLCON sets them, ETHERNET with the router, the status, the address and the receive filter, and TRAFFIC:
OPEN MODULE PAGE lets the panel's own phone open the page the Arduino serves:
The ROUTER tab lists the router's clients, the module among them as a LAN client:
The Test page measures the running model: the web request test lets the panel's phone open the page three times, and the cable test pulls the cable for 3 seconds, three times:
After the cable test the laptop opens the page again, and the SPI page shows the new connections:
The footer counts the register accesses - EthernetENC reads the chip's packet counter all the time, about 75,000 register accesses a second of simulation while it waits. That is the price of a stack on the UNO, and the reason the simulation runs below real time.
Pins of the ENC28J60 Ethernet Module
| Pin | Demo wiring | What it does |
|---|---|---|
| VCC 3.3V | +3.3V | power: 3.3 V (5 V would damage a real ENC28J60) |
| GND | ground | ground |
| CS | D10 | chip select (LOW = selected) |
| SCK, SI, SO | D13, D11, D12 | SPI; SI is MOSI, SO is MISO and floats while CS is HIGH |
| RESET | free | LOW holds the ENC28J60 in reset; free or HIGH = running |
| INT | free | LOW while an enabled interrupt flag is up |
| WOL, CLKOUT | free | wake-on-LAN output (HIGH) and the clock output (not driven) |
Properties of the ENC28J60 Ethernet Module
| Property | What it does |
|---|---|
| ROUTER | the router the cable goes to - the network name of the Wi-Fi parts (TEP-WiFi) |
| CABLE | the Ethernet cable at Run: IN or OUT |
| PANEL | the phone's tab at start (BROWSER, ROUTER, CLOUD) |
| PAGEPORT | the port OPEN MODULE PAGE opens (80) |
| CLOCK | the clock of NTP and the panel: PC (UTC) or a start time |
With DHCP (Ethernet.begin(mac)) the address follows the part's number: U1 gets 192.168.1.101, U2 .102 and so on - the router answers EthernetENC's DHCP with unicast frames, as it asks. The laptop is always 192.168.1.21 and the phone 192.168.1.41.
Troubleshooting
- The hardware status is EthernetNoHardware: check SCK, SO, SI, CS (and
Ethernet.init()when it is not D10), VCC and GND, and that RESET is not held LOW. - The page never opens: the sketch must call the library often -
server.available()in every loop. With a longdelay()nothing answers, not even ARP or a ping. - A fixed address is "not seen yet": that is normal until somebody looks for it - open the page or ping it.
- DHCP never answers: the cable is out - the panel shows CABLE OUT and
Ethernet.linkStatus()is LinkOFF. Put it in with the panel, or click the RJ45 jack. - A UDP broadcast never arrives: EthernetENC's filter drops broadcasts - send to the module's address.
- No panel: click the PANEL pad or the ENC28J60, or turn "Open the panel at Run" back on in Settings.
Things to Know Before Using a Real ENC28J60 Module
- Power: the module runs from 3.3 V and has no regulator. The ENC28J60 draws well over 100 mA while it sends, more than the 3.3 V pin of many Arduino boards is meant to give - use a separate 3.3 V regulator for a real build. It also runs warm, which is normal.
- The header: makers order the 2x5 pins differently - always wire by the names printed on your board.
- The MAC address: the module has none of its own; give each module on the network a different one in the sketch.
- 10 Mbit/s: the ENC28J60 is a 10BASE-T part. Any modern switch or router port talks to it, but it is slower than the WIZnet chips - plenty for a page, a reading or a command.
- Flash and RAM: the stack lives in the sketch. The demo takes 21,170 of the UNO's 32,256 bytes of flash and 1,036 of its 2,048 bytes of RAM - a bigger project may need a Mega, or a WIZnet module.
- Keep the loop busy: the stack only runs when the sketch calls the library; avoid long
delay()calls.
Limitations of the Simulation
- The ENC28J60 is our model of the chip as EthernetENC (2.0) uses it: the SPI instructions, the register banks, the buffer, the receive filters and the PHY registers that matter for the link and the LEDs.
- Not modelled: the CLKOUT clock, wake-on-LAN, collisions and flow control frames, power-save timing, the supply's voltage and current.
- The far end of each TCP connection is ours: it sends one segment at a time; with the cable out the connections are kept for 20 s - our choice, close to what a real network does for a short pull.
- The PANEL pad, the panel, its phone, the router, the internet host and the two monitors are TEP additions.
- ENC28J60 is a name of Microchip; this library is not made or endorsed by Microchip or Labcenter.
- Tested in Proteus 8.5 in October 2026 (the demo as shipped, the UNO, the module, the laptop and the phone together at about 0.25 to 0.35 x real time on our PC). Proteus 7 is not supported.
So, that was all about the ENC28J60 Ethernet Module Library for Proteus. I hope it helps you build and test ENC28J60 projects in Proteus before you solder anything - and see what happens under the hood when the TCP/IP stack runs on the Arduino: the ARP questions, the handshakes, the filter that drops a broadcast. The cable goes to the same router as our Wi-Fi boards and WIZnet modules, so they can all share one design. If you use the ENC28J60 Ethernet Module Library for Proteus in a project, please share it in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!