UIPEthernet, SD, ENC28J60... Freezes up

My Stuff: Arduino Mega Rev3, The very latest Arduino IDE and UIPEthernet libraries. Arduino Local IP=192.168.1.200.

I started my first ethernet projects and tutorials and I seem to be running into an issue that I'm not sure how to go about resolving. I bought my ethernet shield not realizing it was one not supported by the included Arduino libraries so I opted to use the UIPEthernet library since it is a drop in replacement. Looking at the tutorial located here, I managed to get it working. However, if I navigate back and forth a few times, it freezes up. The .htm and image files are available to download from their site.

I littered my code with Serial.print statements to locate the issue and I found that the Arduino itself is still working when the webpages freeze. After a short time, i guess the UIPEthernet library times out as it will exit the "if(client) {...}" section back to the main loop. If it times out, the "Ethernet Client = server.available()" will not connect to a client again. After freezing, If I navigate to the local IP address, the Ethernet shield will light up showing its receiving a connection. Resetting the Arduino will allow it to work again.. for a few clicks. I found the issue to specifically come from the section that its printing to the website and usually, but not always, while its trying to upload the image (as thats the longest part of the loading process so more likely to fail there).

if (webFile) {
  while(webFile.available()) {
    client.write(webFile.read();); // send web page to client
  }

 webFile.close();
}

The serial.print statements I put into this sections showed that it get stuck in the while(...) loop at the client.write statement. I think it has something to do with the UIPEthernet library but I'm not entirely sure.

Things I've tried that do not work:

  • Splatter it with Ethernet.maintain() statements
  • ENC28J60 chip does not get hot so no need for heat sync
  • including a client.close() statement before trying to connect to client

I'm not entirely sure as I did not write these libraries, but I don't think adding anything to the sketch will help since its freezing specifically at the "client.write(webFile.read())" part. Suggestions/solutions?

Splatter it with Ethernet.maintain() statements

Splattering is not the best choice here. Where did you insert the statement? Inside the while loop?
Did you rename the UIPEthernet to Ethernet?
UIPEthernet does it's best to emulate the original Ethernet library but it's not a complete drop-in replacement. The tutorial you used is for an original Arduino Ethernet shield which does a lot of stuff in hardware that has to be done in the software when using the ENC28J60.
Try to adapt the software to use the UIPEthernet class and don't rename the library because that may cause problems that are not apparent.
Did you try to activate the UIPETHERNET_DEBUG_CLIENT switch in the library to see what's going on while it "freezes"?

Splattering is not the best choice here. Where did you insert the statement? Inside the while loop?

Well, I didn’t put millions of ethernet.maintain statements in it. I moved them from place to place. I had one located on the outside of the client connected loop and i tried having them inside the while(webfile.available()) loop, before it, after it, and inside the client loop. Nothing seemed to help.
When it “freezes” heres what the debug client shows.

UIPClient.write: writePacket(1) pos: 44, buf[0-1]: 'M'
UIPClient.write: writePacket(1) pos: 45, buf[0-1]: 'I'
UIPClient.write: writePacket(1) pos: 46, buf[0-1]: '‚'
UIPClient.write: writePacket(1) pos: 47, buf[0-1]: 'ã'
UIPClient.write: writePacket(1) pos: 48, buf[0-1]: 'w'
UIPClient.write: writePacket(1) pos: 49, buf[0-1]: ''
UIPClient.write: writePacket(1) pos: 50, buf[0-1]: '¶'
UIPClient.write: writePacket(1) pos: 51, buf[0-1]: 'ì'    <--- most all stop at 51
UIPClient.write: writePacket(2) pos: 0, buf[0-1]: 'ì'
UIPClient.write: writePacket(2) pos: 1, buf[0-1]: 'y'
UIPClient.write: writePacket(2) pos: 2, buf[0-1]: 'ï'
UIPClient.write: writePacket(2) pos: 3, buf[0-1]: ','
UIPClient.write: writePacket(2) pos: 4, buf[0-1]: 'Ø'
UIPClient.write: writePacket(2) pos: 5, buf[0-1]: 'æ'
UIPClient.write: writePacket(2) pos: 6, buf[0-1]: ','
UIPClient.write: writePacket(2) pos: 7, buf[0-1]: '£'
.......(continues this).....
UIPClient.write: writePacket(2) pos: 498, buf[0-1]: ''
UIPClient.write: writePacket(2) pos: 499, buf[0-1]: 'J'
UIPClient.write: writePacket(2) pos: 500, buf[0-1]: '¨'
UIPClient.write: writePacket(2) pos: 501, buf[0-1]: '('
UIPClient.write: writePacket(2) pos: 502, buf[0-1]: '+'
UIPClient.write: writePacket(2) pos: 503, buf[0-1]: 'Ä'
UIPClient.write: writePacket(2) pos: 504, buf[0-1]: '^'
UIPClient.write: writePacket(2) pos: 505, buf[0-1]: 'É'
UIPClient.write: writePacket(2) pos: 506, buf[0-1]: 'û'
UIPClient.write: writePacket(2) pos: 507, buf[0-1]: 'î'
UIPClient.write: writePacket(2) pos: 508, buf[0-1]: '²'
UIPClient.write: writePacket(2) pos: 509, buf[0-1]: 'ï'
UIPClient.write: writePacket(2) pos: 510, buf[0-1]: 'Ü'
UIPClient.write: writePacket(2) pos: 511, buf[0-1]: 'å'
UIPClient.write: writePacket(2) pos: 512, buf[0-1]: '´'
UIPClient.write: writePacket(3) pos: 0, buf[0-1]: '´'
UIPClient.write: writePacket(3) pos: 1, buf[0-1]: '{'
UIPClient.write: writePacket(3) pos: 2, buf[0-1]: 'e'
UIPClient.write: writePacket(3) pos: 3, buf[0-1]: 'n'
UIPClient.write: writePacket(3) pos: 4, buf[0-1]: 'y'
UIPClient.write: writePacket(3) pos: 5, buf[0-1]: '¢'
UIPClient.write: writePacket(3) pos: 6, buf[0-1]: 'Ì'
UIPClient.write: writePacket(3) pos: 7, buf[0-1]: '¾'

.......(repeats for 3 and 4).......

UIPClient.write: writePacket(4) pos: 507, buf[0-1]: '8'
UIPClient.write: writePacket(4) pos: 508, buf[0-1]: '¸'
UIPClient.write: writePacket(4) pos: 509, buf[0-1]: 'Ž'
UIPClient.write: writePacket(4) pos: 510, buf[0-1]: ''
UIPClient.write: writePacket(4) pos: 511, buf[0-1]: '±'
UIPClient.write: writePacket(4) pos: 512, buf[0-1]: '˜'
UIPClient.write: writePacket(5) pos: 0, buf[0-1]: '˜'
UIPClient.write: writePacket(5) pos: 1, buf[0-1]: '«'
UIPClient.write: writePacket(5) pos: 2, buf[0-1]: 'Ó'
UIPClient.write: writePacket(5) pos: 3, buf[0-1]: 'Ú'
UIPClient.write: writePacket(5) pos: 4, buf[0-1]: '˜'
UIPClient.write: writePacket(5) pos: 5, buf[0-1]: 'Ó'      
......(continues this).......
UIPClient.write: writePacket(5) pos: 504, buf[0-1]: 'Ý'
UIPClient.write: writePacket(5) pos: 505, buf[0-1]: '²'
UIPClient.write: writePacket(5) pos: 506, buf[0-1]: 'ž'
UIPClient.write: writePacket(5) pos: 507, buf[0-1]: '¤'
UIPClient.write: writePacket(5) pos: 508, buf[0-1]: 'Õ'
UIPClient.write: writePacket(5) pos: 509, buf[0-1]: '^'
UIPClient.write: writePacket(5) pos: 510, buf[0-1]: '.'
UIPClient.write: writePacket(5) pos: 511, buf[0-1]: 'õ'
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''
UIPClient.write: writePacket(5) pos: 512, buf[0-1]: ''

I’m new to the ethernet/internet side of programming so I don’t really know what this indicates other than its obviously having issues somewhere lol. Most of the packets that are sent stop at 51. Once it gets to 512 on packet(5) it just repeats the same thing.

Did you rename the UIPEthernet to Ethernet?

I’m using the UIPEthernet library. Yes i deleted the include for <SPI.h> and i renamed Ethernet.h to UIPEthernet.h

Try to adapt the software to use the UIPEthernet class and don’t rename the library because that may cause problems that are not apparent.

The UIPEthernet library doesn’t provide any examples for creating a web server that can be opened in a webpage. I’m assuming this is because it was supposed to be a drop in replacement for the ethernet library. I don’t know what would be different as everything I’ve googled uses things similar to the Ethernet library.

I'm new to the ethernet/internet side of programming so I don't really know what this indicates other than its obviously having issues somewhere lol. Most of the packets that are sent stop at 51. Once it gets to 512 on packet(5) it just repeats the same thing.

Post the code you're using, otherwise this output doesn't help a lot.

The UIPEthernet library doesn't provide any examples for creating a web server that can be opened in a webpage. I'm assuming this is because it was supposed to be a drop in replacement for the ethernet library. I don't know what would be different as everything I've googled uses things similar to the Ethernet library.

The UIPEthernet library does it's best to emulate the Ethernet library of the IDE but it will never show completely the same behavior as the original because the underlying hardware isn't the same. The kind of sketch you're using even doesn't work with some browsers using the original Ethernet shield. It sends every byte in a separate packet. What are you delivering with this sketch? Pictures?

The kind of sketch you're using even doesn't work with some browsers using the original Ethernet shield. It sends every byte in a separate packet.

Only if you send it that way. You can load stuff into a character or byte array and send the whole array as one packet with client.write().

with UIPEthernet you don't need to buffer output in own code. The library will do the buffering for you (in ENC28J60 internal memory not wasting valuable µC-ram). Using Version 1.09 (1.59 for Arduino IDE 1.5.x) the library will send a packet after 10ms of buffering latest (if there is no outstanding ACK). Previous version would wait up to 250ms to send buffered data.
Stock Ethernet-lib will send a packet on each call to client.write().

You might want to test a fix that fixes an issue with the transmit-logic of enc28j60 that is described in latest silicon-errata that would result in stall of transmit-logic not transmitting any further outgoing packages.

I've commited the fix to branch 'fix_errata12' GitHub - ntruchsess/arduino_uip at fix_errata12

(you may download as zip: https://github.com/ntruchsess/arduino_uip/archive/fix_errata12.zip)

I'd be glad to hear whether this fixes your issue.

Looks like worked better using the examples in the IDE. I still timed out but it tool longer to do so.

/*
Web Server

A simple web server that shows the value of the analog input pins.
using an ECN28j60 Ethernet shield.

Circuit:

  • Ethernet shield attached to pins 10, 11, 12, 13
  • Analog inputs attached to pins A0 through A5 (optional)

created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
updated to work with UIPEthernet 1-1-2015 by
Mike Zemering

*/

#include <SPI.h>
#include <UIPEthernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}

void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println(“new client”);
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you’ve gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == ‘\n’ && currentLineIsBlank) {
// send a standard http response header
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”); // the connection will be closed after completion of the response
client.println(“Refresh: 1”); // refresh the page automatically every 5 sec
client.println();
client.println("");
client.println("");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print(“analog input “);
client.print(analogChannel);
client.print(” is “);
client.print(sensorReading);
client.println(”
“);
delay(100);
}
client.print(“Running Time “);
client.print(millis()/1000);
client.println(” Seconds”);
client.println(””);
break;
}
if (c == ‘\n’) {
// you’re starting a new line
currentLineIsBlank = true;
}
else if (c != ‘\r’) {
// you’ve gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println(“client disonnected”);
}
}

I had a similar issue until recently. I have been working with both the ENC28J60 and some Nrf24L01+ transceivers, and something that is recommended with them is to solder a 3.3uF or more cap across VCC and ground. I tried this with the ENC28J60 and a 10uF electrolytic, and the freezes have completely stopped. I am now able to hit it with several requests/second and it doesn't freeze (prior to this, more than one request in a few seconds would cause it to hang.)

Here are the instructions for the nRF24L01 modules:

NOTE! Power Problems:
Many users have had trouble getting the nRF24L01 modules to work. Many times the problem is that the 3.3V Power to the module does not have enough current capability, or current surges cause problems. Here are suggestions:
Connect a .3.3 uF to 10 uF (MicroFarad) capacitor directly on the module from +3.3V to Gnd (Watch + and - !) [Some users say 10 uF or more..]
A separate 3.3V power supply (Maybe this one?)
A YourDuinoRobo1 Arduino compatible, which has an added 3.3V regulator (But maybe add a .1 uF capacitor on the radio module).
This is especially important if you are connecting the module with jumper wires.
If you design a printed circuit board that the module plugs into, add .1uf and 10uf capacitors close to the GND and 3.3V pins.
This is particularly noticeable when 3.3V power comes from a MEGA, Nano etc. that has only 50 ma of 3.3V power available. Newer boards like the YourDuinoRobo1 have 350 ma or more available and can run the high-power modules directly.

I just figured I'd put this out there and hope it helps anyone else.

Mark