Arduino Ethernet shield and Python socket

Posted on 2015/06/14

1


I started playing with an Ethernet shield for Arduino that I bought at a faire. I noticed that the shield itself is not original, but it’s a clone of the Arduino Ethernet Shield version 5.0, also identified as revision 2. The shield provides Ethernet connectivity and has an SD card slot to provide non-volatile memory support. It is a basic component to build a device interconnected with the world through the Internet of Things.

Arduino Uno with Ethernet shield

Arduino Uno with Ethernet shield

I wanted to try doing basic things with it first, partly to gain confidence with the shield and the code, partly to check if it’s functioning correctly. I snapped the shield on my Arduino Uno and hooked them to the USB port of my Debian PC, and to the Ethernet port of my router. Then I opened up Arduino IDE and loaded the example sketch for a simple TCP (Telnet) client; the menu path is:

Files -> Examples -> Ethernet -> TelnetClient

The sketch uses the Ethernet library and the Serial port to create a terminal that talks to a remote socket. The sketch leaves to the developer to fill the client and server IP addresses, and doesn’t use DHCP. It is said in the Arduino reference pages that using DHCP makes the sketch bigger. I opened the web pages that my router exports (at 192.168.1.1 in my case) to see which IP addresses were allocated for the machines I have at home. The default client IP in the example sketch is 192.168.1.177, and it’s OK for my setup because I have no computer connected with that address. The computer I use to create a “server” is my Debian PC, and by running /sbin/ifconfig, or by hovering the mouse on the network manager icon, I discover that its IP address is 192.168.1.173, so I write that address in the code substituting the existing one:

// Enter the IP address of the server you're connecting to:
IPAddress server(192,168,1,173);

The other modification I did was to increase the delay before trying to connect to the server from one to five second, because I saw that the LEDs on the Ethernet shield were turning on a little after one second from the reset. This consists in substituting a “delay(1000);” with a “delay(5000);” before the call to “client.connect” in the setup function. I don’t know if this delay is a problem of my setup, my router, or the non-official shield that I bought; but I see the FULLD LED blinking before the other ones do, like the shield is struggling to negotiate full duplex support (or at least that’s my interpretation of its behaviour).

I click the Upload button and the sketch is flashed into the Arduino Uno. I then open the serial monitor that is embedded in Arduino IDE to have a terminal to try the sketch functionality. I choose the menu entry “Tools -> Serial Monitor“, and when the monitor opens I make sure that the newline option is “Both NL and CR”, and the baud rate is 9600 like in the sketch.

Then I created a small Python script that uses the socket library to implement a small server that listens from a port, and when a client establishes a connection, it receives characters and echoes them back to the client in uppercase.

Data flow diagram of Arduino Ethernet  communication test

Data flow diagram of Arduino Ethernet communication test

The Python script “arduino_socket.py” below has been written with inspiration from http://pymotw.com/2/socket/tcp.html:

import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('192.168.1.173', 10002)
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)

try: 
    while True:
        # Wait for a connection
        print('waiting for a connection...')
        connection, client_address = sock.accept()
        print('connection from %s:%d' % client_address)
        try:
            while True:
                # Receive the data one byte at a time
                data = connection.recv(1)
                sys.stdout.write(data)
                if data:
                    # Send back in uppercase
                    connection.sendall(data.upper())
                else:
                    print('no more data, closing connection.')
                    break
        finally:
            # Clean up the connection
            connection.close()
except KeyboardInterrupt:
    print('exiting.')
finally:
    sock.shutdown(socket.SHUT_RDWR)
    sock.close()

I run the script with then command “python arduino_socket.py” in a shell terminal and the program waits for a client connection to port 10002.

Now I press the reset button on the Ethernet shield, which is connected to the reset signal of the Arduino Uno so that it resets both, and after a few seconds the serial monitor prints the status messages and indicates that the connection has been established. I then send character in the Serial monitor, they appear in the shell terminal that runs the Python server, then they are echoed back uppercased into the Serial monitor.

Arduino Ethernet communication test

Arduino Ethernet communication test

The next test I want to try is to connect it on a Nucleo F103RB and build the same communication channel as I did with the Arduino. It will probably mean finding or developing libraries for SPI communication and for the chip on the Ethernet shield, which is a Wiznet W5100.

Posted in: Hardware