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.
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.
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.
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.