Go Down

Topic: Ethernet shield problems! Time to update library? (Read 29176 times) previous topic - next topic

Garito

Sorry eTracer but my network configuration is correct (I know it because I can ping the shield with the lets lighting correctly or, at least with let activity when I ping)

On these threat we discover client problems, it's easy to deduce that the ethernet shield was incorrect in the client and the server before the correction

This corrections was for the client but no for the server

Perhaps it's time to revise the server part

If not I would like to know if I neet to change the shield because is break or something like this

Need to know what to do

Thanks!

etracer

#31
Apr 17, 2009, 05:53 pm Last Edit: Apr 17, 2009, 05:55 pm by etracer Reason: 1
Just because the lights flicker on the shield doesn't mean you have your configuration correct. This only shows that there's activity on the ethernet link. If you can ping the Ethernet Shield from your computer and get a response, then that indicates your settings are probably at least partially correct.

And the server portion of the code uses the client code when connections are established. So the improvements to the client do affect the server side as well.

Garito

Then what solution you propose?

I configure my network by myself and the other computers works fine (have 2 macs and an Ubuntu laptop)

etracer

Answer the questions I posted several replies ago and maybe someone can help. But if you just want to complain that it doesn't work and not participate then no one will be able to help.

As a refresher, here are the questions again:

  • What operating system are you using on your computer?
  • What is your computer's IP address?
  • What's your subnet or netmask?
  • What's your gateway address?
  • How are you connecting your Ethernet Shield to the network? Is it connected to a hub/switch, or is the cable connecting directly to your computer?
  • Which LED's light up solidly when you plug the network cable into the Ethernet Shield?
  • Do the TX and RX LED's show any activity?


Additionally:
  • What IP address are you assigning to the Ethernet Shield in your sketch?
  • What is the subnet address you're assigning in your sketch?
  • What is the gateway address you're assigning in your sketch?
  • If you ping the IP address assigned in the sketch from your computer, what do you get?


Please also include the example sketch you're trying to use (that will answer the first 3 additional questions). There's been so much code included in the various topics that it's unclear what code you're trying to run.

Garito

First I want to apologize. I want to collaborate but I think my skill is not enoug

The questions you ask:

I use a MacBook unibody with Leopard
My IP is 192.168.1.77
Netmask: 255.255.255.0
Default gateway: 192.168.1.1
I try to connect the shield directly and with a switch

When I ping the shield the tx and rx lights on and the link led lights off in the same time

When I try to connect leds (tx and rx) lights on and the link one lights off 6 times and then nothing (it only blinks 2, 3 or 4 times more)

No connection. It raises a time out

This is the code I used:

#include <Ethernet.h>

// network configuration.  gateway and subnet are optional.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

// telnet defaults to port 23
Server server = Server(23);

void setup()
{
 // initialize the ethernet device
 Ethernet.begin(mac, ip, gateway, subnet);

 // start listening for clients
 server.begin();
}

void loop()
{
 Client client = server.available();
 if (client) {
   server.write(client.read());
 }
}

Thanks!

etracer

Well I set up my network the same as you listed and tested your sample telnet server code and it worked fine with both the original and improved Ethernet library. My test was even done on a MacBook Pro with OSX Leopard.

So either you have a defective ethernet shield (unlikely), or there's still some problem in your network.

Some more questions (including some you didn't answer last time around):
  • What LED's are lit solidly on the Ethernet shield when it's idle?
  • When you ping the address you assigned the Ethernet Shield from your MacBook, do you get a response? If so, copy the result in your reply.
  • What Arduino board and chip are you using?

Jose Bastos

Similar with the problem of the client that hangs if more than 4 connections are open simultaneously, I have the same problem setting up a server that has several simultaneous requests.

The server sends RST packets to the extra connections, but forgets to close correctly the 4 connections leaving then  half closed in the CLOSE_WAIT state. Therefore the server hangs forever with all sockets in use.

The following patch in Server.cpp (arduino 0017)

[font=Courier]void Server::begin()
{
 for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
   Client client(sock);
   if (client.status() == SOCK_CLOSED || client.status() == SOCK_FIN_WAIT || client.status() == SOCK_CLOSE_WAIT) {
     socket(sock, Sn_MR_TCP, _port, 0);
     listen(sock);
     EthernetClass::_server_port[sock] = _port;
     break;
   }
 }  
}[/font]

and moving server.begin() from setup to the main loop as shown below in the WebServer example seems to solve the problem

[font=Courier]/*
* Web Server
*
* A simple web server that shows the value of the analog input pins.
*/

#include <Ethernet.h>

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

Server server(80);

void setup()
{
 Ethernet.begin(mac, ip);
}

void loop()
{
 server.begin();
 Client client = server.available();
 if (client) {
   . . .
 }
}[/font]


Mavromatis

Jose,

Any updates on how this is working for you?  I just made these changes as well...

Jose Bastos

I ended up patching Client.cpp and Server.cpp (delivered with software version 0017).

arduino+ethershield have been running non stop for several months now.

You can get the patched code here
http://livewindreport.info/arduino/Client.cpp
http://livewindreport.info/arduino/Server.cpp

Mavromatis

#39
Aug 20, 2010, 05:09 am Last Edit: Aug 20, 2010, 05:11 am by Mavromatis Reason: 1
Do you guys know how we can use the full 8k of RX buffer of the W5100 chip?  Seems like we are set at 2048 for up to 4 socket connections.  Can we go 4k on two sockets max instead?  How can I make these changes?  

Here are some more details in this post: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282169385

lebelg

Hi guys,

I am totally new to this but I have read tons of posts and can't seem to find a fix for my problem. Here's the story:

My team and me created an installation for a museum. A part of it consist of small stations where visitors can scan their ticket and push a button (A or B). This answer is send to a server via a php request.

To make this happen, we use an Arduino Duomilanove, an ethernet shield (rev 4, so without the sd card slot), a stripped barcode scanner and some buttons and stuf.

Here's our problem: Everything works fine for a while when we reset the board and the ethernet shield. But after a random amount of scans, out software gets stuck at "connecting" (check the code below). The problem is that it never revives after that. I posteds the code below, I am very sorry it's so much lines, but we put a lot of effort in making it easy to change the ip and server etc.

Hopefully someone can help us with this issue. Here's the code:

/*
 VraagAntwoord

Software with the final hardware configuration

Version 1.7

*/

/*
Ethernet for sending messages to a server,
PS2Keyboard for reading barcodes,
EEPROM for writing/reading permanent data (questionId, IP addresses)
*/

#include <SPI.h>
#include <Ethernet.h>
#include <PS2Keyboard.h>
#include <EEPROM.h>

// Answers
#define YES 1
#define NO 0

#define VERSION "1.7"

// EEPROM addresses to write to (or with the ip addresses the address to begin writing to
#define ADDRQUESTION 0
#define ADDRSERVER 10
#define ADDRIP 20

// Ethernet reset pin
#define DO_RESET_ETH_SHIELD 9

#define RESET_AFTER_QUESTIONS 1

byte questionId = 1;

int answeredQuestions = 0;

/*
Barcode scanner
*/
int codeIRQPin = 2;
int codeDataPin = 3;

int codeLedPin = 4; // Connection status LED, blinking once: succes, blinking twice: connection failed

int ledAPin = 5;
int ledBPin = 6;
int buttonAPin = 7;
int buttonBPin = 8;

byte mac[] = {
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[4]; // Our ip
byte gateway[] = {
 172, 16, 0, 254 };
byte subnet[] = {
 255, 255, 255, 0 };
byte server[4]; // Server ip
Client client(server, 80);
PS2Keyboard keyboard;

// Buffer for the barcode reader
char codeBuffer[16]; // Should be enough to hold our barcodes
int codeBufferI;

char code[sizeof codeBuffer + 1]; // +1 for the null char

// Buffer for the serial port
char serialBuffer[32];
int serialBufferI = 0;

// The setup() method runs once, when the sketch starts
void setup()   {
 Serial.begin(9600);

 delay(1000);

 questionId = EEPROM.read(ADDRQUESTION);
 mac[5] = questionId; // mac address is dependent on the questionId

   //Serial.println("Reading server ip");
 readAddress(server, ADDRSERVER);

 //Serial.println("Reading this unit's ip");
 readAddress(ip, ADDRIP);

 //Serial.println("Setting pinModes ..");
 // LEDs
 pinMode(ledAPin, OUTPUT);
 pinMode(ledBPin, OUTPUT);
 pinMode(codeLedPin, OUTPUT);

 // Knoppen
 pinMode(buttonAPin, INPUT);
 pinMode(buttonBPin, INPUT);
 //Serial.println("Done");

 //Serial.println("Setting up ethernet ..");
 init_ethernet();

 delay(1000);

 //Serial.println("Setting up keyboard ..");
 keyboard.begin(codeDataPin, codeIRQPin);

 //Serial.println("Done");

 delay(1000);

 Serial.println();
 Serial.println();
 Serial.print("VraagAntwoord v");
 Serial.println(VERSION);
 Serial.println();
 Serial.print("questionId: ");
 Serial.println(questionId, DEC);
 Serial.print("ip: ");
 printAddress(ip);
 Serial.print("server ip: ");
 printAddress(server);

 Serial.println();

 usage();
}

void init_ethernet()
{
 Ethernet.begin(mac,ip,gateway,subnet);
 delay(1000);
}

// Add a char to the code buffer if possible, silently fails if not possible.
void addChar(char c) {
 if (codeBufferI < sizeof codeBuffer) {
   codeBuffer[codeBufferI] = c;
   codeBufferI++;
 }
}

//  the keyboard class's buffer
void Buffer() {
 while (keyboard.available()) {
   keyboard.read();
 }
}

void doRequest(const char * code, int answer) {
 Serial.print("Sending answer ");
 if (answer == YES) {
   Serial.print("YES");
 }
 else {
   Serial.print("NO");
 }
 Serial.println();
 Serial.println("connecting...");

 client.connect();

 delay(1000);

 if (client.connected()) {
   Serial.println("connected");

   char request[128]; // Should fit, somewhat dependant on the barcode length
   strcpy(request, "GET /in_question.php?code="); // Copy string to pointer to char[]
   strcat(request, code);
   strcat(request, "&qid=");
   sprintf(request+strlen(request), "%d", questionId);// Sprintf converts decimal number (%d) to int, places it in a string, starting at pointer location.
   strcat(request, "&answer=");
   sprintf(request+strlen(request), "%d", answer);
   strcat(request, " HTTP/1.0");

   Serial.println(request);
   client.println(request);

   delay(500);

   client.println();

   delay(500);

   digitalWrite(codeLedPin, HIGH);
   delay(200);
   digitalWrite(codeLedPin, LOW);

 }
 else {
   Serial.println("connection failed");
   digitalWrite(codeLedPin, HIGH);
   delay(200);
   digitalWrite(codeLedPin, LOW);
   delay(200);
   digitalWrite(codeLedPin, HIGH);
   delay(200);
   digitalWrite(codeLedPin, LOW);
 }

 while(client.connected()) {
   client.flush();
   client.stop();
   delay(1000);
 }

}

void readSerialChar(char c) {
 if (serialBufferI < sizeof serialBuffer) {
   serialBuffer[serialBufferI] = c;
   serialBufferI++;
 }

 if (c == '@') {
   switch(serialBuffer[0]) {
   case 'q':
     setQuestionId();
     break;
   case 's':
     setServer();
     break;
   case 'i':
     setIp();
     break;
   default:
     Serial.println("Invalid command.");
     usage();
   }

   for(int i=0; i < sizeof serialBuffer; i++) {
     serialBuffer = 0;
   }
   serialBufferI = 0;
 }
}

void readAddress(byte * dest, int eepromBeginAddr) {
 for(int i=0; i < 4; i++) {
   dest = EEPROM.read(eepromBeginAddr + i);
 }
}

void printAddress(byte * address) {
 for(int i=0; i < 4; i++) {
   Serial.print(address, DEC);
   if (i < 3) {
     Serial.print(".");
   }
 }
 Serial.println();
}

void writeAddress(byte * dest, int eepromBeginAddr) {
 byte address[4];

 int i = 1;
 for(int part=0; part < 4; part++) {
   byte value = 0;
   while (serialBuffer != '.' && serialBuffer != '@') {
     if (serialBuffer >= '0' && serialBuffer <= '9') {
       value *= 10;
       value += serialBuffer - '0';
       i++;
     }
   }
   address[part] = value;
   i++;
 }

 // Save the address to EEPROM
 for(int i=0; i < 4; i++) {
   EEPROM.write(eepromBeginAddr + i, address);
 }

 memcpy(dest, address, 4);
}

void setServer() {
 Serial.print("Setting new server ip address: ");
 writeAddress(server, ADDRSERVER);
 printAddress(server);
 Serial.println("remember to restart");
}

void setIp() {
 Serial.print("Setting new ip: ");
 writeAddress(ip, ADDRIP);
 printAddress(ip);
 Serial.println("remember to restart");
}

void setQuestionId() {
 int i = 1;
 byte value = 0;
 while(serialBuffer != '@') {
   value *= 10;
   value += serialBuffer - '0';
   i++;
 }

 Serial.print("Setting questionId to ");
 Serial.println(value, DEC);

 EEPROM.write(ADDRQUESTION, value);
 questionId = value;
}

// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
 // blink A and B status: ready

 digitalWrite(ledAPin, HIGH);
 digitalWrite(ledBPin, HIGH);
 delay (200);
 digitalWrite(ledAPin, LOW);
 digitalWrite(ledBPin, LOW);
 delay (200);
 digitalWrite(ledAPin, HIGH);
 digitalWrite(ledBPin, HIGH);
 delay (200);
 digitalWrite(ledAPin, LOW);
 digitalWrite(ledBPin, LOW);

 // Waiting for barcode
 Serial.println("Waiting for barcode");
 Buffer();
 boolean done = false;
 while (!done) {
   if (keyboard.available()) {
     char c = keyboard.read();
     if (c == PS2_ENTER) {
       Serial.print("[End of code]"); // Code ingelezen.
       Serial.println();
       addChar('\0'); // End the string
       strcpy(code, codeBuffer);
       codeBufferI = 0;
       Serial.print(code);
       Serial.println();
       done = true;
     }
     else {
       addChar(c);
       Serial.print(c);
     }
   }

   if (Serial.available() > 0) {
     readSerialChar(Serial.read());
   }
 }

 // Waiting for answer
 Serial.println("Waiting for answer");
 digitalWrite(ledAPin, HIGH);
 digitalWrite(ledBPin, HIGH);
 while (digitalRead(buttonAPin) == LOW && digitalRead(buttonBPin) == LOW) {
   delay(10);
 }
 digitalWrite(ledAPin, LOW);
 digitalWrite(ledBPin, LOW);
 if (digitalRead(buttonAPin) == HIGH) {
   // Geef antwoord "Ja"
   doRequest(code, YES);
 }
 else {
   // Geef antwoord "Nee"
   doRequest(code, NO);
 }

 checkReset();
}

void checkReset() {
 answeredQuestions++;
 if (answeredQuestions >= RESET_AFTER_QUESTIONS) {
   init_ethernet();
   answeredQuestions = 0;
 }
}

void usage() {
 Serial.println("Usage:");
 Serial.println("q<number>@                               Sets the questionId");
 Serial.println("s<number>.<number>.<number>.<number>@    Set the ip address of the server the data should go to");
 Serial.println("i<number>.<number>.<number>.<number>@    Set this unit's ip address");
 Serial.println();
 Serial.println("Commands can not be concatenated, one command at the time. Have fun!");
 Serial.println();
}



Thanks in advance for all your trouble!

Mavromatis

Awesome!  Love what you are doing.   Which version of the Arduino software are you using? Current is 21.  I am still running 18 and have no issues.  I've done a lot of work with the ethernet shield and libraries so I think I can help you out if I know what version you are using.

lebelg

Awsome for your superfast response!!!!!!!!!  :)

Version is latest. 21. Really hope you can help! The code is written by an intern and when he stopped I dove into it. I made a lot of changes and already fixed some other issues, but now I am stuck. Especially beacuse it works fine for a random amount of time (somewhere between 5 minutes and an hour). I already did like 30 succesfull scans after a reset and than after 15 minutes it still worked like a charm. After an hour of no activity it suddenly got stuck at connecting...... It feels totally random...

Thanks again for your trouble!

Mavromatis

Any chance you can try with 18?  21 has all the latest updates and I personally have stuck with 18 due to all the changes with the SPI.  

Mavromatis

One more thing... I'll look at the code later, just wanted to make sure about a few things.

You have 4 sockets avail with the W5100 and stock code offers 2k buffer on each are you exhausting the buffer and the app is crashing?  When it gets stuck on connecting it mean that either there is no available socket or you had a crash.  You need to make sure you close/release the sockets otherwise it will "lock".

Go Up