Wireless field gateway protocol V2

I have now built a couple of nRF2L01P field gateways (for AdaFriut.IO & Azure IoT Hubs) which run as a background tasks on Windows 10 IoT Core on RaspberyPI). I have also written several clients which run on Arduino, devDuino, Netduino, and Seeeduino devices.

I have tried to keep the protocol simple (telemetry only) to deploy and it will be used in high school student projects in the next couple of weeks.

To make the payload smaller the first byte of the message now specifies the message type in the top nibble and the length of the device unique identifier in the bottom nibble.

0 = Echo

The message is displayed by the field gateway as text & hexadecimal.

1 = Device identifier + Comma separated values (CSV) payload

[0] – Set to 0001, XXXX   Device identifier length

[1]..[1+Device identifier length] – Unique device identifier bytes e.g. Mac address

[1+Device identifier length+1 ]..[31] – CSV payload e.g.  SensorID value, SensorID value

 

Xively GPS Location data upload V2

In the previous post I assembled the xively request XML using a StringBuilder rather than using the XML support available in the NetMF. To use the NetMF XML library I needed to add a reference to the DPWS extensions (MFDpwsExtensions) and change the using statement at the top of the module from System.Text to System.Ext.Xml

static void xivelyFeedUpdate(string ApiKey, string feedId, string channel, double latitude, double longitude, double altitude)
{
byte[] buffer;

using (XmlMemoryWriter xmlwriter = XmlMemoryWriter.Create())
{
xmlwriter.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
xmlwriter.WriteStartElement("eeml");
xmlwriter.WriteStartElement("environment");
xmlwriter.WriteStartElement("location");

xmlwriter.WriteStartAttribute("domain");
xmlwriter.WriteString("physical");
xmlwriter.WriteEndAttribute();

xmlwriter.WriteStartAttribute("exposure");
xmlwriter.WriteString("outdoor");
xmlwriter.WriteEndAttribute();

xmlwriter.WriteStartAttribute("disposition");
xmlwriter.WriteString("mobile");
xmlwriter.WriteEndAttribute();

xmlwriter.WriteStartElement("name");
xmlwriter.WriteString("Location");
xmlwriter.WriteEndElement();

xmlwriter.WriteStartElement("lat");
xmlwriter.WriteString(latitude.ToString("F5"));
xmlwriter.WriteEndElement();

xmlwriter.WriteStartElement("lon");
xmlwriter.WriteString(longitude.ToString("F5"));
xmlwriter.WriteEndElement();

xmlwriter.WriteStartElement("ele");
xmlwriter.WriteString(altitude.ToString("F1"));
xmlwriter.WriteEndElement();

xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();
xmlwriter.WriteEndElement();

buffer = xmlwriter.ToArray();
}

try
{
using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(xivelyApiBaseUrl + feedId + ".xml"))
{
request.Method = "PUT";
request.ContentLength = buffer.Length;
request.ContentType = "text/xml";
request.Headers.Add("X-ApiKey", xivelyApiKey);
request.KeepAlive = false;
request.Timeout = 5000;
request.ReadWriteTimeout = 5000;

// request body
using (Stream stream = request.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);                }
using (var response = (HttpWebResponse)request.GetResponse())
{
Debug.Print("HTTP Status:" + response.StatusCode + " : " + response.StatusDescription);
}
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
}

I was expecting the XML libraries to be quite chunky, but on my Netduino Plus 2 there wasn’t a huge size difference, the StringBuilder download was 49K8 bytes and the XMLWiter download was 56K1 bytes.

When I ran the StringBuilder and XMLWriter versions they both had roughly 92K6 bytes of free memory.

Realistically there was little to separate the two implementations

Xively GPS Location data upload V1

For one of the code club projects we looked at the National Marine Electronics Association (NMEA) 0183 output of my iteadStudio GPS Shield + Active Antenna. We used the NetMF Toolbox NMEA GPS processing code with a couple of modifications detailed here.

IteadStudio GPS

IteadStudio GPS shield and Antenna

For another project we had used Xively a “Public Cloud for the Internet of Things”. The Xively API has support for storing the position of a “thing” and it didn’t look like it would take much effort to extend the original GPS demo to trial this. The xively Location & waypoints API is RESTful and supports JSON & XML

void xivelyFeedUpdate(string ApiKey, string feedId, string channel, double latitude, double longitude, double altitude)
{
try
{
using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(xivelyApiBaseUrl + feedId + ".xml"))
{
StringBuilder payload = new StringBuilder();
payload.Append(@"<?xml version=""1.0"" encoding=""UTF-8""?><eeml><environment><location domain=""physical"" exposure=""outdoor"" disposition=""mobile""><name>Location</name><lat>");
payload.Append(latitude.ToString("F5"));
payload.Append("</lat><lon>");
payload.Append(longitude.ToString("F5"));
payload.Append("</lon><ele>");
payload.Append(altitude.ToString("F1"));
payload.Append("</ele></location></environment></eeml>");

byte[] buffer = Encoding.UTF8.GetBytes(payload.ToString());

request.Method = "PUT";
request.ContentLength = buffer.Length;
request.ContentType = "text/xml";
request.Headers.Add("X-ApiKey", xivelyApiKey);
request.KeepAlive = false;
request.Timeout = 5000;
request.ReadWriteTimeout = 5000;

// request body
using (Stream stream = request.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
using (var response = (HttpWebResponse)request.GetResponse())
{
Debug.Print("HTTP Status:" + response.StatusCode + " : " + response.StatusDescription);
}
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
}

The position of the “thing” is displayed like this

Xively poisition

The position of my car

The XML was constructed using a stringbuilder (NetMF 4.2) as this appeared easier/smaller than using the baked in XML functionality.