3
\$\begingroup\$

I have an Arduino with Ethernet shield handshaking with my machine over Ethernet, and now I want to send data between them. My problem seems to be correctly parsing the different data types.

For example, after connecting to my Arduino server, my Python script runs this

msg = "255"
print "Sending %s" % msg
data = s.send(msg)
s.close()

and all I'm looking to do right now is print it to serial on Arduino (I'll eventually do different things based on the input).

Here is my run loop on the Arduino.

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

     if (client == true) {
          int recv = client.read();    
          if (recv == 255)
               Serial.print("Received ");
          Serial.println(recv, DEC);
     }
}

For some reason it's only printing a single blank character and I don't get any "received" message.

\$\endgroup\$
5
\$\begingroup\$

In Python, msg = "255" will make msg a string type using those quotes around 255.

Your Arduino code is making this comparison: if(recv == 255)

This is going to do an integer comparison. A string "255" is not going to equal the integer 255 and I'm not sure how the data is going to be received and formatted on the Arduino using client.read(), it's probably returning the first byte out of that string.

In any case, you'll have to keep things consistent byte for byte in your python code and your arduino code.

EDIT:

After some further reading:

client.read() Returns The next byte (or character), or -1 if none is available. So you either need to house that function in a loop and terminate on -1 (which is a bad idea in my opinion - in the case that you do want to send the value -1 in your data stream) or you can do what Joby Taffey suggested, build a basic protocol and state the number of bytes of content that will follow.

\$\endgroup\$
  • \$\begingroup\$ I would guess that the ".read()" is doing the job of reading characters from the interface until the eos character is reached. The only issue here being that 255 will not be the value. It is probably a case that 255 is the return value when no string is received. Maybe suggesting a !=255 to verify there was a received string would get the job done and moving the print of the string inside the braces also? \$\endgroup\$ – Kortuk Sep 30 '11 at 14:45
  • \$\begingroup\$ @Kortuk, arduino.cc/en/Reference/ClientRead "Returns The next byte (or character), or -1 if none is available." \$\endgroup\$ – Jon L Sep 30 '11 at 17:20
  • \$\begingroup\$ that means it is returning 255 if you read a unsigned char and there is no character. So it looks like it should be a case of !=255. It should read into unsigned char instead, and it only represents 1 character. \$\endgroup\$ – Kortuk Sep 30 '11 at 17:25
  • 1
    \$\begingroup\$ could you not house a loop that ignores characters that are -1 and prints everything else? This would result in printing any characters that are sent, including endlines and such. \$\endgroup\$ – Kortuk Oct 3 '11 at 1:18
2
\$\begingroup\$

As Jon pointed out, your Arduino is only receiving one byte. TCP provides a continuous stream of bytes, so you need to decide how you are going to separate messages.

You can either send a header telling the receiver how long the message is, or you can send a footer with a pre-chosen termination byte.

On the wire, the bytes for a message with a header might look like {3, 'f', 'o', 'o'}. The receiver gets the first byte, then knows to read three more before the message is complete. Once it's read 3 bytes, it waits for another header.

If using a footer, the receiver writes every incoming byte to a buffer until it sees a special termination character. C strings work this way, placing them "on the wire" you might see {'f', 'o', 'o', 0}. This scheme allows for infinitely long strings, but requires the receiver to have a big enough buffer for incoming data. It also doesn't allow 0 to appear in messages. Any scheme based on a terminating character won't be 8-bit clean and will need an escaping mechanism for passing binary data.

For human readable data, a footer of '\n' (the newline character) is easy to work with. This way, you can use telnet/nc to interact with each side of the system for testing.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.