Pages

Updated Arduino ENC28J60 Ethernet library available

Finally after slow progress I’m releasing an update to my ENC28J60 Ethernet library. This is version 1.6. There is still work that can be done on it but for now I’m sending it off into the wild to let others have a play.

Changes made are:

  • Updated library filenames so that it should compile correctly under both Linux and Windows versions of the Arduino IDE
  • Alternative EtherShield::ES_enc28j60Init that includes a parameter to specify which pin the CS line is on. This is for hacked boards where more than one well behaved SPI device are used together (I have used this with EtherShield with tri-state buffers and a RF12 module together)
  • Converted 8 bit ENC28J60 writes to 16 bit writes where applicable, i.e. it now takes 1 operation to update a register not 2.
  • Added support for DNS queries, no need to get IP addresses now. Also handles multiple response records and picks the first valid A record.
  • Updated examples:
    • Twitter client now uses supertweet.net to post updates as twitter.com no longer supports basic authentication.
    • DNS client example – provides a web page where you enter the site, click reload link and it shows the IP address.
    • Retrieve CSV values from a Pachube feed
    • Broadcast a udp packet on the local network – this could be from a sensor that is then picked up by a daemon running on another machine. I currently use this for currentcost and RF12 data from Jeenodes

There are still a couple more example files that I have yet to finish including NTP usage.

Updating existing code

As the library filename has changed you will need to change your #includes to the correct name, this is EtherShield.h not etherShield.h. You will also have to remove the old library directory to prevent any clashes during compilation.

UPDATE This version has already been updated to fix a problem when sending PUT requests to Pachube.com.

Download library EtherShield_1.6.zip

Still todo

  1. Fully document the library
  2. Add more examples
  3. Add TCP support for sessions with more than 1 data packet transferred so that mqtt can be implemented
  4. Tidy up some of the code

Enjoy and feedback welcome.

Bookmark this post: bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark

36 comments to Updated Arduino ENC28J60 Ethernet library available

  • […] This post was mentioned on Twitter by Andrew D Lindsay, Andrew D Lindsay. Andrew D Lindsay said: Finally for those that were asking: http://blog.thiseldo.co.uk/?p=504 ENC28J60 updated library available. […]

  • pubdc

    Thanks Andy for the updated libraries. The code inside, even in the samples, is still beyond what I can make sense of. Is it possible to provide an example that allows for some basic interaction, like switch pin 13 (with built-in led) on/off ? Better yet, an example where I can send/write a number and the arduino will pass that on to the serial port (to an LCD for example) ? That type of thing I think I could take and run with.
    What I want to get at in the end is to send a series of 12 values (8bit) to the arduino over ethernet, the arduino will immediately write them to a string of 12 shift registers.
    Greetings, Peter DC, Bahrain

  • Hi Peter,

    your best bet is to get a book or two. I don’t have any myself so can only go on reviews by others. Have a look on your local Amazon site (or similar) for a book called Beginning Arduino, this has 50 projects covering just about anything you would want to hook up to it.

    Hope this helps

    Andrew

  • pubdc

    Hi Andrew, one of the issues with this ENC28J60 is that different sites provide libraries and updates thereof, with some coss-referencing or pointing towards same sources, examples that are shared and others that are not compatible between these ‘driver’ versions. That has me confused. Also, a very simple example could help : as in executing a digital/analog write/read. I just provided the other info as a reference of where I want to go. I already have all of that running on the arduino, but not through the ethershield. I liked the nuelectronics etherShield_web_switch example, but it doesn’t work with your latest library. Is there a small/easy fix or does it require a total rewrite ?

  • Lars

    Do you have any experience of the stability when running as a server with the ethernet library? I have been running a project on the Arduino with broadcasting UDP messages and that works fine. Now I wanted to add some server functionality as well, but the enc28j60 stops responding after some time. Now I tried your new library with your web server example and if you refresh the browser repeatedly it stops responding quite fast.
    Thanks, Lars

  • binooetomo

    Dear Andy.
    Thx for your realy great work on this library.

    duemilanove
    I have 2 question about this library.
    1. How to make : PORT, HOSTNAME, HTTPPATH as “end user” configureable ?
    I can make a menu for user input, but since that 3 factor is declared with “#define”, it’s not changeable.

    2. My Arduino board is duemilanove with USB and 328 in it. Whenever I plug my ENC28J60 base EthernetShield, I lost the USB feature.
    Is it fixable ? if so, How ?

    Sincerely
    -bino-

  • binooetomo

    Dear Andy,
    I try to stripdown your readpachube example, to make it to just send simple text to my station.

    here is the striped version

    /*
    * Stripped down of Readpachube example
    */
    #include

    static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x25};
    static uint8_t myip[4] = {192,168,10,231};
    static uint8_t gwip[4] = {192,168,10,1};

    //============================================================================================================
    // Pachube declarations
    //============================================================================================================
    #define PORT 80

    #define HOSTNAME "www.bino.int"
    static uint8_t websrvip[4] = { 192,168,10,232 }; // Get pachube ip by DNS call
    #define HTTPPATH "/post.php?time=" // Set your own feed ID here
    static uint8_t resend=0;
    static int8_t dns_state=0;
    EtherShield es=EtherShield();
    #define BUFFER_SIZE 550
    static uint8_t buf[BUFFER_SIZE+1];

    void browserresult_callback(uint8_t statuscode,uint16_t datapos){
    if (datapos != 0)
    {
    // now search for the csv data - it follows the first blank line
    // I'm sure that there is an easier way to search for a blank line - but I threw this together quickly
    // and it works for me.
    uint16_t pos = datapos;
    while (buf[pos]) // loop until end of buffer (or we break out having found what we wanted)
    {
    while (buf[pos]) if (buf[pos++] == '\n') break; // find the first line feed
    if (buf[pos] == 0) break; // run out of buffer
    if (buf[pos++] == '\r') break; // if it is followed by a carriage return then it is a blank line (\r\n\r\n)
    }
    if (buf[pos]) // we didn't run out of buffer
    {
    pos++; //skip over the '\n' remaining
    Serial.println((char*)&buf[pos]);
    }
    }
    }

    void setup(){
    Serial.begin(9600);
    Serial.println("Ethershield Pachube Read example");

    /*initialize enc28j60*/
    es.ES_enc28j60Init(mymac);

    //init the ethernet/ip layer:
    es.ES_init_ip_arp_udp_tcp(mymac, myip, PORT);

    // init the web client:
    es.ES_client_set_gwip(gwip); // e.g internal IP of dsl router
    es.ES_client_set_wwwip(websrvip);

    }

    void loop()
    {
    static uint32_t timetosend;
    uint16_t dat_p;
    int sec = 0;
    long lastDnsRequest = 0L;
    int plen = 0;

    dns_state=2;

    while(1) {
    // handle ping and wait for a tcp packet - calling this routine powers the sending and receiving of data
    plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);
    dat_p=es.ES_packetloop_icmp_tcp(buf,plen);
    // If we have IP address for server and its time then request data
    if( dns_state == 2 && millis() - timetosend > 1000) // every 10 seconds
    {
    timetosend = millis();
    char strtimetosend[50];
    ltoa(timetosend,strtimetosend,10);

    es.ES_client_browse_url(PSTR(HTTPPATH), strtimetosend, PSTR(HOSTNAME), &browserresult_callback);
    }
    }
    }

    and using “socat” to listen to it –> sudo socat TCP-LISTEN:80,fork,reuseaddr –
    I got this kind of data (result#1) :

    GET /post.php?time=22216 HTTP/1.1
    Host: www.bino.int
    User-Agent: EtherShield/1.6
    Accept: text/html
    Connection: close

    Looks good.

    Next, I try to change two part of above code
    1. HOSTNAME declaration :

    #define HOSTNAME "www.bino.int"

    to be :

    char HOSTNAME[]="www.bino.int"

    and,
    2. Data send part :

    es.ES_client_browse_url(PSTR(HTTPPATH), strtimetosend, PSTR(HOSTNAME), &browserresult_callback);

    tobe:

    es.ES_client_browse_url(PSTR(HTTPPATH), strtimetosend, HOSTNAME, &browserresult_callback);

    Using the same socat command as above, I got deferent result (Result#2):

    GET /post.php?time=19213 HTTP/1.1
    Host: 1
    Host:
    User-Agent: EtherShield/1.6
    Accept: text/html
    Connection: close

    Looks like a wrong HTTP header.
    There is two “Host” part sent with wrong value.

    How to fix it ?
    I want to write a sketch that just send some analog read, and I want it to be end-user configureable.
    Thats why I want some variable not to be declared using “#define” nor “static”, so that I can write a configuration menu that user can access from serial port.

    Sincerely
    -bino-

  • Kozovits

    Hi Andy,

    I have tried your 1.6 library with my Ethernet Shield ENC28J60 v1.1 mounted over Arduino MEGA 2560. You webserver example compiles and loads to the board without any warning but it is not working! Do you have a clue on what could be wrong.

    My local network uses a DI Link router with two wireless computers with dynamic DHCP from 192.168.0.100 .. 192.168.0.198 range. Arduino board was set to a static address 192.168.0.199 (I have changed that IP in your webserver sample and http port changed to 8080 as well). Why its impossible to reach “Arduino’s Web Server”. I think I am not missing anything, am I?

    Could you help me?

    Kozovits, Brazil

  • eugene

    Hi Andy, nice library. I modified a hand full of lines to work with Mega card you move the SPI interface to different pins. Bend out pins 10,11,12,13 and re-route to 50-53. In the ENC28J60.h file change these lines

    #define DEFAULT_ENC28J60_CONTROL_CS 53
    #define SPI_MOSI 51
    #define SPI_MISO 50
    #define SPI_SCK 52

    Seems like everything else works.

  • Thanks for the comment. I’ll add this info into the code as it could be useful to others with a mega.

  • gg23

    hi,
    Thanks for your great work. In a previous post you mentioned DHCP. Does this library support DHCP? Do you intend on implementing this? I have seen DHCP implemented using this ethernet chip and an arduino and BASCOM-AVR. So it must be possible.

    My requirements are to be able to plug an hardware unit (arduino + ethernet) into an ethernet port, have the unit allocate its own IP address using DHCP, and then be able to control one of the arduino output pins remotely from a webpage via Pachube. I am assuming this is possible apart from DHCP. Do you have any example code to get me started? The examples I can compile and run, just a little confused about Pachube so an example would be great.
    Thanks
    Greg

  • You should update it in Google Code: http://code.google.com/p/ethershield/ =)

    I had a hard time trying to find the newest version.

    Cheers

  • Hi,

    DHCP is on the list of things to do, however its not going to be completely config free as each arduino will need to have its MAC address set, unless I can work out some other way of generating a mac address or part of it.

    Cheers

    Andy

  • Hi,

    I’ve not created a google code copy as I think I only need it in one place, using more than one only leads to problems. The github archive is at https://github.com/thiseldo/EtherShield.

    thanks

    Andy

  • alvarojusten

    Hello Andy,
    good job! I did not see all your code but it looks like that you are implementing some helping functions.

    Well, I started a project with the goal of turn the Ethernet examples found on Arduino’s IDE compatbile with ENC28J60, so I’m rewriting all the socket layer, based on nuelectronics etherShield Library.

    For now, TCP server connections work (with some limitations) and the web server example is working fine.

    If do you want to know more, please see:

    – Topic on Arduino Forum: http://arduino.cc/forum/index.php/topic,56057.0.html
    – Project on GitHub: http://github.com/turicas/Ethernet_ENC28J60

    Your contribution will be much appreciated!

    Thanks.

  • Hi

    thanks for the info, I’d actually seen that post. One thing I’d suggest is to forget about the nuelectronics code and base any changes on my library. There are a number of reasons for this. Firstly my library has been updated to make it easier to use than the nuelectronics one, secondly it includes a number of updates and fixes including DNS support. One other change is that my library compiles on linux based systems whereas the nuelectronics one didnt due to file name and class name case problems. I have also provided a number of examples too.

    Just head over to my github repository and pull the latest code from there.

    Hope this helps

    Andy

  • tzn

    Hi,

    Im just trying to play with your ethershield lib but experiencing some things i cant solve. so what i want is a very simple code which can download a simple html file which contains just some strings.

    i set up my network card’s ip to 10.10.10.1 and set my arduino board’s ip to 10.10.10.2. a simple apache server running on the ip 10.10.10.1 with an index.php which contains just a string.

    my problem is, the ethershield cant reach the server. i ran a wireshark trace to check whats going on and noticed that only one SYN packet coming from the board but no any ACK packet has been sent back to the board.

    this is the only packet coming from the board but no any other packet (syn-ack) going back so the tcp handshake cant happen:
    179 181.832929 10.10.10.2 10.10.10.1 TCP powergemplus > http [SYN] Seq=0 Win=1024 Len=0 MSS=550

    i compared the SYN packet coming from the board to a normal http requests tcp syn packet and i found that some options are missing from your library’s syn packet.

    a normal syn packet’s options in wireshark:
    Maximum segment size: 1460 bytes
    NOP
    Window scale: 8 (multiply by 256)
    NOP
    NOP
    SACK permitted

    ethershield syn packet’s option:
    Maximum segment size: 550 bytes

    it contains just that option. im not exactly sure if this can cause my problem because im not a network guy (and i guess its working for you), i just thinking about that maybe this difference can be the problem.

    here is the code what i tried:
    do you guys have any suggestion? im using ethershield lib v1.6


    #include

    static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x27};

    static uint8_t myip[4] = {10,10,10,2};
    static uint8_t gwip[4] = {10,10,10,1};
    static uint8_t webip[4] = {10,10,10,1};

    #define WEBURL "/index.php"
    #define MYWWWPORT 80

    #define STATUS_BUFFER_SIZE 50
    #define BUFFER_SIZE 650
    static uint8_t buf[BUFFER_SIZE+1];
    static char statusstr[STATUS_BUFFER_SIZE];

    EtherShield es=EtherShield();

    void browserresult_callback(uint8_t statuscode,uint16_t datapos){
    Serial.print("Received data, status:"); Serial.println(statuscode,DEC);
    if (datapos != 0)
    {
    Serial.println((char*)&buf[datapos]);

    uint16_t pos = datapos;
    while (buf[pos])
    {
    while (buf[pos]) if (buf[pos++] == '\n') break;
    if (buf[pos] == 0) break;
    if (buf[pos++] == '\r') break;
    }
    if (buf[pos])
    {
    pos++;
    Serial.print("CSV line is:");
    Serial.println((char*)&buf[pos]);
    }
    }

    }

    void setup(){
    Serial.begin(9600);

    es.ES_enc28j60Init(mymac);
    es.ES_init_ip_arp_udp_tcp(mymac,myip, MYWWWPORT);
    es.ES_client_set_gwip(gwip);

    es.ES_client_set_wwwip(webip);
    }

    void loop(){
    static uint32_t timetosend;
    uint16_t dat_p;

    while(1){

    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
    if(dat_p==0){

    if (millis() - timetosend > 10000)
    {
    timetosend = millis();
    es.ES_client_browse_url(PSTR("/index.php"), NULL, PSTR("10.10.10.1"), &browserresult_callback);
    }
    }
    }
    }

  • […] Updated Arduino ENC28J60 Ethernet library available  http://blog.thiseldo.co.uk/?p=504 […]

  • derpfaelzer

    Hi Andy,
    i want to replace the serial communication with a telnet session on my stove control project.
    I admit, that i am just starting to dig into microcontroller programming, and i do not want to handle the http stuff at the same time. So i’d like to keep the interface simple (i am old enough to know VT100 codes;-).

    Unfortunately, no one seems to be interested in setting up a telnet service based on the ENC28J60. I checked several µc-Communities as well as google and nuelectronics, before i decided to bother you with this newbie stuff;-)

    The Arduino Ethernet shield documentation looked much more simple than the examples of the ENC based Ethershield. Maybe the mistake lies in purchasing the cheaper board.

    So, do you have an example for a telnet server or is there a reason why the ENC28J60 cannot deal with that?

    Regards from Bavaria

    DP

  • londondigital

    Hi Andy,

    Do you have any example code for using NTP?

    What I would like to be able to do, is set the ntp client details via a web page and then have the client report the correct time.

    Eventually I would like to take this a little further and have the arduino switch a digital line on and off at preset times, if this could all be done via a web page, that would be great.

    Any advice and/or guidance would be appreciated.

    Thanks for all your hard work.

  • […] – Okiraku Programming Arduino Internet Clock « Andy’s Life Updated Arduino ENC28J60 Ethernet library available « Andy’s Life Arduino playground – Time Arduino playground – Timer1 Ardunio << […]

  • […] dangerousprototypes.com writes: [via] Nanode is a low cost Arduino-like sensor node board intended for web connectivity applications. It allows you to develop web based sensor and control systems – giving you web access to six analogue sensor lines and six digital I/O lines. The schematic and other details can be found on the project’s Thingiverse page. The code can be found here. […]

  • kvi

    Hi, Andy!
    I use Your fine library with the MK-duino (the Arduino clone).
    I had simplifid Your example file EtherShield_webserver.pde.
    It works continuously over a period of several weeks!!!
    But some time it hangs up ;-(
    May be You will help me to find the bag?

    Here is fragment of my code:
    ——————————-
    void loop(){
    uint16_t dat_p;
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
    if(dat_p!=0){// eny request to my shild
    if (strncmp(“/ “,(char *)&(buf[dat_p+4]),2)==0){// my request request
    dat_p=print_webpage(buf);
    }
    es.ES_www_server_reply(buf,dat_p);
    }
    }//loop
    —————————————

  • kmmankad

    Could you please release code for the PING example(and others too,if possible) from Ethershield v1.1 for the new 1.6?

  • kvi

    Hi Kmmankad.
    My fragment is differ from Andi’s example file EtherShield_webserver.pde in Loop() block only.
    The Andi’s Lib1.6 includes all necessary actions inside it.
    It formed the PING and others in those functions:
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
    es.ES_www_server_reply(buf,dat_p);
    Your own functions will located in
    dat_p=print_webpage(buf);
    And test
    strncmp(“/ “,(char *)&(buf[dat_p+4]),2)==0
    controls http content request to your Arduino web-server.

  • kapu

    Hi Andy,

    First of all thanks for the great library. I am however having troubles to get the web client code work correctly. My web client can connect to my server but using GET method is the problem. Apache error log says:

    [13/May/2011:13:24:27 +0300] “GET /logdata.php\x87 HTTP/1.0″ 404 – “-” “Arduino/1.0″
    81.197.78.106 – –

    instead of \x87 there should be ?temp=xx.xx. Any ideas where the problem is? I have tried with bigger buffer sizes but same thing.

    Greetings, Kapu

  • ogogon

    Good evening!

    As in this library set netmask? Sometimes it is very important.

    How to contact you by e-mail?

    Ogogon.

  • gnih

    Hi Andy!

    I’m playing with you library (many thanks for the good work :) !) and I wondered if it would be possible to receive UDP packet, I guess so but could you put me on the right way… ?

    Thank you in advance!

    Gnih

  • Hi,

    you can receive UDP packets, have a look at the NTP, DNS and DHCP code as these all use UDP. The main arp/tcp function just exits and you then look at the packet to identify the protocol and the port its directed at.

    Thanks

    Andy

  • jatrn

    Hello Andy,
    I’m using your library for broadcasting UDP, works like a charm. Thanks a lot.
    Do you have any examples how to receive UDP pockets and based on its content perform appropriate actions?

    Thank you

  • […] A few notes about using that ethernet shield with the arduino mega. First of all I used the Ethershield library located here: http://blog.thiseldo.co.uk/?p=504 […]

  • robcikss

    Hello!

    Is it possible to use this library with ATXmega128A1 and ENC28J60-H?

    Thank you!!

  • nikro

    Hi.

    Nice job you are duing here, but I can’t get it to work with IDE 1.0

    Are there a vesion for arduino IDE 1.0 on it’s way?

    Regards
    Niels

  • nikro

    Never main found it

  • […] LCD display in action. On the first screen you can see the current data, the time when they were recorded and if the change from earlier time is positive, negative or constant. On the second picture the display is showing maximum and minimum within certain period and they can even be reset. All the captions are in Slovene language. More pictures can be found in gallery. Useful links at building this device: Modified Arduino library for graphic display Arduino ENC28J60 Ethernet library […]