Some hints to do with networking with an Arduino Uno. This is an adjunct to my current blog topic, Ardjson-JSon-REST-Azure Mobile Services, which includes interacting with an Azure Mobile Services from an Arduino device.

Hardware

There is a specific Shield, the Uno Ethernet Shield,, for networking the Arduino Uno.

I am using a Uno clone from Freetronics that includes the network shield onboard.

Uno Ethernet Shield

EtherTen Quickstart Guide

image
EtherTen (100% Arduino compatible with onboard Ethernet)

Top left:        Arduino Uno

Top Right:     Arduino Ethernet Shield

Bottom Left:  Freetronics EtherTen

The latter is equivalent to the shield above plugged in to the Uno.

   
   

Software

There is a standard library for the Uno Ethernet Shield so with Arduino compatible hardware it works off-the-shelf: From the Arduino IDE its located in

File > Examples > Ethernet

image

The main networking library is the Ethernet Library. Whilst it is simplest to take and example and modify it for your own purposes, the library can be added to a any project via Sketch > Import Library > Add Library > Ethernet 

image

EtherTen Network Compatibility

“The network functionality of the EtherTen uses the Wiznet W5100 chip, which is the same chip used on the official Arduino Ethernet Shield. They also kept all the pin assignments the same, so functionally the EtherTen is identical to having, say, an Arduino Uno with an official Ethernet Shield plugged into it.

This means any relevant tutorials or examples you find will work just fine on the EtherTen, and also that it's fully supported by the official "Ethernet" library and associated examples included with the Arduino IDE. If you select File > Examples > Ethernet you will see a variety of sketches that you can try with your EtherTen.

Note that just like the official Ethernet Shield, the EtherTen does not come with a specifically assigned MAC address stored in hardware. The MAC address must be set from inside your sketch, just as you'll find near the start of each of the Ethernet examples. You can pick any valid MAC address you like as long as it's unique on your network.”


DHCP Networking IP

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };


set_up( )
  ....
  ....Set up serial....
  ....
  Ethernet.begin(mac); //Use DHCP
  Serial.println("ipconfig:");
  Serial.println(Ethernet.localIP());
  Serial.println(Ethernet.subnetMask());
  Serial.println(Ethernet.gatewayIP());
  Serial.println(Ethernet.dnsServerIP());

  // give the Ethernet shield a second to initialize:
  delay(1000);
  ....
  ....
  ....
}

Static IP

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress ip(192,168,137,177);
IPAddress bbitmask(255,255,255,0);
IPAddress ddns(192,168,137,1);
IPAddress ggateway(192,168,137,1);


set_up( )
  ....
  ....Set up serial....
  ....
 Ethernet.begin(mac,ip); //Static IP
 //OR
//Ethernet.begin(mac,ip,bbitmask,ddns,ggateway);
  Serial.println("ipconfig:");
  Serial.println(Ethernet.localIP());
  Serial.println(Ethernet.subnetMask());
  Serial.println(Ethernet.gatewayIP());
  Serial.println(Ethernet.dnsServerIP());

  // give the Ethernet shield a second to initialize:
  delay(1000);
  ....
  ....
  ....
}

Note that the DHCP version of Ethernet.begin( ) returns 1 if successful which can be used to check if the DHCP call worked.

The static IP versions of  Ethernet.begin are void functions and so the Ethernet properties after the called should be used in sanity checks to see if the call was successful.

Static versus Dynamic IP

For a “semi” standalone development environment, I used my development system, a laptop to connect to Ethernet via WiFi with Network Sharing turned on for it using the wired NIC. This was connected to the EtherTen NIC using a crossover cable  (an ordinary CAT 5 cable would have done), requiring a static IP on the device.  The laptop wired NIC was configured with an IP address of 192.168.137.1 and bitmask 255.255.255.0; hence the IP settings above for device in static IP address mode. The Arduino Networking examples worked OK except for where they required DNS. It was found that fixed IP addresses were required in the code rather for target addresses rather than URLs as strings. When the EtherTen was instead connected to a network switch that was connected to the Ethernet, and DHCP was used to obtain the device’s IP address, the URL strings in code (and hence DNS) worked OK. Note that static IPs for Azure Mobile Services didn’t work and hence the DHCP configuration was required for that work.

Network communications

Network messages are received on the Server object and transmitted from the Client object:

//Web Client
EthernetClient client;
IPAddress server (104,40,63,98);      // Fixed IpAddress, for connecting to a service
char server = "msdn.microsoft.com"; //URL string, for connecting to a service
//In code:
client.connect(server, 80)

//Creating a web service
EthernetServer server(80); 
//In setup():
  server.begin();
//In loop ():
  EthernetClient client = server.available();
  if (client) {

//Creating a telnet service
EthernetServer server(23);
EthernetClient client;
//In setup():
  server.begin();
//In loop() 
  EthernetClient client = server.available();
  if (client) {

Submitting a Request

The following is a summary of submitting a request from a web client.

//Connect to a socket and submit a request
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("POST/GET/PUT/PATCH or DELETE   <resource on target> HTTP/1.1");
    client.println("Host: <target host URL>"); //
    client.println("....")
    client.println("....")
  } 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  delay(2000);
 

Getting the Response

Getting the response for a web client.

in loop()

  while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  if (!client.connected()) {
     client.stop();
  }

Arduino Networking Code

The structure of these programs is:

  • Declarations
  • send_request( ) Form http request string and submit it
  • wait_response( ) Wait until connected for response
  • read_response( ) Get the response and process it
  • end_request( )  Disconnect from TCPIP connection when response is read.
  • set_up( ) Setup Serial and Ethernet (First thing called by an Arduino app)
  • loop( )  Call first four functions in order (Main loop for Arduino app, Continuously called after set_up( )).
  • Additional app specific functions and declaration

The send_request and read_response functions are specific to each of the three apps.
The other code is common to all three. This code common  is listed in two parts:

  • The Common Declarations
  • The Common Functions. (wait_response, end_request, set_up and loop)