Show Posts
Pages: 1 [2]
16  Using Arduino / Networking, Protocols, and Devices / Re: W5100/Ethernet cannot use socket as UDP after using it as TCP on: April 26, 2013, 09:37:51 am
How very strange.  I'm using 1.0.4 also.  I've verified this on two different Ethernet Shields and a bunch of different Megas and Unos.  I wonder if there were different versions of the W5100 chip released?  What output do you get? 

Here's mine:
Code:
Start!
Socket#0:0x14 80 D:0.0.0.0(0)
Socket#1:0x0 0 D:0.0.0.0(0)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)

Socket#0:0x14 80 D:0.0.0.0(0)
Socket#1:0x22 8888 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
Unix time = 1366986649

Socket#0:0x14 80 D:0.0.0.0(0)
Socket#1:0x22 8888 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
Unix time = 1366986659

Socket#0:0x14 80 D:0.0.0.0(0)
Socket#1:0x22 8888 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
Unix time = 1366986669
new Client
Socket#0:0x17 80 D:192.168.10.213(9129)
Socket#1:0x14 80 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
GET / HTTP/1.1
Host: 192.168.10.20
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
If-Modified-Since: Fri, 02 Jun 2006 09:46:32 GMT

client disconnected

Socket#0:0x22 8888 D:192.168.10.1(123)
Socket#1:0x14 80 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
Unix time = 1366986679
new Client
Socket#0:0x14 80 D:192.168.10.1(123)
Socket#1:0x17 80 D:192.168.10.213(9132)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
GET / HTTP/1.1
Host: 192.168.10.20
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

client disconnected

Socket#0:0x14 80 D:192.168.10.1(123)
Socket#1:0x22 8888 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
UDP FAIL!

Socket#0:0x14 80 D:192.168.10.1(123)
Socket#1:0x22 8888 D:192.168.10.1(123)
Socket#2:0x0 0 D:0.0.0.0(0)
Socket#3:0x0 0 D:0.0.0.0(0)
UDP FAIL!

Once it goes into fail mode it'll never come back **for that socket**.  However, if you play around with refreshing your browser you can sometimes get it to bounce to a different socket and then it'll work.  (at least until that socket also has had a TCP conversation on it)  I've also verified through tcpdump packet capture that the packet doesn't actually get sent. 
17  Development / Suggestions for the Arduino Project / BUG: W5100 cannot use socket as UDP after using it as TCP on: April 25, 2013, 06:55:49 pm
I've detailed my description of this here: http://arduino.cc/forum/index.php/topic,162799.msg1216412.html

Pretty sure this is a bug.  I'm not sure if it's in the library or in the W5100 itself.  I've verified it on both the Uno and the Mega.  I've got 1.0.4.
18  Using Arduino / Networking, Protocols, and Devices / Re: W5100/Ethernet cannot use socket as UDP after using it as TCP on: April 25, 2013, 03:34:22 pm
So I've dummied up a test case from some of the Arduino samples.  All this does is create a TCP server on port 80, and every 10 seconds it'll poll an NTP server via UDP.  Here's what will happen:
* It'll start listening on port 80 (W5100 socket #0)
* It'll do the NTP stuff from port 8888 on W5100 socket #1.  (this works fine).
* It'll continue to do the NTP stuff every 10 seconds indefinitely and successfully.
* If you connect to the port 80 (e.g. browse there with a web server), it'll service the request on socket 0, and open a new listening port on socket 1, and then terminate socket 0.
* The NTP stuff continues every 10 seconds, but this time it's on socket 0.  It works..
* Browse to port 80 again.  This time it'll service on socket 1.
* NTP never works again.  Web server works just fine forever...

Here's the sketch.
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <utility/W5100.h>

void ShowSockStatus()
{
for (int i = 0; i < MAX_SOCK_NUM; i++) {
Serial.print("Socket#");
Serial.print(i);
uint8_t s = W5100.readSnSR(i);
Serial.print(":0x");
Serial.print(s,16);
Serial.print(" ");
Serial.print(W5100.readSnPORT(i));
Serial.print(" D:");
uint8_t dip[4];
W5100.readSnDIPR(i, dip);
for (int j=0; j<4; j++) {
Serial.print(dip[j],10);
if (j<3) Serial.print(".");
}
Serial.print("(");
Serial.print(W5100.readSnDPORT(i));
Serial.println(")");
}
}

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

EthernetServer server(80);
IPAddress timeServer(192,168,10,1);
IPAddress ip(192,168,10,20);
IPAddress gateway(192,168,10, 2);
IPAddress subnet(255, 255, 255, 0);

long timer;

void setup() {
Serial.begin(9600);
Ethernet.begin(mac, ip, INADDR_NONE, gateway, subnet);
delay(500);

Serial.println("Start!");
server.begin();
ShowSockStatus();
timer = millis();
}

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

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(EthernetUDP & Udp, IPAddress& address)
{

// 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;

// 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
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}

void checkTime()
{
EthernetUDP Udp;
Udp.begin(8888);
sendNTPpacket(Udp, timeServer); // send an NTP packet to a time server
Serial.println("");
ShowSockStatus();
// wait to see if a reply is available
delay(1000); 
if ( Udp.parsePacket() ) { 
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:

unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord; 

// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;     
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears; 
// print Unix time:
Serial.println(epoch); 

else
Serial.println("UDP FAIL!");
Udp.stop();

}

void loop()
{
//Check if a web client has attached.
EthernetClient client = server.available();
if (client) {
Serial.println("new Client");
ShowSockStatus();
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.print(c);
if (c == '\n' && currentLineIsBlank) {
client.stop();
}
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 disconnected");
}

if ((millis() - timer) > 10000) {
timer = millis();
checkTime();
}
}
19  Using Arduino / Networking, Protocols, and Devices / W5100/Ethernet cannot use socket as UDP after using it as TCP on: April 25, 2013, 02:18:02 pm
So here's the issue.  If I use any of the 4 W5100 sockets as at TCP socket that sends/receives data, it seems to disqualify that socket from sending out UDP datagrams anymore.  Calling a W5100.init() seems to fix the issue, but of course that resets all of my sockets.
Has anyone experienced this before? 
20  Using Arduino / Programming Questions / Re: Reflashing my sketch from within my sketch. on: April 24, 2013, 06:20:09 pm
Thanks everyone.  I actually went through the code and found the code in the CDC.cpp file that waits for the DTR to go high and then resets the board back to the bootloader.

OK,  so does anyone have a suggestion for a good bootloader that loads the sketch off a SD card?  I've seen a few floating around out there in the intertubes, but have not actually played around with any of them.
21  Using Arduino / Programming Questions / Re: Reflashing my sketch from within my sketch. on: April 24, 2013, 04:04:32 pm
Hmmmm.  OK, so then how exactly does flashing work while you're normally connected via the USB port?  i.e. I'm running my program (the bootloder has long ago passed control to my program), but then I hit the program button on the Arduino console and somehow my code gets flashed.  Does the USB UART controller have some means of halting my program and passing control back to the bootloader?
22  Using Arduino / Programming Questions / Reflashing my sketch from within my sketch. on: April 24, 2013, 12:16:38 pm
So, I'd like to reflash my Arduino from my running sketch.  I'd get the sketch binary from some place like an Ethernet socket or from the SD card.  I've seen bootloaders that can do this, but I'm wondering if it's possible to actually do it from my running sketch and not change the bootloader?

I'm guessing there will be issues revolving around the idea of overwriting the sketch while I'm actually running code in it, but maybe there's a way to jump to a section or something that does all the overwrite except for the actual overwrite code.  Make any sense?
23  Using Arduino / Networking, Protocols, and Devices / Re: More efficient socket / Ethernet library? on: April 17, 2013, 09:29:20 pm
Apparently this was submitted as an issue to the Arduino dev team back in 2011 : https://code.google.com/p/arduino/issues/detail?id=563

It was apparently dropped.

There was also a good discussion about it back in 2009.  What I would call a "proper" solution was not what was implemented. 
24  Using Arduino / Networking, Protocols, and Devices / Re: More efficient socket / Ethernet library? on: April 17, 2013, 05:29:58 pm
Figured I'd post a little more information.

Incidentally, most implementations of Berkeley Sockets implement something similar to what I'm commenting on through the Nagle algorithm (unless you set a sock option TCP_NODELAY...which will essentially mimic what the Arduino library currently does).

Here's what happens when you call EthernetClient::write().
EthernetClient::write() does some error checking and then calls send() from the socket.h library
send() will incrementally send each byte of the buffer through the SPI bus to the W5100 (through the W5100Class::send_data_processing_offset function).  Once it's all there, it instructs the 5100 to send it right away, and then sits there and waits for the ACK response to come back from the remote host.
25  Using Arduino / Networking, Protocols, and Devices / More efficient socket / Ethernet library? on: April 17, 2013, 04:34:11 pm
So I'm having some issues here with efficiency on the socket / Ethernet library and TCP.
NOTE:  This applies to the TCP operation mode. 

Specifically, when you call the write() function on the client, it actually copies the buffer to the W5100, and then sends a packet.  That's all fine and good if you want to send the packet right then, but frequently it is far more efficient to build up a buffer of what you want sent, and then send out full size packets as necessary.  The worst case situation here would be to call write one byte at a time as you'll send out a packet for every single byte.  That's horribly inefficient.

Now, of course I could build a buffer myself in RAM and do essentially the same thing, but that wastes RAM, and there's a perfectly good 2kB buffer on the W5100 that I could use.  Ideally I'd like to send data to the 5100 buffer myself and then trigger a command to actually fire off the packet when I'm ready (or perhaps automatically if the buffer becomes full).

Has anyone done this already?

Incidentally, in the socket library it appears that there is already something like this setup for UDP sockets with the startUDP, bufferData and sendUDP functions.

Pages: 1 [2]