Ethernet shield madness

Hello,

I have an old ethernet shield (with the full-size SD card slot) and an arduino duemilanove (atmega328p), when I upload the ChatServer example and I open a connection with telnet it seems that my arduino gets a lot of garbage even before I start to type in the terminal.

My serial terminal outputs:

We have a new client

ÿý
ÿû
ÿû
ÿû ÿû!ÿû"ÿû'ÿý
ÿû#ÿû
ÿþ
ÿþ
ÿþ ÿþ!ÿþ"ÿþ'ÿü
ÿþ#Z[£¨vÁ
2?
?ñ|
?z|
? úP”æPÊ
_
\ÂÂ!QT?U4øؐ1e?Q?JMù
?Õ!+
+ªcé%a?´Ú_E«­Ø
¯?n)A”

¿Hãd?¤ðgÿB

And my telnet:

mig@laptop ~ $ telnet 192.168.1.177
Trying 192.168.1.177...
Connected to 192.168.1.177.
Escape character is '^]'.
Hello, client!
2[ch65533][[ch65533][ch65533]v
  [ch65533][ch65533]|
[ch65533]z|
[ch65533]P[ch65533][ch65533]P[ch65533]
\[ch65533][ch65533]!QT[ch65533]U4[ch65533][ch1552]1e[ch65533]Q[ch65533]JM[ch65533]
[ch65533][ch65533]!++[ch65533]c[ch65533]%a[ch65533]_E[ch65533][ch65533][ch65533]
[ch65533][ch65533]n)A[ch65533]
                                                           
[ch65533]H[ch65533]d[ch65533][ch65533][ch65533]g
[ch65533]*[ch65533]

 0[ch65533]
[ch65533][ch65533][ch65533][ch65533]
[ch65533]V*[ch65533]

[ch65533]=,[ch1309];][ch65533][ch65533]
F[ch65533][ch65533][ch65533]P[ch65533]
\[ch65533][ch65533]!QT[ch65533]U4[ch65533][ch1552]1e[ch65533]Q[ch65533]JM[ch65533]
[ch65533][ch65533]!++[ch65533]c[ch65533]%a[ch65533]_E[ch65533][ch65533][ch65533]
[ch65533][ch65533]n)A[ch65533]
                                                                   
[ch65533]H[ch65533]d[ch65533][ch65533][ch65533]g
[ch65533]*[ch65533][ch65533][ch65533]
[ch65533]V*[ch65533]

[ch65533]=,[ch1309];][ch65533][ch65533]
F[ch65533][ch65533]M[ch65533]
[ch65533][ch65533]!++[ch65533]c[ch65533]%a[ch65533]_E[ch65533][ch65533][ch65533]
[ch65533][ch65533]n)A[ch65533][ch65533][ch65533]\[ch65533]
[ch65533] [ch65533][ch65533]0[ch65533]s<[ch65533]1w[ch65533]e[ch65533]9@e[ch65533][ch65533]#
                                               
[ch65533]H[ch65533]d[ch65533][ch65533][ch65533]g
[ch65533]*[ch65533]

 0[ch65533]
[ch65533][ch65533]8[ch65533][ch65533]Sa[ch65533][ch333]Zn[ch65533]A[ch357][ch65533][ch65533]
[ch65533]V*[ch65533]

[ch65533]=,[ch1309];][ch65533][ch65533]
F[ch65533][ch65533][ch65533]n)A[ch65533]$[ch65533][ch65533]\[ch65533]
[ch65533] [ch65533][ch65533]0[ch65533]s<[ch65533]1w[ch65533]e[ch65533]9@e[ch65533][ch65533]#
                          
[ch65533]H[ch65533]d[ch65533][ch65533][ch65533]g
[ch65533]*[ch65533]

 0[ch65533]
[ch65533][ch65533]8[ch65533][ch65533]Sa[ch65533][ch333]Zn[ch65533]A[ch357]3y
U
'a[ch844][ch65533][ch65533]

[ch8719]v4[ch65533][ch65533]x[ch65533][ch65533]"#[ch65533][ch65533]
[ch65533]V*[ch65533]

[ch65533]=,[ch1309];][ch65533][ch65533]
F[ch65533][ch65533]

 0[ch65533]
[ch65533][ch65533]8[ch65533][ch65533]Sa[ch65533][ch333]Zn[ch65533]A[ch357]3y
U
'a[ch844][ch65533][ch65533]

[ch8719]v4[ch65533][ch65533]x[ch65533][ch65533]"#[ch65533]}[ch65533]
\$[ch65533][ch65533]\[ch65533]
[ch65533] [ch65533][ch65533]0[ch65533]s[ch65533][ch65533]
[ch65533]V*[ch65533]

[ch65533]=,[ch1309];][ch65533][ch65533]
F[ch65533][ch65533][ch1309];][ch65533][ch65533]
F[ch65533][ch65533]^C[ch65533][ch65533]
[ch65533][ch65533]
[ch65533][ch65533]
[ch65533][ch65533]
[ch65533][ch65533]
^]e[ch65533][ch65533]#[ch65533][ch65533]0[ch65533]s<[ch65533]1w[ch65533]e[ch65533]9@e[ch65533][ch65533]#
telnet> Connection closed.

Playing with the code I found that checking the number of bytes recived by the client fixes (to some extent, still gettin a little bit of garbage) this issue, these are my modifications to ChatServer:

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// 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, 0, 0 };

// telnet defaults to port 23
Server server(23);
boolean gotAMessage = false; // whether or not you got a message from the client yet

void setup() {
  // initialize the ethernet device
  Ethernet.begin(mac, ip, gateway, subnet);
  // start listening for clients
  server.begin();
  // open the serial port
  Serial.begin(9600);
}

void loop() {
  // wait for a new client:
  Client client = server.available();
  
  // when the client sends the first byte, say hello:
  if (client) {
    if (!gotAMessage) {
      Serial.println("We have a new client");
      client.println("Hello, client!"); 
      gotAMessage = true;
    }

    char availableChars = client.available();
    if (availableChars > 0) {
      Serial.print("got: ");
      Serial.println(availableChars, DEC);
    }
    while (availableChars) {
      // read the bytes incoming from the client:
      char thisChar = client.read();
      // echo the bytes back to the client:
      server.write(thisChar);
      // echo the bytes to the server as well:
      Serial.print(thisChar);
      availableChars--;
    }
  }
}

My serial terminal outpus:

We have a new client

got: 27

ÿý
ÿû
ÿû
ÿû ÿû!ÿû"ÿû'ÿý
ÿû#got: 27

ÿû
ÿþ
ÿþ
ÿþ ÿþ!ÿþ"ÿþ'ÿü
ÿþ#got: 1

hgot: 1

ogot: 1

lgot: 1

a

And my terminal outputs:

mig@laptop ~/files/arduino-0021 $ telnet 192.168.1.177
Trying 192.168.1.177...
Connected to 192.168.1.177.
Escape character is '^]'.
Hello, client!
hhoollaa

As you can see, I am using the char type for availableChars, this is “wrong” because the available method in Client class must output an integer, but if I use an integer I still get a lot of garbage (bad recived size) before I send something in the terminal.

Diggin furter in the code I see that the W5100 has a 16 bit register to store the size of the recived buffer. ¿Whats the deal here? My intuition tells me that there is some problem when the Ethernet library reads the SnRX_RSR register in the W5100, the datasheet (version 1.1.6) says the SnRX_RSR register is unsigned… but before diggin more i like to ask :slight_smile:

Thanks a lot.

As you can see, I am using the char type for availableChars, this is "wrong" because the available method in Client class must output an integer, but if I use an integer I still get a lot of garbage (bad recived size) before I send something in the terminal.

The available method does return an int. However, since the value is usually small, it will fit into a char variable. But that doesn't mean that it should be stored in a char variable.

Along with printing the character received, I'd try printing it as a character and as a decimal, to see what is actually received. The y with the two dots is what you get when you try to print a -1.

As you can see, I am using the char type for availableChars, this is "wrong" because the available method in Client class must output an integer, but if I use an integer I still get a lot of garbage (bad recived size) before I send something in the terminal.

The available method does return an int. However, since the value is usually small, it will fit into a char variable. But that doesn't mean that it should be stored in a char variable.

That's my point! I don't know if my shield don't work or the library is doing something strange with the number of recived bytes, for example:

void loop() {
  // wait for a new client:
  Client client = server.available();
  
  // when the client sends the first byte, say hello:
  if (client) {
    if (!gotAMessage) {
      Serial.println("We have a new client");
      client.println("Hello, client!"); 
      gotAMessage = true;
    }

    int availableChars = client.available();
    //if (availableChars > 0) {
    Serial.print("available: ");      
    Serial.print(availableChars, DEC);        
    Serial.print(" - "); 
    Serial.println(availableChars, BIN);
    //}
    while (availableChars) {
      // read the bytes incoming from the client:
      char thisChar = client.read();
      // echo the bytes back to the client:
      server.write(thisChar);
      // echo the bytes to the server as well:
      //Serial.print(thisChar);
      availableChars--;
    }
  }
}

And when the client connects my serial termial outputs:

We have a new client
available: 283 - 100011011
available: 307 - 100110011
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 289 - 100100001
available: 295 - 100100111
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 280 - 100011000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000
available: 256 - 100000000

what i am missing? is my shield not working? As I said before the available method just reflects the value in the SnRX_RSR register of the w5000 and i understand is a 16-bit unsigned int... :frowning:

Along with printing the character received, I'd try printing it as a character and as a decimal, to see what is actually received. The y with the two dots is what you get when you try to print a -1.

I think is garbage in the recive buffer of the w5000, sometimes it has previous connections data.

Thanks a lot!

I think there is a definite bug. As you said, the getSn_RX_RSR function in the w5100.c file returns an uint16 (unsigned int) to Client::available, which then returns that value to you as an int.

The Client::available function should return an unsigned int.

If you subtract 256 from the number of bytes that are supposedly available to read, does the result correspond to the number of bytes that can actually be read?

If you ignore the value returned by Client::available(), and simply use Client::read() in a loop until it returns -1, does that still result in garbage being returned? Does the number of bytes that can actually be read correlate to the value returned by Client::available()?

If you subtract 256 from the number of bytes that are supposedly available to read, does the result correspond to the number of bytes that can actually be read?

No, I haven’t send anything in my examples to the shield, I just open the connection and the garbage come in :frowning:

If you ignore the value returned by Client::available(), and simply use Client::read() in a loop until it returns -1, does that still result in garbage being returned? Does the number of bytes that can actually be read correlate to the value returned by Client::available()?

For example (am I getting your idea right?):

void loop() {
  Client client = server.available();
  if (client) {
    Serial.println("new client!"); 
    while (client.connected()) {
      int thisChar = client.read();
      if (thisChar != -1) {
        Serial.print("thisChar: "); 
        Serial.println(thisChar, BIN);
      }
    }
    client.stop();
  }
}

The serial output, even before try to send any data is:

new client!

thisChar: 11111111

thisChar: 11111101

thisChar: 11

thisChar: 11111111

thisChar: 11111011

thisChar: 11000

thisChar: 11111111

thisChar: 11111011

thisChar: 11111

thisChar: 11111111

thisChar: 11111011

thisChar: 100000

thisChar: 11111111

thisChar: 11111011

thisChar: 100001

thisChar: 11111111

thisChar: 11111011

thisChar: 100010

thisChar: 11111111

thisChar: 11111011

thisChar: 100111

thisChar: 11111111

thisChar: 11111101

thisChar: 101

thisChar: 11111111

thisChar: 11111011

thisChar: 100011

thisChar: 10011001

thisChar: 0

thisChar: 10110000

thisChar: 1010100

thisChar: 10001010

thisChar: 101011

thisChar: 100010

thisChar: 10001

thisChar: 1110110

thisChar: 1111111

thisChar: 11111

thisChar: 11011010

thisChar: 1000000

thisChar: 11001000

thisChar: 110111

thisChar: 10011010

thisChar: 10101100

thisChar: 11001001

thisChar: 1010010

thisChar: 10000100

thisChar: 11010000

thisChar: 11100001

thisChar: 10000101

thisChar: 1101101

thisChar: 10011011

thisChar: 10110101

thisChar: 10111000

thisChar: 1011010

thisChar: 1

thisChar: 1011011

thisChar: 100011

thisChar: 10101000

thisChar: 1110110

thisChar: 11000001

thisChar: 1101

thisChar: 110010

thisChar: 10011011

thisChar: 1100

thisChar: 10000011

thisChar: 11110001

thisChar: 1111100

thisChar: 11111

thisChar: 10011010

thisChar: 1111010

thisChar: 1111100

thisChar: 10

thisChar: 10001110

thisChar: 10101000

thisChar: 11111010

thisChar: 1010000

thisChar: 10010100

thisChar: 11100110

thisChar: 1010000

thisChar: 11001010

thisChar: 10010

thisChar: 1011111

thisChar: 11000

thisChar: 1011100

thisChar: 11100010

thisChar: 11000010

thisChar: 10010001

thisChar: 1010100

thisChar: 10001011

thisChar: 1010101

thisChar: 110100

thisChar: 11111000

thisChar: 11011000

thisChar: 10010000

thisChar: 110001

thisChar: 100101

thisChar: 10011000

thisChar: 1010001

thisChar: 10011011

thisChar: 1001010

thisChar: 1001101

thisChar: 11111001

thisChar: 11111

thisChar: 10011010

thisChar: 11011101

thisChar: 100001

thisChar: 10101011

thisChar: 111

thisChar: 1101011

thisChar: 10101011

thisChar: 1100011

thisChar: 11101001

thisChar: 100101

thisChar: 1100001

thisChar: 10001110

....
.....

Thanks!

Hi,

did you ever find out what the problem is?
I'm having the same problem.

greetz
alex

No, the diagnose is that the ethernet chipset in my shield have a bug.

If you want try this sketch and post your serial ouput to tell you if its the same problem.

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

byte mac[] = { 0xDE,0xAD,0xBE,0xEF,0xFE,0xED};
byte ip[] = { 192,168,1,7};
byte gateway[] = { 192,168,1,1};
byte subnet[] = { 255,255,255,0};

Server server(23);

void setup()
{
        Ethernet.begin(mac, ip, gateway, subnet);
        server.begin();
        Serial.begin(9600);
}

void loop() 
{
        Client client = server.available();

        if (client)
        {
                Serial.println("new client!"); 
                while (client.connected())
                {
                  char availableChars = client.available();
                  
                  if(availableChars)
                    {
                      Serial.print("availableChars: "); 
                      Serial.println(availableChars, HEX);
                      while (availableChars)
                        {
                          int thisChar = client.read();
                          Serial.print("thisChar: "); 
                          Serial.println(thisChar, HEX);
                          availableChars--;
                        }
                    }
                }
                client.stop();
        }
}

Manuel: I tried the last sketch you posted on a Arduino Uno with a new Ethernet Shield (w/ micro-SD card slot). When I first connect with telnet, I see some garbage characters in the serial terminal, but after that it seems to work fine, at least when typing small numbers of characters at a time.

I believe the initial garbage is my telnet program trying to configure the telnet connection. There are various options for the connection and a binary protocol for configuring them. Could that be what you're seeing?

Thanks for your attention David!

The problem with my shield is that after my telnet client sends his capabilites I still read gargabe, it seems that the method Client::available() always return a bad character count.

I also raised this issue at the developers list and David L. Martin offer me some help (off the list). The diagnose we conclude is that my WIZnet chip has a hardware issue and it always return the 0x100 bit set of the receive buffer size.

My serial output compared with one from David Martin is:

availableChars: 11B // insteadof just 1B
thisChar: FF
thisChar: FD
thisChar: 3
thisChar: FF
thisChar: FB
thisChar: 18
thisChar: FF
thisChar: FB
thisChar: 1F
thisChar: FF
thisChar: FB
thisChar: 20
thisChar: FF
thisChar: FB
thisChar: 21
thisChar: FF
thisChar: FB
thisChar: 22
thisChar: FF
thisChar: FB
thisChar: 27
thisChar: FF
thisChar: FD
thisChar: 5
thisChar: FF
thisChar: FB
thisChar: 23      // last byte of the telnet announce
thisChar: 99      // i think here begins to read outside the used buffer
thisChar: 0
thisChar: B0
....
....
availableChars: 100 // that bit!
thisChar: 99
thisChar: 0
thisChar: B0
thisChar: 56
thisChar: 8A
....
....
availableChars: 100 // again!
thisChar: 99            // also the output is the same than the last one
thisChar: 0             //  i think i am reading the buffer many times without even being changed
thisChar: B0
thisChar: 56
thisChar: 8A
thisChar: 2B
thisChar: 22

By the way, my ethernet shield is an old one with the full size SD slot.