UDP Write Hangs

I'm using Arduino 1.0 on a mega with the wiz5100 chip, I was checking out the NTP client that came with the IDE changed a couple things, mainly the NTP server I'm talking to, I'm at the office right now or I would post the code (really like I said its the default example)

But every once in a while the project completely freezes I added a couple of Serial.println to find out where and its Udp.write line.

Does anyone have any ideas why the Udp.write would freeze ?

I can post my code tonight but I thought that I would put this out there to see if any one had any ideas.

Thanks

Edit: Here is the code

#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>

byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

unsigned int localPort = 8888;      // local port to listen for UDP packets

IPAddress timeServer(199,167,198,163); // pool.ntp.org NTP server
//IPAddress timeServer = "hera.limescope.net";

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

int timeZoneHour = -4; 

long timeZoneOffset = (timeZoneHour * -1) * 60 * 60 ;
int NTP_Update_Interval = 60;


void setup() 
{
  Serial.begin(9600);
  Serial.println("Starting");
  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  Udp.begin(localPort);
  Serial.print("Got IP:");
  Serial.println(Ethernet.localIP());
  setSyncProvider(getNTPTime);
  setSyncInterval(NTP_Update_Interval);
}

void loop()
{
  time_t t = now();
  
  printDigits(hour(t));
  Serial.print(":");
  printDigits(minute(t));
  Serial.print(":");
  printDigits(second(t));
  Serial.print(" ");
  Serial.print(month(t));
  Serial.print("/");
  Serial.print(day(t));
  Serial.print("/");
  Serial.print(year(t));
  Serial.println();
  
  delay(10000); 
}

void printDigits(int digits){
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

boolean AlreadySent = false;

unsigned long getNTPTime()
{
  Serial.println("In getNTPTime");
  if (!Udp.parsePacket()) {
    Serial.println("In Send Packet");
    if (!AlreadySent) {
      sendNTPpacket(timeServer);
      Serial.println("Packet Sent");
      AlreadySent = true;
    } else {
      Serial.println("Packet Already Sent Skip");
    };
  } else {  
    Serial.println("Got Time Packet");
    Udp.read(packetBuffer,NTP_PACKET_SIZE);
 
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    unsigned long secsSince1900 = highWord << 16 | lowWord;  

    const unsigned long seventyYears = 2208988800UL + timeZoneOffset;      
    unsigned long epoch = secsSince1900 - seventyYears;  
    AlreadySent = false;  
    return epoch;    
  }
  Serial.println("No Time Packet Found");
  return 0;
}
// send an NTP request to the time server at the given address 
unsigned long sendNTPpacket(IPAddress& address)
{
  Serial.println("In sendNTPpacket");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  Serial.println("NTP packet Created");
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp: 		   
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Serial.println("UDP begin Packet");
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
  Serial.println("exiting sendNTPpacket");
}

Maybe. See reply #14 here:
http://arduino.cc/forum/index.php/topic,68624.0.html

It reads a 16 bit register from the w5100. That read function has a bug. The "605 Bug".
http://code.google.com/p/arduino/issues/detail?id=605

Normally it affects the 16 bit rx register read.

I applied the "605" patch and still nothing ...

I've done some more testing and it seems with the code I posted that after the 5th UDP write is were it freezes so I'm sure I'm doing something wrong (or there is some other bug)

Is there something you have to do to reset the connection ?

What is the last message displayed on the serial monitor?

And this happens only after the 4th send?

Yeah, only after the fourth post and its worse now

I downloaded and complied a new IDE from github thinking I didn't apply the patch right and it made the NTP stuff stop working (I think I get an over flow because the time is set to 2037) and it freezes on the UDP.parsepacket line

But to answer your earlier question the last thing I see from the 1.0 IDE downloaded from the download section with or without the 605 patch is

UDP begin Packet

Any pointers would be great ... thanks

I'm running a test with the NTP code from the examples included with IDE 1.0, modified for static ip and using my NTP server.

I am not having trouble with the write routine, but my NTP server starts returning bogus times after a few requests. I thought I might be polling the NTP server too often, so I slowed the updates to every 10 minutes, but that also started returning bad times after 3 updates.

After the first few updates, the "Seconds since Jan 1 1900 =" value is occasionally (not always) backing up a few minutes instead of going forward. Then after a couple more incorrect time updates, it starts sending the correct time again. Maybe I have discovered time travel? Or maybe it is something I am sending it in the request packet. I haven't figured that part out yet.

I just figured that part out, and maybe what is causing your crash. All requests now return the exact date/time. It was the SD SPI interface interfering with the w5100 transfer.

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

   // Here was my interference
   // Disable the SD SPI and all is ok
   pinMode(4,OUTPUT);
   digitalWrite(4,HIGH);

   // rest of your setup
}

edit: My bad. I had a bug in there. It is ok now.

It WORKS !

That was the problem the SD card reader was causing the issue ... I'm just wondering now how does that work with if I wanted to log some information or what not ... do I manually change pin 4 and 10 or does the framework take care of that for me ?

If you want to use the SD card, just use the SD.begin(4) function instead of disabling the SD SPI.

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

   SD.begin(4);
   // The SD function returns with its SPI disabled, so nothing needs to be done

   Ethernet.begin(mac,ip);
   // The ethernet function returns with its SPI enabled
   // so disable it, and now the low level read/write routine take care of the SS pins
   digitalWrite(10,HIGH);

   // rest of the setup
}

Now you can read and write to both without manipulating the SS pins on either interface.

Excellent SurferTim - thank you, saved my bacon!

However if the SPI causes so many problems why is it used at all on these boards?

thanks