Exploring IoT… A practical approach, Part 1

Without going into formal definitions and what not, I will skip straight to the practical side.

Business Case: An industrial weighing scale that weighs trucks and their load. The scale goes from 0.00 kg to 50,000.00 kg. The scale precision or stepping is 20.00 kg, which is kind of understandable being a metric ton and not a metric kilogram scale! The scale is connected directly to a dedicated PC through a serial COM port. The need is to connect the scale directly to the Internet as a proof of concept and monitor its state – preferably by not breaking up the current functionality!

Step 1: I connected the scale to my laptop through a USB-to-RS232 converter, set the COM port settings to the usual suspects (baud: 9600 kbps, data bits: 8, parity: none, stop bits: 1, flow control: none). I was kind of expecting that the scale indicator would operate by polling i.e. I would ask “what is the current weight which is registered?” and it would respond “the current weight registered is xxx.xx kg“. Instead, it is constantly flushing its state through its COM port, resulting in something such as this:

Weight_scale_01

Look closely, and you’ll observe that each message is exactly 19 bytes in length including the last two: 0x0D (LF) and 0x0A (CR) (or a new line in a Windows environment). But I need to double check this as it may turn out to be something my terminal application was appending!?

Nevertheless, the message begins with US,GS, or ST,GS, followed by 8 bytes for the actual weight, ended by a ,kg. and (supposedly) ended by LF CR.

Suppose I decided to keep the existing computer and no other external hardware, the way I would do it (and actually did professionally many times before!) is to introduce virtual COM ports. One excellent product (and battle tested!) which I would highly recommend is the completely free Null-modem emulator (com0com). Check out the project page as it offers other interesting software as well.

Essentially what you do is create a pair of two interconnected virtual COM ports. What comes at one end, is replicated at the other end. Like an echo! Then you build the simplest adapter – a software which sits in the background, listening and waiting for incoming data from the physical COM port and then re-transmits the same data (or modified if you wish!) on one of the virtual COM ports from the virtual COM port pair. Finally, you setup your original application to listen to the other virtual COM port instead of the physical one. With this approach, you get a lot (a lot!) of additional functionality and flexibility!

Step 2: But, in the true spirit of IoT (whatever that implies…), I decided to use a smaller device – one which doesn’t have an OS layer but is cable to connect to a network and thus potentially gain access to the Internet. An Arduino is probably the most likely candidate here but I decided to go with something different. Something which was on my TODO list for some time now and never got the chance to properly explore it.

Meet the LaunchPad series development platform from Texas Instruments:

TI_LaunchPad_and_BoostPack

But first thing’s first!

I was exploring for potential candidates for my IoT platform and I came across this article: Internet of Things: 4 Free Platforms To Build IoT Projects. There are certainly other articles out there and the same applies for the platforms, but I decided to go (with no particular reason really!) with Ubidots. Check them out: they offer a 30 day trial with full functionality and I must admit – I was pleasantly surprised.

Step 3: Ubitdots have a dedicated GitHub page definitely worth checking out! The section of specific interest to me was the one offering guidance on working with the Ubidots API from .NET C#. I basically wanted to explore it’s capabilities from the comfort of my desktop PC, and this is what I did:

  • Created a device (device name: TestDevice, device label: test_device):

02-Add device

  • Created a variable associated with that device (API label: test_variable, format: Raw). Clicking on the information icon will give you the variable’s ID:

03-Add variable

  • Created a dashboard (dashboard name: TestDashboard)
  • Added a couple of widgets (a gauge and a line chart, and associated both with the variable ‘test_variable‘)
  • Created an event (which essentially meant creating a trigger/action pair i.e. ‘on trigger – do action’):

04-Events

05-Events

06-Events

  • You will also be needing your API key once you start coding:

01-API credentials

After that, I fired up Visual Studio, followed the explanations presented on Ubidots’ C# page, and basically tried something along these lines:

using Ubidots;

‘Includes’ the Ubidots namespace and ‘prevents’ us from having to use fully qualified types and/or methods in our program.

// Instantiate a new API object
// Replace 'your_api_key' with your API key
ApiClient Api = new ApiClient("your_api_key");

// Retrieve the data source with the specified ID (in this case: 'TestDevice')
// Replace 'your_device_id' with your device ID
DataSource testDevice = Api.GetDataSource("your_device_id");

// Retrieve only the variable with the spicified ID (in this case: 'test_variable')
// Replace 'your_variable_id' with your variable ID
Variable testVariable = Api.GetVariable("your_variable_id");

// Storing a single value into a variable (in this case into: 'test_variable')
testVariable.SaveValue(12450);

// Store multiple values into a variable (in this case into: 'test_variable')
int[] values = new int[3] { 20325, 39151, 45161 };

long timeStamp1 = (long)(DateTime.UtcNow).ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
Thread.Sleep(500);

long timeStamp2 = (long)(DateTime.UtcNow).ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
Thread.Sleep(500);

long timeStamp3 = (long)(DateTime.UtcNow).ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
Thread.Sleep(500);

long[] timeStamps = new long[3] { timeStamp1, timeStamp2, timeStamp3 };

// The 'SaveValues' method accepts two arguments: the actual values and the respective time stamps
// basically the point in time when the value has been read - for each value!
// The use of Thread.Sleep is to 'create' a noticeable difference between each reading
testVariable.SaveValues(values, timeStamps);
Thread.Sleep(1500);

With the use of a for loop, I got this result:

07-Sample data

And after enabling my event alert, I got this (as expected!):

08-Alerts

I’ll say it again: I was really pleasantly surprised by the ease of the entire process. Plus, the refresh rate of the widgets (both the gauge and the line chart in this case) was really impressive. In reality I guess it makes little sense to update the values with such a high frequency. Nevertheless, it was still impressive!

Now I’m ready to move on to ‘the real deal’ i.e. on with my LaunchPad development board (which might be an overkill in the current context…).

But this is reserved for Part 2 of the article.