Azure Veneziano – LinkIt ONE

This post follows my first one on Internet-of-Things telemetry project based on Azure.
At that time I used a Netduino Plus 2 as remote sensor device: this time I use the awesome Seeedstudio LinkIt ONE board.
I strongly suggest to read the old one first, because most of the below content relies on concepts already discussed in the past.

Here are the previous parts:

The source of the project is hosted in the azure-veneziano GitHub repository.

WP_000868

The LinkIt ONE board impressions.

My viewpoint is the one from who does NOT like C/C++, does NOT have (decent) experience in such a languages, rather loves RAD environment. Even Netduino, which is based on the .Net Micro Framework, relies on a enjoyable IDE (Visual Studio). The .Net libraries together with the awesome debugger really makes the Netduino board the best ever.

Every time I must face a C/C++ program, I feel frustrated.
For this project, I had to “translate” the original Netduino C# sources to a Arduino/C/C++ “working” sketch. I say “working”, because my goal was just make the board working, not writing a decent program.
Why “frustrated”? Because I think it’s a nonsense wasting time against a hyper-verbose C/C++ project, than simply writing high-level languages like C# or Java. It’s a super-board, even faster and larger in terms of resources than a Netduino Plus 2. It’s not just a 8-bit AVR.

So, why the LinkIt ONE board should be “awesome”?
First of all, because the hardware. The board is a little masterpiece for hobbists, because is really full-featured, but also comes with a very reasonable price.
Secondly, I’d say the Arduino APIs approach, which simplifies the things for dumb+lazy programmers like me.
Honestly speaking, the APIs cover many of the board features, but I’d expect a better coverage. My impression is rather a thin layer which is wrapping the real OS running into the board. That’s pity, because the users may feel some limitation very early.

An example is the HTTP support, which is nonexistent.
A clearly claimed board “for prototyping Wearables and IoT devices” should expose at least the most common services, that a typical IoT project use.
I personally found annoying digging in the Internet for open source projects about very basic services like JSON manipulation, HTTP client and so other. Thankfully the Arduino-world is still huge, and there are plenty of users contributing with their own works.

To close this argument, most of the time I’ve spent on the porting was…about ME, and my inexperience on writing C/C++, searching for libraries on the Internet, and make them working in a decent way.
A normal C/C++ developer shouldn’t have any problem on writing apps for this board.

The software.

As said, except for the JSON and the HTTP libraries, almost everything was “cloned” from the original C# sources. That’s because many of you, maybe C/C++ skilled, will smile (laugh) by seeing how I’ve written the ported source.

The JSON library comes from Benoît Blanchon, who made a very cool job.
The library is well written, in my opinion, but you should bear in mind that the Benoît target was the “real” Arduino, as very poor on resources (and language features).
That is, the LinkIt board is a 32-bit ARM core, thus the memory usage is way higher than what described in the library Wiki.
Moreover, the Arduino default platform comes without “new” and “delete”, and the JSON library adds its own “new” operator overloading. However, that will fight with the LinkIt SDK, which is a C/C++ featured platform, and such operators are fully supported.
By the way, this board comes with 4MB of RAM. Far from being a problem allocating some KB of cache!

For the HTTP client, I chose this library.
It’s a minimalistic HTTP composer and parser, but way enough for what any hobby project requires. It comes also with the BASIC authentication.

There are some other difference from the original Netduino project.
First off, the TCP connection is made via Wi-Fi, because the LinkIt ONE does not comes with any Ethernet plug. However, this is a very straightful task, because the APIs/samples are very clear on how to set-up a wireless connection.
Another difference is on the GPS sensor monitoring, which is absent in the Netduino, but included in the standard LinkIt ONE package. Despite I used it mostly for fun, I believe it would be useful whereas you need to track the device position if it’s moveable.
Again, very easy to set-up.

The sketch initialization isn’t much different than the old Netduino’s one:

/**
* Hardware input ports definition
**/

InputPortWrapper* _switch0;
InputPortWrapper* _switch1;

AnalogInputWrapper* _analog0;
AnalogInputWrapper* _analog1;

IInput* _inputPorts[16];
int _portCount;

#define LED 13

#define WIFINAME "(your wi-fi name)"
#define WIFIPWD "(your wi-fi password)"

int _wifiStatus;
MobileServiceClient* _ms;

gpsSentenceInfoStruct _gpsinfo;


void setup()
{
	/**
	* Hardware input ports definition
	**/
	_switch0 = new InputPortWrapper(
		"Switch0",
		0
		);

	_switch1 = new InputPortWrapper(
		"Switch1",
		1
		);


	_analog0 = new AnalogInputWrapper(
		"Analog0",
		0,
		100.0,
		0.0
		);

	_analog1 = new AnalogInputWrapper(
		"Analog1",
		1,
		100.0,
		0.0
		);

	//collect all the input ports as an array
	_inputPorts[0] = _switch0;
	_inputPorts[1] = _switch1;
	_inputPorts[2] = new RampGenerator("Ramp20min", 1200, 100, 0);
	_inputPorts[3] = new RampGenerator("Ramp30min", 1800, 150, 50);
	_inputPorts[4] = _analog0;
	_inputPorts[5] = _analog1;

	_portCount = 6;

	//just the led port used as a visual heartbeat
	pinMode(LED, OUTPUT);

	//turn-on the GPS sensor
	LGPS.powerOn();

	//setup the WI-FI connection
	LWiFi.begin();

	_wifiStatus = LWiFi.connectWPA(WIFINAME, WIFIPWD);

	//istantiate a new Azure-mobile service client
	_ms = new MobileServiceClient(
		"(your service name).azure-mobile.net",
		"(your application-id)",
		"(your master key)"
		);
}

Then there’s the “loop” section, which is also pretty easy:

void loop()
{
	if (_wifiStatus >= 0)
	{
		bool hasChanged = false;

		//perform the logic sampling for every port of the array
		for (int i = 0; i < _portCount; i++)
		{
			if (_inputPorts[i]->sample())
			{
				hasChanged = true;
			}
		}

		if (hasChanged)
		{
			//something has changed, so wrap up the data transaction
			StaticJsonBuffer<4096> jsonBuffer;

			//read the GPS info
			LGPS.getData(&_gpsinfo);

			JsonObject& jobj = jsonBuffer.createObject();
			jobj["devId"] = "01234567";
			jobj["ver"] = 987654321;
			jobj["pos"] = (char*)_gpsinfo.GPGGA;

			JsonArray& jdata = jobj.createNestedArray("data");

			//append only the port data which have been changed
			for (int i = 0; i < _portCount; i++)
			{
				IInput* port;
				if ((port = _inputPorts[i])->getHasChanged())
				{
					port->serialize(&jdata);
				}
			}

			//execute the query against the server
			_ms->apiOperation(
				"myapi",
				REST_Create,
				&jobj
				);
		}

		//invert the led status
		digitalWrite(
			LED,
			digitalRead(LED) == 0
			);

		//take a rest...
		delay(1000);
	}
}

Once the program is deployed, the data incoming the Azure APIs show something like the following:

log-entry

Conclusions.

Although I don’t like the rough C/C++ programming style, the LinkIt ONE board is really awesome. I’d only encourage the Seeedstudio team to:

  • Cover the rest of the board hardware with more APIs (e.g. sound, phone calls managements, etc)
  • Offer an higher-level language choice, such as Java/C#/JavaScript: Node.js running in the LinkIt would be the top!
  • Embed the most used (basic) services for IoT, such HTTP client/server, JSON, etc.

Have fun!

Leave a comment