ENC28J60 Web Server

Dear All.

This chip is a cheap alternative to the WIZ one.
I Realize that it'll also mean need alot of work to use it.
I realy Appreciate andrewdlindsay for his great work at http://blog.thiseldo.co.uk/?p=504
There is two main problem that I have using this library :

  1. Client mode : AFAIK this library need us to hardcoded the server name. I did a work around by make a small change in the library.
  2. Web Server mode :
    This library need us to fill the buffer first , and send it in one shoot.
    The problem with this approach is limited RAM we have in Arduino.
    If we want to show a lot of data in one page, we'll eat alot of RAM (Most of it for HTML tag to make it neat).

So , is there any way to send the web-page line by line ?
I realy attracted by how the WIZ's library using "client.print" and "client.stop" approach.

Sincerely
-bino-

Hi,

The work I've done on the ENC28J60 library for the nuelectronics ethershield has really been driven by things I've needed for my own applications. However, feedback and comments are most welcome. Plus if you have any changes/updates that you have done, these can be fed back into the main code by myself or you can release your own version!

In answer to your questions:

  1. Is something I'm looking at, to provide alternative methods that dont use flash memory for the strings.
  2. The library is set up for single packet send and receive so its a trade off between available memory and a usable packet size. If you need more flexibility in this area then a hardware solution such as a shield with the alternative chips may be the correct way to go for your needs. The ENC28J60 is a cheap solution because it provides just the basic packet framing, the IP and TCP layers are done in software, but it is exactly this reason that makes it very flexible too.

The library I have produced can still be classed as a work in progress, there are things I'd like to see in there for my own use but as yet havnt got round to them. To many other distractions I'm afraid.

Cheers

Andy
:slight_smile:

Dear Andy.
I really appreciate your reply

AndyL:
Hi,

The work I've done on the ENC28J60 library for the nuelectronics ethershield has really been driven by things I've needed for my own applications. However, feedback and comments are most welcome. Plus if you have any changes/updates that you have done, these can be fed back into the main code by myself or you can release your own version!

In answer to your questions:

  1. Is something I'm looking at, to provide alternative methods that dont use flash memory for the strings.

Ah ... I'm not that good to realease my own version.

I just replace some "prog char" to "char", and some "fill_tcp_data_p" with "fill_tcp_data" in www_client_internal_datafill_callback, and in client_browse_url part.

Question :
There is "buf" that created/declared inside the sketch.
Is it the same "buf" that used inside "ip_arp_udp_tcp.c" ?

If so, since the final process is :
client_tcp_req(&www_client_internal_result_callback,&www_client_internal_datafill_callback,80)
I'm thinking of doing www_client_internal_datafill_callback inside the sketch and just call www_client_internal_result_callback after it.

Is it doable ?

AndyL:
2. The library is set up for single packet send and receive so its a trade off between available memory and a usable packet size. If you need more flexibility in this area then a hardware solution such as a shield with the alternative chips may be the correct way to go for your needs. The ENC28J60 is a cheap solution because it provides just the basic packet framing, the IP and TCP layers are done in software, but it is exactly this reason that makes it very flexible too.

The library I have produced can still be classed as a work in progress, there are things I'd like to see in there for my own use but as yet havnt got round to them. To many other distractions I'm afraid.

well ... for www-server part ...
I'm thinking of just send out some java script with xmlhttprequest in it.
I think the server can throw it at once ... and let the browser auto-request for other part of the doc. I found some where in internet the guy that write about dinamic table creation using xmlhttprequest.
I think with this approach, we can make our sketch to send as much data as we wish.

I really appreciate your library.

Sincerely
-bino-

binooetomo:
Question :
There is "buf" that created/declared inside the sketch.
Is it the same "buf" that used inside "ip_arp_udp_tcp.c" ?

Basically the buffer is defined in the sketch and you are passing pointers to this buffer into the ip_arp_udp.c code. Due to memory limitations, the same buffer is used for both received and transmitted packets, but obviously not at the same time.

Cheers

Andy

Again, I realy appreciate your reply

AndyL:
Basically the buffer is defined in the sketch and you are passing pointers to this buffer into the ip_arp_udp.c code. Due to memory limitations, the same buffer is used for both received and transmitted packets, but obviously not at the same time.

So ... (I hope you still have spare time to continue this "course").

In your Library, you wrap client_browse_url as :

void EtherShield::ES_client_browse_url(char *urlbuf, char *urlbuf_varpart, char *hoststr,

		void (*callback)(uint8_t,uint16_t)) {

	client_browse_url(urlbuf, urlbuf_varpart, hoststr, callback);

}

While in turn (in ip_arp_udp.c) .. client_browse_url call for 2 other function, via single call to client_tcp_req:

www_fd=client_tcp_req(&www_client_internal_result_callback,&www_client_internal_datafill_callback,80);

Kindly please cmiiw : www_client_internal_datafill_callback is the one that do buffer filling. and we can do it in sketch.

If So , while :

  1. Inside your library there is a wrapper for client_tcp_req as :
uint8_t EtherShield::ES_client_tcp_req(uint8_t (*result_callback)(uint8_t fd,uint8_t statuscode,uint16_t data_start_pos_in_buf, uint16_t len_of_data),uint16_t (*datafill_callback)(uint8_t fd),uint16_t port ) {

	return client_tcp_req( result_callback, datafill_callback, port );

}
  1. we Have (i.e) browserresult_callback() as our result_callback handler, and
  2. we have "buf" as our buffer,

Is it mean that we can call --> ES_client_tcp_req(&browserresult_callback, buf,80) ?

(Ah ... while waiting for your further enlightment, I'll try it my self. May God bless my lame brain)

Edit : This is my dirty try:

I'm pretty sure that the error is at the part I call --> es.ES_client_tcp_req
sincerely
-bino-

I put a bit of a wrapper round your library - probably an old version from Nuelectronics, that makes it a bit easier to use. I did have plans to mirror the standard Ethernet library, but it was too much work :frowning:

Its here if anyone is interested or wants to take it further.

Hello, I have been working all day trying to figure something out.

I have some binary image data stored in the arduino flash. Unfortunately, it is much larger than a packet size, so I must send multiple packets to fully complete sending the image.

I have broken up the data into chunks the size of the remaining buffer after the header, yet when I try to send multiple packets within the same loop, it hangs up after the first packet.

I send them such as:

plen=es.ES_fill_tcp_data_p(buf,0,PSTR("SOME CONTENT TO SEND, BUT MUCH BIGGER THAN THIS") );
es.ES_make_tcp_ack_from_any(buf); // send ack for http get
es.ES_make_tcp_ack_with_data(buf,plen);

plen=es.ES_fill_tcp_data_p(buf,0,PSTR("SOME REMAINING CONTENT TO FINISH ENTIRE WEBPAGE") );
es.ES_make_tcp_ack_from_any(buf); // send ack for http get
es.ES_make_tcp_ack_with_data(buf,plen);

All in the same loop. Is there a way to do this this library? I'm dumbfounded.

@Si

I've tried using your ETHER_28J60 library, but I get several errors when trying to compile it. I'm not sure how to troubleshoot this. I'm far from an expert in C. Dueminalove with 168, Arduino 18 environment, etherShield library, ETHER_28J60 library, ENC28j60 ethernet module.

C:\Program Files\arduino\arduino-0018\libraries\ETHER_28J60\ETHER_28J60.cpp: In member function 'char* ETHER_28J60::serviceRequest()':
C:\Program Files\arduino\arduino-0018\libraries\ETHER_28J60\ETHER_28J60.cpp:79: error: 'class EtherShield' has no member named 'ES_make_arp_answer_from_request'
C:\Program Files\arduino\arduino-0018\libraries\ETHER_28J60\ETHER_28J60.cpp:108: error: no matching function for call to 'EtherShield::ES_make_tcp_ack_from_any(uint8_t [501])'
C:\Program Files\arduino\arduino-0018\libraries\EtherShield/EtherShield.h:51: note: candidates are: void EtherShield::ES_make_tcp_ack_from_any(uint8_t*, int16_t, uint8_t)
C:\Program Files\arduino\arduino-0018\libraries\ETHER_28J60\ETHER_28J60.cpp: In member function 'void ETHER_28J60::respond()':
C:\Program Files\arduino\arduino-0018\libraries\ETHER_28J60\ETHER_28J60.cpp:158: error: no matching function for call to 'EtherShield::ES_make_tcp_ack_from_any(uint8_t [501])'
C:\Program Files\arduino\arduino-0018\libraries\EtherShield/EtherShield.h:51: note: candidates are: void EtherShield::ES_make_tcp_ack_from_any(uint8_t*, int16_t, uint8_t)

Does anyone have a recommendation, or should I just ditch this one and buy a W5100?

For $10 shipped, I'd just go with the w5100.

http://www.ebay.com/itm/Ethernet-Shield-W5100-For-Arduino-2009-UNO-Mega-1280-2560-/270955738702?pt=LH_DefaultDomain_0&hash=item3f1638764e

Yeah, that's kind of what I figured...

Oh well, I'll try the other one. There does seem to be a lot more information about them on the web. Guess I should have done more research before buying. Live and learn.

expirobo:
Hello, I have been working all day trying to figure something out.
[...]
All in the same loop. Is there a way to do this this library? I'm dumbfounded.

First, you should go for EtherCard, the other libraries are not supported any more.

Second, while there isn't a lot of information on the libraries, my understanding is that each loop() can only handle max one packet. This means you should put your logic in some kind of state machine, and wait for the TCP ack from your first packet before you send the second one.

But I don't really master the stack either, and while EtherCard is "smarter" in its memory usage (almost everything in Flash and in the ENC chip), it's not reaaly easy to work with.

binooetomo:
Dear All.

This chip is a cheap alternative to the WIZ one.
I Realize that it'll also mean need alot of work to use it.
I realy Appreciate andrewdlindsay for his great work at http://blog.thiseldo.co.uk/?p=504
There is two main problem that I have using this library :

  1. Client mode : AFAIK this library need us to hardcoded the server name. I did a work around by make a small change in the library.
  2. Web Server mode :
    This library need us to fill the buffer first , and send it in one shoot.
    The problem with this approach is limited RAM we have in Arduino.
    If we want to show a lot of data in one page, we'll eat alot of RAM (Most of it for HTML tag to make it neat).

So , is there any way to send the web-page line by line ?
I realy attracted by how the WIZ's library using "client.print" and "client.stop" approach.

Sincerely
-bino-

Hi,

you can use the uIP stack with the ENC28J60, you can work easily with more than one packet, but handling the TCP/IP in software with more than one packet will drammatically slow down the response time (compared to the W5100).

In the project that I'm carring out, I've the ENC28J60 with uIP and the HTTP/JSON server was build to send more than one packet for a single answer. Now I'm moving out from HTTP just because this handling wasn't fast enough.

There are some porting of the uIP stack for ENC28J60 and AVRs and one of these is in the project in my signature.

Regards,
Dario.