Connect an ENC28J60 Ethernet module to an Arduino or a Raspberry Pi

Update 2017: As prices on the W5100 and W5500 modules and shields have also dropped considerably, choosing the W5100 or W5500 is often the better option. However, the W5100 modules can be a bit fiddly to use. Check out how to deal with some of the problems here.
Update 2018: The cheapest ENC28J60 board I now could find is 2.25 Euro, the cheapest W5500 is 2.70 euro.

With prices of ENC28J60 Ethernet modules coming down drastically with some as low as 4,60 euro, (even cheaper here much cheaper even here), buying one of these to connect barebones Arduino projects to the web becomes more and more attractive.  The ENC28J60 has astandard SPI interface. With the official ENC28J60 Ethershield and Ethercard, just sticking it in  the Arduino is easy and takes care of the proper connections, but with one of these modules, we need to make these connections ourselves. Though the Vcc is 3.3 Volt, the datasheet states the I/O  pins to be 5 V tolerant, which makes it easy to interface with the 5 Volt Arduino. The datasheet (blz. 10) shows that a level-shifter is recommended for the WOL (WakeOnLan), the interrupt and the chip’s MISO. However, this is a general recommendation, because  the manufacturer does not know to what MCU you plan to connect the ENC28J60. For use with the Arduino the levelshifter is not necessary. So we just can make the following hardware SPI connections:

ENC28J60 Arduino
SO D12 (MOSI)
SI D11 (MISO)
SCK D13 (SCK)
CS D8 (or D10, read further) SS
VCC  Separate 3V3
GND GND

Should you for any reason decide to use levelshifters, they need to be tri-state, to ensure proper SPI functioning when sharing the bus.

For the ENC28J60 chip/module, there are several Arduino libraries available: Ethershield (development has stopped) and Ethercard (the newest). There is also the UIPEthernet from Norbert Truchsess, that is compatible to the W5100 Ethernet library. To be clear:  the Ethernet library is for the WIZ5100 ethernetshield, using the UIPEthernet library makes (most of) the WIZ5100 based programs suitable for the ENC28J60.

(Update: The Ethershield Library is no longer compatible with the Arduino IDE as the “prog_char” deftype is deprecated. Although it is simple to modify the various library files, you need to ask yourself if that is worth the trouble, as there are more modern libraries. If you still want to do it:Replace prog_char with const char, and do the same for other prog_”datatype” typedefs. If there is a PROGMEM const char *string_table[] =, replace with PGM_P const string_table[]  PROGMEM =)

A note on the Chipselect CS
The use of the proper CS pin is depending on what library one uses for the ENC28J60.
there are defacto three libraries:

  • The Ethershield library uses pin 10 as a chipselect
  • The EtherCard library uses pin 8 as a chipselect
  • The UUPEthernet library uses pin 10 as a chipselect

The reason for this change from 10 to 8  is to be able to use the Ethercard together with an SD card.

If you buy a module, rather than a shield, it is very easy to determine what chipselect pin you want to use. If you use the older EtherShield library, use pin 10 as CS, if you use the somewhat newer Ethercard library, use  pin 8.

If for whatever reason you want to use the Ethercard library with pin 10, change the pin assignment in the library files ENC28J60.h (line 25 and 41 I believe)   and the EtherCard.h  (Line 134: uint8_t csPin = 8 ). (Depending on the version it can also be in line 154.)

Screenshot from 2013-10-01 17:15:11

It is also possible to add the declaration for pin 10 in the program itself like this:

ether.begin(sizeof Ethernet::buffer, mymac, 10)

This card works with a Mega2650 if you override the CS pin in the sketch. The pin mapping is –

ENC28J60 Mega2650
SO 50 (MISO)
SI 51 (MOSI)
SCK 52 (SCK)
CS 53 (SS)

In the sketch you need to override the begin with ether.begin(sizeof Ethernet::buffer, mymac, 53) (note the 53) because the default is for pin 8 on a UNO. If you use another pin for the CS you will need to manually set pin 53 as an output or SPI doesn’t work.

The RST and INT pin can be connected as follows but it is not strictly necessary

ENC28J60 UNO Mega
Vcc 3V3 3V3
RST RST RST
INT 2 2
GND GND GND
SCK D13 D52
SO 12 50
SI 11 51
CS 10 53
CLKout
WOL

Similar info here

Good info here as well.
Much info on use of the ENC28J60 can be found in Luca Dentella’s blog

Adding the ENC28J60 to a Raspberry Pi

You may wonder why anybody would want to do that, but a good reason would be if you blow up your ethernetport on your Rapberry B or…… if you have a Raspberry Zero or Zero W. True, you could add WiFi to the first one via a USB dongle, sure, but if you want Ethernet, this is how you do it.

 

ENC28J60 Raspi BCM pins Raspi Physical pins
INT 25 22
SO 9 (MISO) 21
SCK 11 (SCLK) 23
SI 10 (MOSI) 19
CS 8 (CE0) 24

As there sometimes is confusion about the numbering of the pins I added the physical numbers of the pins as well as the BCM numbers

Obviously you connect ground to ground and the Vcc to a suitable source. If your ENC28J60 module has a 5Volt entrance (followed by a 3V3 regulator) you can connect it to the 5V pin of the raspberry.
If the module needs  3V3 on the Vcc, you could try and feed it from the 3v3 pin of the raspberry, but the current draw is a bit outside the specs of the raspberry. In that case it might be wise to add a small 3v3 LDO and feed it from the 5Volt line.

Once you have done that you need to enable SPI on the raspberry. You do that via the raspi-config utility or via Menu > Preferences > Raspberry Pi Configuration> Interfaces tab on the desktop. You could also just uncomment the line dtparam=spi=on in your /boot/config.txt file

Then add the following to your /boot/config.txt

dtoverlay=enc28j60

reboot and then your Ethernet should work

59 thoughts on “Connect an ENC28J60 Ethernet module to an Arduino or a Raspberry Pi”

    1. try that pin if my solution does not work. Ofcourse you can use many pins for CS as it is just a matter of setting it high or low

    2. Jackson,
      I realise that I might have been too brief in my reply to you. I will leave a note as part of the posting on how to solve the CS confusion

  1. I am confused..from some sources, .I came to know that CS pin is to be connected to pin 10 of Dumilanovae…..but here it is at Pin8…I tried with CS connected to Pin 10 firstly and no response…i haven’t tried your connection….will it work???

    1. Yogen
      I realise that I might have been too brief in my reply to you. I will leave a note as part of the posting on how to solve the CS confusion

  2. Please selp me with arduino mega 2560 and enc28j60.
    it doesn’t work with your library and I don’t find where I must change the pin definition for mega.
    Many thanks to all.

  3. thanks but in ethercard library from jeelab doesn’t exist the define for pins
    i found the solution and it is to put pin 53 in ether.begin

  4. Thanks! I have been having an intermittent hang that I’ve tried to figure out for literally months (it goes days between a problem). I narrowed it down to the udpSend code but haven’t made it beyond that yet.

    I correctly set CS to 10 in the .begin call, but didn’t realize that didn’t fix problems in the enc28j60.h file. Since pin 8 is connected to an LED that I am using I suspect the problem is occurring when I alter the LED.

    1. Dan, do i understand correctly that by changing the pin in the enc28j60.h file your problem is fixed? Or are you still having problems?
      If the pins are set correctly both in yr hardware and yr software, an LED on another pin (in yr case pin 8) really should not be a problem anymore. Please let me know if you still have problems

      1. Well, it appears I was premature in thinking I found my problem. I spent this evening carefully looking at the enc28j60 code. I call ethercard::begin with csPin set to 10. This is correctly propagated into the enc28j60::initialize code. You really don’t need to change csPin from 8 to 10 in the code, just call ethercard::begin.

        So that leaves me wondering why my Nano/ethernet shield hangs every few days. At this point, the most I know is it hangs when I call udpSend.

        It wasn’t doing that during testing on the breadboard. The only change I made when going from breadboard to the final PCB was to move an LED from pin 7 to pin 8; hence my belief that somehow my use of pin 8 is somehow causing the problem. I’ve just removed all code for the LED to see if the problem goes away, but at this point I don’t see it having anything to do with csPin being incorrectly set.

      2. I have not tried that yet. For me it was OK to just change the coding for the CD pin as I only have one card. Thanks for yr info

      3. Dan it has been a while but I was was wondering if u solved it. The internet shield/lib is quite memory hungry and if u have a couple of strings in yr program u can easily run out of memory. Try putting yr strings in program memory.

      4. Thanks for checking. I did, but it has been so long now I’m not sure exactly what the solution was. I think the final solution was increase the voltage to the arduino. I was giving it 6V thinking that was enough for the regulator to get 5V and evidently it wasn’t so I dialed up the input voltage to 7.5V. Even then I had very occasional hangs (every month or so) so I finally put a watch dog timer on it. Which is really what I should have done to begin with. Any future project that is mean to go into ‘production’ will have a WDT so I don’t have to dink with an arduino in the cold or rain. 🙂

        I am about ready to start a new Nano/ENC28J60 project (actually more and experiment) and I’m going to try the UIPEthernet library with it.

      5. Tnx for yr reply Dan. ENC28J60 modules are dirt cheap now at aliexpress.
        I presume that with the watchdog timer u mean a periodic reset of the arduino?

      6. Thanks Dan. I am familiar with it. Was in fact preparing an article but may not be necessary as u did a good write up already 🙂

      1. Tried the libary. very impressive, but as I understand it actually allows you to run most W5100 programs based on the Ethernetshield to run on the ENC28j60 card simply by replacing:
        #include by
        #include

        Thanks. Great job

  5. this was very helpful for me
    but i new in using ethernet module so i have a question if i want to access my arduino using ethernet module from any place in the world did i need to have a static ip in my home
    Sry for my bad english 😀

    1. a static IP would be the easiest, but it is also possible with a dynamic IP, using a dynamic ip service such as http://www.noip.com
      google on ‘dynamic ip service and you will find a bundle. many of them free

  6. Sorry for this noob question: Can you offer any advice for connecting one of these to an Arduino Nano? Do the pins remain the same?
    Thank you! 😀

    1. Yes the pins remain the same. But of course the lay out of the pins on the Nano is different from the Uno

  7. recently i did experiment with enc28j60 . i was able to run the hello world program using WiFi. The problem is that when i use my cellphone internet and try to access ip 192.168.2.15 after disconnecting wifi the web page doesnt shows up

    1. I am not sure if I fully understand your question because the answer seems overly simple: if you disconnect WiFi, how can yr webpage show up? You have disconnected so your cellphone cant ‘see’ any webpage

      1. My Enc28j60 was not disconnect from wifi but only the cellphone and what I did was , I was trying to access the same IP address from cellphone by using internet connection from sum card.
        Is there any way where I can access my module from any part of the world .
        PS English is not my native language

      2. i understand abt yr english. it isnt my mother tongue either, although I am still not sure what it exactly is you are trying to say. If you disconnect your cellphone then also it is not strange that you dont see a page.
        I am not sure what your ‘sum’ card is.

        Anyway, in order to access your module from anywhere in the world (I presume you have a router), you have to do portforwarding to the local IP address of your ethernet module. the easiest is to use port 80 for that.
        So suppose that your module is having the internal IP number 192.168.1.10. Then in your router (it has options for that) you connect that ip number to port 80.
        if then anywhere in the world you put your external ip number in a browser your router will send the http request to your module.
        The drawback is that it will do that for anybody browsing to your ip address.
        One can make ita bit less transparent by connecting a different port… say 8080 to your modules internal ip address.
        In that case you would have to do a call to http://42.104.xx.xxx:8080

      3. I believe that by “sum card” you mean “sim card”, right? Even if you have a sim card connected to your cell phone you MUST be connected to your wi-fi or you won’t be able to access the IP the way you want, the IP you have is an internal address only accessible through your local network, which is only available if you connect to it through wi-fi or an ethernet cable, now, if you want to expose this local ip (192.168.2.15) from any other place in the world, you must set up a port forwarding to this ip (192.168.2.15), this way you can access you global ip address (the one that you modem have, not 192.168.2.15, since this is a LOCAL ip address) from anywhere
        now to setup a port forwarding you must know what’s your modem and route brand so you can search for port forwarding to your hardware

  8. hello, I’m trying to run both an sd module and this enc28j60 module on an arduino nano, if I run just the ethernet code OR the sd code, they startup and run just fine… however, if I try to merge them both in one single code, my device won’t even start… here’s the code i’ve been trying:

    #include
    #include
    File root;
    #define REQUEST_RATE 5000 // milliseconds
    static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
    const char website[] PROGMEM = “google.com”;
    byte Ethernet::buffer[700];
    static long timer;

    static void my_result_cb (byte status, word off, word len) {
    Serial.print(“<<< reply ");
    Serial.print(millis() – timer);
    Serial.println(" ms");
    Serial.println((const char*) Ethernet::buffer + off);
    }

    void printDirectory(File dir, int numTabs) {
    while(true) {

    File entry = dir.openNextFile();
    if (! entry) {
    // no more files
    //Serial.println("**nomorefiles**");
    break;
    }
    for (uint8_t i=0; i timer + REQUEST_RATE) {
    timer = millis();
    Serial.println(“\n>>> REQ”);
    ether.browseUrl(PSTR(“/foo/”), “bar”, website, my_result_cb);
    }
    }
    as you see is a simple directory listing and a dns resolver, however, it won’t work! I’ve changed the CS pin of the ethernet module to 8 as well, I’m sure the connections are ok because if I remove the ethernet part of this code the directories will get listed just fine, and if I remove the Sd part of this code it will get a dhcp and ping the address just fine…

    do you have any idea what could it be?
    I’ve noticed that if I lower the buffer size of the ethernet library the serial will usually print something, however it won’t access the sd

    thanks a lot!

    1. as both individual programs work it can only be a conflict between the two and a few things come to mind then: memory and or pins.
      For some reason i do not see which libraries you have included. is that just a wordpress hickup or might there lie part of your problem.
      The Ethershield library uses pin 10 as a chipselect
      The EtherCard library uses pin 8 as a chipselect
      and the SD card uses pin 10. if you want to use both you need the Ethercard library with CS8.

      So first thing to do is check what library u use. and check the memory usage. Both ethernet and sd card can be quite hungry for memory

      1. Yeah I guess it was trimmed out sorry, the includes are “Sd.h” and “Ethercard.h”, I’m going to try to check arduino’s memory then, thanks a lot, I just found weird because I’ve been people saying they successfully ran similar code on arduino and I always assumed it was uno, nano or mini, if it’s a memory problem, do you think it would be worth to remove “unnecessary” code from these libraries to try to make everything fit in the arduino nano?
        by drecreasing the buffer size I could see the SD printing the directories to the serial, however, it was a bit messed up, besides the directories it prints a lot of garbage

      2. Well it should be possible, that is why the Ethercard made room for use with an SD card.
        You may want to check here: http://dangerousprototypes.com/2009/12/16/web-platform-sd-card-server-demo/
        als here: http://induino.blogspot.nl/2012/07/induinox-user-guide-interfacing-with_30.html
        someone with similar issues as you has found a solution: check here: https://github.com/jcw/ethercard/issues/4

        With regard to program space: I am not sure if you use a lot of strings, but I found that only already a small webserver with little output could easilu run into trouble and say adding one character to a string would already crash the program.
        You may want to consider putting your strings in Flash memory because you have much more of that than you have RAM (only 2 kb, much of which is used for internal processes.
        You may want to check here: http://jeelabs.org/2011/05/22/atmega-memory-use/
        and here: http://jeelabs.org/2011/05/23/saving-ram-space/

      1. Well it is good that it works 🙂 Thanks for the feedback
        Many 3.3V specified modules are 3.3V tolerant.. to some extend, so I am not surprised. Yet I rather dont take risc and just supply with 3.3V 🙂

  9. Hi, is it possible to connect an ENC28J60 module with an Arduino NANO trough the ICSP connector? the idea is not to use too many digital pins. How can it be done?
    By the way… great post! thanks

    1. thank you for yr compliments. Sadly your idea to connect it through the ICSP doesnt solve your ‘problem’.
      The connections you need, as described in the article, are:
      ENC SO -> Arduino pin 12=MISO
      ENC SI -> Arduino pin 11=MOSI
      ENC SCK -> Arduino pin 13=SCK
      ENC CS -> Arduino pin 8 (or 10)
      on the ICSP you find:
      MOSI, MISO, SCK, Reset
      So, 3 of the pins you need are the same, just on an other header, and then you still need to pick up the CS somewhere

  10. I have the same issue listed above with both ENC28J60 and SD CARD reader, using UIPEthernet library and all compilling OK, but nothing works. Serial monitor reports that both SD and Ethernet started and successfuly registered IP, but when I hit cmd ping there is no responce…
    I’ll appreciate any help. Thanks

    1. Same as Leandro Koit you mean? Well it has been a long time ago that I worked on this but usually the issue is somewhere between the CS and the proper library. u are using the UIPethernet lib. is it possible you are running out of memory?
      Which chipselects are you using?
      are you using one shiled with both the ENC and the SD card or 2 seperate shields?

  11. please help me how to interface with arduino nano and hanrun hr911105A with library for arduino programming..

    1. What exactly is the problem in connecting it? The nano basically uses the same pins as the UNO, namely the MOSI, MISO, SCLK and CS. Connect those to the hanrun module as described in article

  12. hej! I sucessfully used the UIPEthernet library to either send or receive stuff via UDP packaging the messages as OSC Messages.

    For some reason I could not send and receive in that configuration, though I am unsure if that could be because I don’t use a levelshifter or if it might be that I need the INT Pin or sth for that.

    Any ideas why it works like a charm mono-directional but not bi-directional?

    1. Gauguer, hej Apologies for my late reply, had some health issues.
      I have not tried to use the UDP-OSC protocol but it is especially meant for data communication over regular ethernetconnection. I do know that it DOES work with the Eternetlibrary and in fuchtion the UIPEthernet and Ethernet libraries should do the same. The only thing I can think of (apart from a mistake on your program) is that maybe the protocol is just too much for the Arduino with an ENC28J50 in terms of speed and memory. However, it did work with the old ethercard etc libraries, so maybe there is just something missing in the UIPlib for this aspect.
      You may want to check here where someone made it work with an ENC28J60. goodluck

      1. E, thank you so much for your response! I triple checked my implementation and realized one thing that I did not implement in my OSC packaging when sending out messages:
        the udp.client instance (most of the times called upd in the example sketches) needs to be restarted after each send. that must have been lost while i was implementing the OSC stuff around the udp client.

        after i put this code back into the udp/OSC send methods, it all was fine:

        ####################################

        void receiveOSC()
        {
        OSCMessage oscmsg;
        int size;

        if (( size = UDP.parsePacket()) > 0)
        {
        Serial.println(“jo”);
        while (size–)
        {
        oscmsg.fill( UDP.read() );
        }

        if (!oscmsg.hasError())
        {
        oscmsg.route(“/LED/SET”, eventhandler);
        sendOSCstr(“/TUT”,”LED OFF”,outIP);

        }
        else
        {
        Serial.println(“MESSAGE ERROR!”);
        }

        ///////////////////////
        //// ATTENTION !!! ////
        ///////////////////////
        // this is important for the enc28j60 MODULE. wiznet does not need that
        // nor does the ESP8226 wifi modules. don’t loose this part when
        // using the enc28j60 !!!

        UDP.stop();
        //restart with new connection to receive packets from other clients
        Serial.print(“restart connection: “);
        Serial.println (UDP.begin(8888) ? “success” : “failed”);

        ///////////////////////
        ///////////////////////
        }
        }

        ######################################

        maybe it helps sb for future reference…

        hope you have recovered ok! I very much appreciate you responding!
        lot’s of open source love ❤
        gauguer

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.