Ethernet Communication - Timing Throuble????

Hi everybody,

I got an Arduino UNO plus Ethernet shiled, my goal is to make it talking as TCP client to an external device.
Arduino has to send in output two commands as array of bytes, the first is to load a set of parameters, the second command`s aim is to start the ext. device itself.

Everything works beautiful, paramters are loadedd and the device is started, now I would like to read and show on serial monitor the answer from the Receiver, this is a RFID industrial system and I would like to get data which it is reading...
The problem is a (i guess) bad timing on the ethernet bus, using the code:

if (client.available()) {
char c = client.read();
Serial.print(c, HEX);
}

The HEX stream showed on serial monitor is:
FFFFFFAAFFFFFFBB151EFFFFFF800FFFFFFAAFFFFFFCCFFFFFFAAFFFFFFBB1511FFFFFF810FFFFFFAAFFFFFFCCFFFFFFAAFFFFFFBB1511FFFFFFC1FFFFFFFF116230310102FFFFFF84241320FFFFFFAAFFFFFFCC.

Now, I have extablished this communication with an industrial PLC (ext. device-PLC) and I know the answer should be:
AABB151800AACC.

I don`t understand where those F are coming from...
Anybody can help me out??

Thanks

Claudio

FF is hex for 255 or -1. That is the return value if there are no characters available in the client rx buffer. I'm not certain why client.available() is returning true if nothing is in the rx buffer.

What version of IDE are you using?
Any other devices connected to the Arduino besides the ethernet shield?
Is there an SD card in the shield's slot?

IDE you mean the siftware`s version? 1.0.5
Nothing else connected, the communication is straight from a RJ-45 (arduino) to M12 (ext. device).
No SD card on the shield.

Post a link to the M12, preferably a page with a datasheet or manual.

edit: and post your entire sketch.

What do you mean with a link?
The M12 is just the type of connection, as RJ-45 is the socket normally used in office, industrial environment, M12 is a connector high-IP rated for outdoor.
This is nothing connected with the physical communication.

I wonder why the reading of F bytes always come in a sequence of 6 bytes...
Client.available() gives as result the number of available bytes, client.read() read a byte at the time.
It does not make much sense to me.

Sorry, I missed the last part, following the skrech I have loaded into Arduino:

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

#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte abyStartReceiver[] = {0xAA, 0xBB, 0x01, 0x01, 0x11, 0x01, 0xAA, 0xCC };
byte abyLoadParameter1[] = {0xAA, 0xBB, 0x01, 0x01, 0x1E, 0x00, 0x01, 0xAA, 0xCC};
boolean bStartEnabled = false;
byte byReceived;
IPAddress serverIP(192,168, 0, 1);
int serverPort=4007;
EthernetClient client;

int msg;

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

IPAddress IP(192,168,0,177); //static assignment of IP address
Ethernet.begin(mac,IP); //if not specified gateway=192.168.0.1 and subnet=255.255.255.0

delay(1000);
pinMode(2, INPUT);
Serial.println("connecting to Server ...");

// if you get a connection to the Server
if (client.connect(serverIP, serverPort)) {
Serial.println("Connected");//report it to the Serial
Serial.println("Load Parameters 1 ");//log to serial
client.write(abyLoadParameter1, 9);//send the message
delay(1000);
Serial.println("Sending START Message ");//log to serial
client.write(abyStartReceiver, 8);//send the message
client.stop();
}
else {
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
}

void loop()
{
delay(50);

bStartEnabled=digitalRead(2);
if(bStartEnabled)
{
if (client.connect(serverIP, serverPort)) {
Serial.println("Connected");//report it to the Serial
Serial.println("Load Parameters 1 ");//log to serial
client.write(abyLoadParameter1, 9);//send the message
delay(1000);
Serial.println("Sending START Message ");//log to serial
client.write(abyStartReceiver, 8);//send the message
bStartEnabled=false;
}
else {
// if you didn't get a connection to the server:
Serial.println("connection failed");
client.stop();
}
}

if (client.available()) {
char c = client.read();
Serial.print(c, HEX);
}

}

As I said the skrech itself is straightforward, during the setup opens a socket and send Load Parameter 1 and Start Receiver commands.
If something happens during execution, through D2 is possible to re-inizialite the ext. device.
NB. Library Newping is inserted but never used...

Everything works nice, the only problem is the receiving buffer, this is beyond the functionalities I need for this project but still I would like to understand what is happening.
Thank you.

I don't understand the connection procedure. You connect to the device in setup, then disconnect immediately by calling client.stop(). After the disconnect and if pin D2 is LOW, you attempt to read from the now closed connection in loop. ??

The TCP link is initializated during setup, then two commands are sent from Arduino, Load Parameter 1 and Start.
Then the link is closed.

During the loop nothing happens, only if something happens to the ext device needs a re-start, through a PB (LOW or HIGH level is only a matter of using a NO or NC contact) the operator can re-inizialize the device.
In this conditions, also, the communication is shown on serial monitor until the TCP link is active.

Claudio_Baldo:
During the loop nothing happens, only if something happens to the ext device needs a re-start, through a PB (LOW or HIGH level is only a matter of using a NO or NC contact) the operator can re-inizialize the device.
In this conditions, also, the communication is shown on serial monitor until the TCP link is active.

That is not true. You are trying to read from a closed connection. This is in loop:

if (client.available()) {
 char c = client.read();
 Serial.print(c, HEX);
}

edit: You are complaining about the characters you are receiving from the device. Show me where else in your code you are receiving characters from that device.

No, this is not correct.
The connection is closed after setup, however, if D2 is put HIGH during loop, the connection is opened again and it will stay ON until D2==HIGH && client.connect(serverIP, serverPort)==TRUE.
Of course if then put to GND (D2==FALSE) the connection wont be able to close down due the second if loop is nested inside the first condition D2==TRUE...
i.e. on serial monitor will be shown the sequence (during setup):
"connecting to Server ..."
"Connected"
"Load Parameters 1 "
"Sending START Message "
And nothing else after this.
If D2 is activated, the monitor will write again:
"connecting to Server ..."
"Connected"
"Load Parameters 1 "
"Sending START Message "
and then the string of byte which it is receiving:
FFFFFFAA......
until the communication is opened.
if D2 is kept HIGH the connection may eventually close down, if D2 is only triggered and then put to GND, the communication cannot be closed, it will stay ON forever.

This is to say, in case I am trying to read from a closed connection function client.available() will return FALSE, not byte available.
This function will return TRUE only if there are available byte and to do so, the connection must be opened...
I am wondering why I receive the sequence of FF, if the connection is closed arduino does not receive anything, I have already tested it.

Sounds like a job for wireshark.

Now I really don`t understand what is going on...
The only packet which wire shark detect on the bus is the ARP to get the MAC for 19.168.0.1. (because it is brodcasted)
Wireshwark does not find packet from 192.168.0.1 (ext. device) to 192.168.0.177 (arduino).
If I use my laptop and Hercules to trigger the device then wireshark finds TCP packets from 192.168.0.1 to 192.168.0.10 (Laptop).
In such a case the communication happens as it should be:
AACC.......AABB.
AACC is the start of a packet and AACC is the end.

Is there any way to detect everything on the network no matter which source or destination?
I had a though, FFFFFFFF may be a broadcast address in IPv4 but it does not make much sense is it?

Claudio_Baldo:
Wireshwark does not find packet from 192.168.0.1 (ext. device) to 192.168.0.177 (arduino).

Yes. Your Arduino, your PLC and your PC are plugged into an Ethernet switch. Wireshark on your PC, can only decode packets directed to your PC by the switch.

Is there any way to detect everything on the network no matter which source or destination?

Yes there is but unless you have an old hub sitting around, you will probably just end up spending more time being distracted by Wireshark, trying to confirm what you already know; your sketch is not decoding the PLC protocol quite right.

I had a though, FFFFFFFF may be a broadcast address in IPv4 but it does not make much sense is it?

Nice thought but the Ethernet and IP addresses should have been stripped off the packet by the shield's library code.

Lets go back to the sketch code you posted.

Your PLC follows a protocol and it is essential for your Arduino to follow the same protocol. For instance, after sending 'Load Parameters' I would expect the PLC to send an acknowledgement but your sketch does not wait for one. Over a couple passes through your loop code, the logic resolves to (roughly) If pin2 is high, send the load command, then the start command, pause for a second, then try to read one character, then disconnect. This does not sound right.

Here is a code example. It will not be right and I haven't even tried to compile it. It will (still) be closer to what you want, than what you have. Hopefully the example will provide you with a few ideas.

//some variables for a  simple state machine
bool clientConnected = false;
bool sendLoadParams = false;
bool sendStartCommand = false;

void loop() {

  //The PLC has not stopped, so why do you?
  //delay(50);                    

  //I really can not fathom what pin 2 is supposed to do, so I will ignore it for now
  //bStartEnabled=digitalRead(2);

  //if not connected then try to connect else stop.
  if(!clientConnected )  {
    if (client.connect(serverIP, serverPort)) {
      clientConnected = true;
      Serial.println("Connected");//report it to the Serial
    }
  else {
    client.stop ();

    //reinitialise the state machine
    clientConnected = false;
    sendLoadParams = false;
    sendStartCommand = false;

    //the client can do no more.
   return;
  }

  //I have separated the write code from the read code for readability.
  if(clientConnected) {

     //This is where you send your commands.
     //You should send each command, just the once.
     //You probably need a simple state machine.
    
    if(!sendLoadParams) {
        client.write(abyLoadParameter1, 9);
       sendLoadParams = true;
   } 
  else if(!sendStartCommand) {
    client.write(abyStartReceiver, 8 };
    sendStartCommand = true;
  }

  //the read code should empty the receive buffer on each iteration of the loop function.
  if(clientConnected) {
    uint8_t bytes = client.available();
    for(uint8_t i =0; i < bytes; i++) {
      char ch = client.read();
      Serial.print(ch, HEX); 
    }
  }
}

connecting to Server ...
connection failed
Connected
FFFFFFAAFFFFFFBB111EFFFFFF800FFFFFFAAFFFFFFCCFFFFFFAAFFFFFFBB1111FFFFFF810FFFFFFAAFFFFFFCCFFFFFFAAFFFFFFBB111FFFFFFC3FFFFFFBD446D3802FFFFFFFFFFFFFFAAFFFFFFCCFFFFFFAAFFFFFFBB111FFFFFFC3FFFFFFBD446D3803FFFFFFFFFFFFFFAAFFFFFFCCFFFFFFAAFFFFFFBB111FFFFFFC3FFFFFFBD446D3804FFFFFFFFFFFFFFAAFFFFFFCC

Same problem mate, as I said before, the problem is not the code I have written, the problem is how this bloody shield receive bytes from Ethernet physical layer....
I bought this shield on ebay, for arduino it is quite easy to understand if it is fake or not, due logo and design, but all shield don`t have logo and I am wondering if there are fake and original shield as well....