Help with Ethernet Shield? (ENC28J60)

I just won a "Arduino Ethernet Shield work as ENC28J60 RJ45 Webserver" off Ebay.

Same as this: http://tinyurl.com/27aobke

Does this use the standard ethernet library? I did the simple example webserver that comes with the arduino software and it didn't work. I applied and IP/Mac but I can't ping it. Should I be able to ping it? If I check arp my computer isn't resolving the MAC address for the Arduino.

I have a link light on the Arduino and everything appears to be happy. It just doesn't reply to any IP packets. I'm wondering if the chipset is different and requires a different library?

I answered my own question after a little googling.

http://www.nuelectronics.com/estore/?p=12

It uses the etherShield library. Once I downloaded and installed that I can interface with the shield now.

Looks like an updated library: http://blog.thiseldo.co.uk/?p=329

I'd like to say you are a smasher for posting this now. I couldn't get my shield to work and tried everything. Searched the Arduino sites and googled etc etc but nothing would get it to work. I'm not a network nooby but I completely overlooked the obvious that the library would be device dependant. I've downloaded the updated library for the correct device i.e. the ENC28J80 and it works first time. I've only just received my first board and shield yesterday so I'm pretty pleased with it, me and now you :slight_smile:
One further thing though is on the served web page it says “Read digital analogue inputs HERE” should I be able to click on that and see the inputs?

I've just answered my own question now, by actually looking at the code there doesn't seem to be any code relating to getting the current state of the digital and analogue pins so I guess it is just a title on the web page. I'm off to search for any info I can find on how to put a button on the web page that will control an output and how to display the state of the inputs. Any suggestions?

Here is the preliminary code I have to monitor each analog/digital pin and output it via http. I set it up, and queried it once every .2 seconds for more than 200,000 times and never had an issue.

// EtherShield webserver demo
#include "etherShield.h"

// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x00,0x55,0x58,0x10,0x00,0x24}; 
static uint8_t myip[4] = {192,168,5,99};

int usable_dpins[] = {3,4,5,6,7,8,9};
int usable_apins[] = {0,1,2,3,4,5};

#define MYWWWPORT 80
#define BUFFER_SIZE 750
static uint8_t buf[BUFFER_SIZE+1];

// The ethernet shield
EtherShield es=EtherShield();

uint16_t http200ok(void) {
  return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n")));
}

// Add the string str to the buffer one character at a time
int add_string(char* str, uint16_t &plen) {
  int i = 0;
  
  //Loop through each char
  while (str[i]) {
    // Add each char one by one to the buffer
    buf[TCP_CHECKSUM_L_P + 3 + plen] = str[i];
    i++;
    plen++;
  }
}

// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf) {
  uint16_t plen; // Packet Length
  
  plen=http200ok();
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<html><head><title>Arduino</title></head><body>\n"));
      
  add_string("<h1>Arduino Ethernet Shield</h1>\n", plen);
  
  for (int i = 0; i < (sizeof(usable_dpins) / sizeof(usable_dpins[0])); i++) {
    int mypin = usable_dpins[i];
    
    char mystr[40];
    pinMode(mypin, INPUT);
    sprintf(mystr,"<div>Digital Pin #%d is %d</div>\n",mypin,digitalRead(mypin));
    add_string(mystr, plen);    
  }
  
  for (int i = 0; i < (sizeof(usable_apins) / sizeof(usable_apins[0])); i++) {
    int mypin = usable_apins[i];
    
    char mystr[40];
    sprintf(mystr,"<div>Analog Pin #%d is %d</div>\n",mypin,analogRead(mypin));
    add_string(mystr, plen);
  }
  
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</body></html>"));

  return(plen);
}

void setup() {
  // initialize enc28j60
  es.ES_enc28j60Init(mymac);

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

void loop() {
  uint16_t plen, dat_p;

  while(1) {
    // read packet, handle ping and wait for a tcp packet:
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));

    /* dat_p will be unequal to zero if there is a valid 
     * http get */
    if(dat_p==0){
      // no http request
      continue;
    }
    
    // tcp port 80 begin
    if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
      // head, post and other methods:
      dat_p=http200ok();
      dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>"));
      goto SENDTCP;
    }
    
    // just one web page in the "root directory" of the web server
    if (strncmp("/ard.html ",(char *)&(buf[dat_p+4]),9)==0){
      dat_p=print_webpage(buf);
      goto SENDTCP;
    } else {
      dat_p=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
      goto SENDTCP;
    }
    
SENDTCP:
    es.ES_www_server_reply(buf,dat_p); // send web page data
    // tcp port 80 end
  }
}

Thanks for that.
I stuck it in and it works great as you said with no issues. It did catch me out the first time forgetting to type in the IP and the /ard.html bit. Why doesn't this work with an index page? Not that it matters of course as long as it works. I'm by no means a HTML expert and I know there are different versions but my next problem is how to put a button or something on the web page that I can use to turn an output on. On a standard web page I could use the
Do Something in the body section.
This web server doesn't like that command and reports it wants a ')' before 'button'. Again I'm scouring the net to see what others have done. I found the web_led example that came with previous version of the EtherSheild library but it doesn't seem to want to work on mine. So sorry to be probing you but would you have any suggestions as to how I could see the value of some inputs and then press a button or toggle something on the screen to switch on an output. As I'm hopefully going to make a gate controller out of this project the inputs are things like gate closed gate open gate locked etc so I can check the status of the gate on the web page but then press a button on the page to actually open or close it. Is there a list of the contents of the library and perhaps an explanation of what each do? Thanks again.

Ahh.
It doesn't like the “” around the word button which makes sense I suppose. So somehow I've got the put Ascii character 34 in there to be converted back to “” during compiling. There must be somewhere where I can read up on the programming of these things rather than doing it all by trial and error.

You can escape the " and it will be happy.

add_string("<input type=\"button\" />");

Simple enough I use the old Asc$(34) either side of the button word and I now have a button on the screen with the words Do Something on it. Now the bit I haven't got a clue how to tackle, how to get the state of that button back into the Arduino code to use it to switch on an output. Hmmmmm

Sorry I didn't see you reply before posting mine but it appears both methods work. Any clues on the getting the state of the button?

On a standard web page you'd have something like:-

So do I simply load a variable in the do something bit to check on later and condition the output? How do I break out of the HTML section with the value of the button in my grubby hand?

You have to check the request for that variable you're sending. Something like

if (strstr(request,"open_gate=1")) {
// turn on led or whatever
}

I'm bashing away at that now.
I'm declaring a variable called Web_Button then setting it in

Int Web_Button = 0;

Then I should be able to check that variable for its state when needed. Is that right ?

Ps sorry If you are getting fed up with my questions. I do apreciate your help a little nudge in the right direction goes a long way. Thanks

Ok my way didn't work.
It tries to open a web page called Web_Button.
I guess what you meant was the form itself is a variable and thus I should be able to check it and get a string back as the condition.

If you look at the URL the gets to your arduino after you click the button it should say open_gate=1 or something. Assuming you made your html correctly. You can check the request string for that.

Ok I'm going to have to give it a rest now for tonight the missus is missing me :). My problem is still that variable. Where do I declare it? And how do I set its value? If I put it in the action bit it thinks the variable is the name of a web page and tries to go there.
Thanks again.

Nearly gave it a rest. It says the request is not declared in this scope.

Ok, I'm making progress albeit slowly and I think it's my HTML letting me down. I have two forms with actions on the home web page and each action loads a different web page. So that the button that says open on it has the action to kick off the Open_Gate.html page and similarly for the close. The problem is though each one works on its own if I put both forms on the home page it brings up the little circle thing showing it is doing something i.e. loading a page but never actually loads anything. An Extract of the code is:-

plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("Arduino\n"));

add_string("

Arduino Ethernet Shield

\n", plen);

add_string("<form name="OPEN" action="Open_Gate.html" method="get">\n", plen);
add_string("<input type="submit" value="Open" />\n", plen);
add_string("\n",plen);

add_string("<form name="CLOSE" action="Close_Gate.html" method="get">\n", plen);
add_string("<input type="submit" value="Close" />\n", plen);
add_string("\n",plen);

out of interest What is the /n bit for on the end ?

Thanks to anyone that can shed a bit of light on the above.

The \n is a carriage return. It's basically the enter key. The code you posted is pretty simple HTML I can't imagine it would cause any problems. Post the rest?