The iotQi framework creates consistent development patterns across support devices for sampling telemetry, generating alerts, and implementing custom commands. This post discusses the telemetry sampling options and shows you likely patterns for packaging your telemetry data. These patterns can be implemented on the Raspberry PI or Arduino platforms. The concepts are the same across platforms, but there some differences in how they are coded due to differences in the platforms themselves.
For the Raspberry PI, I am assuming you would be developing your IoT device application in C# and Visual Studio. Note that any “edition” of Visual Studio will work (Community, Professional, etc.), but I recommend Visual Studio 2017 (or at least Visual Studio 2015). For the Arduino family, I am assuming you would be using the Arduino IDE. As an alternate to Arduino IDE, here at LooUQ, we also use Visual Micro add-on to Visual Studio (probably a future post), so if you are a Visual Micro user you should still be able to follow along without any difficulty.
The iotQi device client for Arduino (and the accompanying examples\templates) implement that standard Arduino setup() and loop() function patterns. As expected, the setup() function contains the steps to initialize the Arduino, initialize the iotQi library functions, and initialize your project specific code and\or hardware features.
Loop() implements the steps you need to sample your data and gives iotQi an opportunity to sync up with the cloud. As you can see from the code snippet below this example uses the millis() timer pattern to gather telemetry every TELEMETRY_INTERVAL seconds. Notice the iotQiDoWork() function at the bottom of loop(), this gives iotQi an opportunity to perform its communication duties and then return the processor back to your application. This pattern can be extended to do multiple “user” do work operations; by example performing 1 sample type every minute and a 2nd sample type every 15 minutes. The only requirement is you need to give control to iotQiDoWork() frequently, so it can send your data and check for incoming commands.
But what if you are using interrupts to signal that it is time for a telemetry sample? No problem… use the interrupt to stash your data in variables or a structure available to your user model, then when you “do work” package your data for iotQi to send. In this case you can “spin” the loop() with little or no waiting, you call your do work function and if the interrupt has not fired to generate telemetry, simply return to loop() immediately.
So, as you can see, iotQi allows you to build timer triggered or interrupt triggered data telemetry sampling patterns with ease.
Raspberry PI The Raspberry PI programming model doesn’t automatically present a typical device application pattern like the Arduino setup()/loop(). So, iotQi has a bit more freedom to establish an IoT device application pattern. We run on the PI on top of Windows 10 IoT Core, so we are required to create a UWP (Universal Windows Platform) application to deploy it on to a Raspberry PI. While this may sound restrictive, we can pattern both interrupt (events) and time (timer) driven telemetry sampling patterns.
Interrupts on the PI The Windows 10 IoT indirectly supports hardware event signaling via GPIO Pin ValueChanged event. This approach has some issues, as unlike a true interrupt which can be masked and enabled\disabled, the event behaves only in a similar manner. But for most any hardware trigger, this approach can start your telemetry sample task; once the sample is taken you can immediately send it to the iotQi cloud (there is no loop() and doWork() equivalent here) using the IotqiClient. SendTelemetryAsync() method.
Timed Sample Intervals on the PI
Timed samples, work in a nearly identical manner as events (simulated interrupts as above). Rather than subscribing to the GPIO pin event, you create a periodic timer and register your telemetry sample method as the timer expired event handler (see example below). There are different types of timers on Win10 IoT, I recommend that you use a ThreadPoolTimer because it is not tied to the UI (user interface) thread. The DispatcherTimer is frequently referenced in published materials, but this timer is tied to the UI thread. iotQi device applications are generally background applications on the Raspberry PI.
Wrapping It Up So, as you can see, the Arduino and the Raspberry PI have a common approach to telemetry sampling, with only minor differences. Both device families can support both time based telemetry samples and external event triggered samples. Additionally, both device families can have multiple sampling sequences per iotQi device, and for multiple sampling sequences they can be a mix of timer and event initiated sampling tasks.
Thanks for reading, Greg