Why is my Arduino Uno/Ethernet shield webserver generating gibberish?

Hi,

I'm creating a network connected light sensor. I've based the webserver component of it on examples and tutorials I've found. My problem is that about half the time it outputs a load of gibberish to the browser. It may work fine for some time then I get rubbish. I can't quite figure out any relationship between it and what the sketch is doing at the time.

I get stuff like this:

1 13:43:8
€Ø„&×Z¦dx«ëÕØHTTP/1.1 200 OK Content-Type: text/html mÑÖû¥ÇèÞÎíê襁ͯL¬Ã:ëbeYÈ߬öWïÄPúg™Ýa®d¢çÑóòÕ(СBÄ¿›iÂŒâ=£U&a¬²>l¨«¢gó‡û€X¸´³þ²‹HTTP/1.1 200 OK T(ÁÂ?ÑpùWtb0ªl/6¬( û‰ÔhÊ0¡Â&(¤AD5>l­%¬òÃH?;(ÎQ¶ŒØÙ¹À˜ñÛȲ£ˆ¦l.A›ª¶e#µpqD?ÓŽAÚ«²×²3²þe‰; 4§Q‚ÔÙ,±.1)n,ÄkE,–Š€ò”TTŶ¤Èç¾{LÃ67Bˆ2::7Ã)[¢¾õÅÐ_°cPmœŒ'^»äûÅ"·lé •±"ËúĸßÞi€©;ÜêÁÀ·?%)’[ô4Q…
Current Light Power Content-Type: text/html < ent-Curre1rong>Current Light Power: 1.1662337779 w/m2

ccumulated Insolation: 13.0389604568 J/m2
UV: 1.2025973796 w/m2<

System Time: 25/8/2011 13:44:42
Current Light Power: 1.1662337779 w/m2 - 1
Accumulated Insolation: 124.0441284179 J/m2

The output should look like this:

System Time: 25/8/2011 13:47:56
Current Light Power: 1.1740260124 w/m2 - 1
Accumulated Insolation: 353.5269775390 J/m2
UV: 1.2000000476 w/m2 - 1

Here is the relevent section of webserver code, although I'll post the entire sketch in pastebin in a sec:

Client client = server.available();

 if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // 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();
  
          client.println("<html>");
          client.println("<head>");
          client.println("<title>Pyranometer and UV Meter</title>");
          client.println("<meta http-equiv=\"refresh\" content=\"60\"> ");
          client.println("</head>");
          client.println("<body>");

          // output the value of the light sensors
          client.println("<p>");
          client.print("<strong>System Time:</strong> ");
          client.print(day());
          client.print("/");
          client.print(month());
          client.print("/");
          client.print(year()); 
          client.print(" ");
          client.print(hour());
          client.print(":");
          client.print(minute());
          client.print(":");
          client.print(second());

          client.println(); 
          client.print("
");          
          
          client.print("<strong>Current Light Power:</strong> ");
          client.print(tsl1_energy2, DEC);
          client.print(" w/m<sup>2</sup>  - ");
          client.print(tsl1_sens, DEC);
          client.print("
");
          client.print("<strong>Accumulated Insolation:</strong> ");
          client.print(jouleCounter, DEC);
          client.print(" J/m<sup>2</sup>");
          client.print("
");
          client.print("<strong>UV:</strong> ");
          client.print(tsl2_energy2, DEC);
          client.print(" w/m<sup>2</sup>  - ");
          client.print(tsl2_sens, DEC);
          client.print("</p>");  
  
          client.println("</body>");
          client.println("</html>");         
                 
          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();   
  
  }

Can anyone suggest where the problem may be coming from? Thanks,

David

Do you have a proper power supply connected and are you using proper cables?

Yeah checked the cables and using a plug pack power supply.

You can try it for yourself at http://storm.woodypointcomms.com.au:8231/. Half the time it works, the rest it doesn't.

You have a lot of strings that take up space in SRAM. I suspect that you are running out of memory. Search for the FreeMemory() function (on the forum), and see how much SRAM you have available, at different points in your application.

Seems to have 1065 bytes free. I've tested it both when it fails and doesn't fail. Still the same reading. The function is being called just after it outputs the last line of html. Thanks,

David

I've removed all the HTML now and am just serving plain text. This has meant i now have 1419 bytes free. However on one refresh instead of text I got binary data. When saved and viewed this turned out to be the current text only data interspersed with gibberish of the html pages that had previously been there. It's like the SRAM isn't being cleared and it's somehow getting old data from somewhere. The page it served me was 128kb of repeated HTML and stuff. Any ideas?

Thanks,

David

I've removed all the HTML now and am just serving plain text.

How did you do this without modifying code?

You didn't?

Why didn't you post the new code and sample data, then?

All I did was comment out all the lines containing html. After reading up I think I'm going to try to build a webserver from scratch with a bit more control of the buffers on the ethernet chipset and then integrate it. Thanks,

David

You might be closing the client connection before all the data has been sent. You are sending a lot of packets. I would increase the delay() time before closing the connection, or check the transmit buffer to insure it is empty.

Here is a thread that covers checking the transmit buffer free space. When client.free() returns 2048, all the data has been sent.
http://arduino.cc/forum/index.php/topic,72027.0.html

Edit: If you increase the delay time and it works, you are lucky. If you check the transmit buffer and it works, you are good.

FYI: Every call to client.print(), client.println(), and client.write() creates another packet. Count the packets you are sending just for the date.

There are write functions that are not covered in the docs. These are available (from Client.h):
virtual void write(uint8_t);
virtual void write(const char *str);
virtual void write(const uint8_t *buf, size_t size);

I use the last one. I build a "packet" in a local byte array (outBuffer of size packetSize), then send it in one call.

client.write(outBuffer,packetSize);

Check the transmit buffer free space before writing this tho. If there is not enough space in the transmit buffer, it will cause errors.

I use something like this:

while(client.free() < packetSize) {
  // don't write yet
  delay(5);
}

and this to determine when all is sent:

while(client.free() < 2048) {
  // don't stop yet
  delay(5)
}
client.stop();

I too had this problem with 4 shields and uno's. I have found that it happens when I have a micro SD inserted, but when I remove the SD, it works without fail. Call it a work around, but I would like to find a proper fix.
Duckie

@Duckie58: That sounds like a SPI collision. Both SD and ethernet use it. Maybe this thread will help.
http://arduino.cc/forum/index.php/topic,72027.15.html

I had to
set pin 10 high,
SD.open() and access the SD, then SD.close(),
set pin 10 low again.

That disables the ethernet SPI connection while the Arduino talks to the SD card.

Hi SurferTim,
Sounds logical. I will give it a try.

Thank you
Duckie

Don't feel bad about it. The IDE V0022 SD read/write library example suffers from the same malady.

It sets the pinMode on pin 10 to output, but doesn't:
digitalWrite(10,HIGH);
before the access, or
digitalWrite(10,LOW);
after the access.

I kept getting the "...initialization failed" error until I disabled the ethernet SPI during the access.