The Photon as a weather station, connected to Azure IoT Platform

A few weeks ago, Jon Gallant asked for beta tester for the Azure IoT Platform integration with the Partical platform (Beta Testers Needed for Particle to Azure IoT Integration).

This was great news to me. I have a Photon Azure Starter Kit laying around and I tried once to connect it to the Partical platform.

sparkfun_thing_azure

The kit has potential: it comes with a SparkFun Photon Weather Shield:

p05-weather-station

And on the shield are already attached:

  • Humidity/Temperature Sensor – HTU21D
  • Barometric Pressure – MPL3115A2

And it has two RJ-11 connectors for Weather Meters like this one:

p06-weather-station-meters

But that initial (EventHub?) integration was not quite intuitive and I had more projects to work on. So I moved on.

Now, I had a second chance to make the Photon work!

The first steps are to register your unique Photon device and attach it to the internet (it has a Wifi chip onboard).

If you go to the online IDE, you can write code for your Photon and flash (deploy) it ‘over the air’. This is fun, as long as your Photon is online (wherever it is running), you can contact it using a browser.

The integration tutorial, the blog of Jon Gallant, is very straight forward regarding making an Azure IoT Hub integration. You only need an Azure IoT Hub and a specific access policy.  This will help you in sending a string from the Photon to the hub.

Update: Another useful tutorial comes from the Particle site and it shows how to send some integers.

But sending a JSON message is less intuitive.

Programming for the weather shield

I assume that you have your Photon running, including the IoT Hub integration as described above.

First, let’s start a new app file and include the library with the weather shield logic. Sparkfun provides several libraries, right inside the online IDE, so just look for the right one:

p03-find-lib

Select the SparkFun_Photon_Weather_Shield library and include it in your new app:

 

p04-add-lib

Now change your app file into:

#include "SparkFun_Photon_Weather_Shield_Library/SparkFun_Photon_Weather_Shield_Library.h"

float humidity = 0;
float tempf = 0;
float pascals = 0;
float baroTemp = 0;
float altf = 0;

Weather sensor;

void setup() {
  sensor.begin();
  sensor.setModeBarometer();//Set to Barometer Mode
  sensor.setOversampleRate(7); // Set Oversample rate
  sensor.enableEventFlags(); //Necessary register calls to enble temp, baro and alt
}

void loop() {
  getWeather();
  char payload[256];
  snprintf(payload, 
           sizeof(payload), 
           "{ \"tf\":%f, \"hy\":%f, \"bp\":%f, \"ps\":%f, \"af\":%f }",
           tempf, humidity, baroTemp, pascals, altf);
  Particle.publish("azureiothub ", payload);

  delay(60000);
}

void getWeather() {
  humidity = sensor.getRH();
  tempf = sensor.getTempF();
  baroTemp = sensor.readBaroTempF();
  pascals = sensor.readPressure();
  altf = sensor.readAltitudeFt();  // if in altimeter Mode
} 

note: the barometer has two different modes, you can only pick one:

sensor.setModeBarometer();//Set to Barometer Mode
//baro.setModeAltimeter();//Set to altimeter Mode

Now, if you run this right away, you will receive something like this (as seen in the Device Explorer):

12/29/2016 2:18:37 PM> Device: [3e0025000447343138333038], Data:[
{"data":"{ 
   \"tf\":69.429390, 
   \"hy\":32.795471, 
   \"bp\":70.699997, 
   \"ps\":103652.250000, 
   \"af\":85015.789062 }",
 "device_id":"3e0025000447343138333038",
 "event":"azureiothub ",
 "published_at":"2016-12-29T13:18:37.539Z"
}]

This message does not contain well-formed JSON. And therefore, it’s not very useful.

At first, I expected that I had to pass the JSON in another format using the Publish() method.

But with the help of the Partical Forum, I was pointed to the ‘advanced settings’ of the integration.

Advanced settings

I expect you have not filled in any ‘custom’ JSON in the advanced setting when you created your IoTHub integration:

p05-integration

No worries, we can fix that!

First, it’s better de drop your current Integration and create a new one with the same settings, you can not alter this field afterward. But this time you fill in the Custom JSON Field:

p01-double-quotes-error

The JSON we send with the Publish() method, will be filled in, into this JSON.

Notice: only strings can be passed. Without the double quotes around the values, the JSON is marked invalid.

Update January 3, 2017: the Particle Senior Software Engineer is aware of the JSON template issue, a solution will be available the coming months.

So you end with this ‘Additional’ JSON:

p02-additional-json

As soon you have deployed the new Integration, the Device Explorer shows the updated message:

12/29/2016 1:11:05 PM> Device: [3e0025000447343138333038], Data:[
{
  "PARTICLE_PUBLISHED_AT":"2016-12-29T12:11:04.165Z",
  "PARTICLE_DEVICE_ID":"3e0025000447343138333038",
  "altf":"85053.3125",
  "pascals":"103702.75",
  "baroTemp":"71.712502",
  "humidity":"30.590576",
  "tempf":"70.469078"
}]

Now, this is what we expect to receive from a device.

We can take this a step further by transforming this message using StreamAnalytics. I live in The Netherlands so I prefer the metric system:

SELECT
  -- Measure Temperature in celcius from the HTU21D or Si7021
  (Cast(tempf as float)-32)/1.8 as temperature
  -- Measure Relative Humidity from the HTU21D or Si7021
  , Cast(humidity as float) as humidity
  -- Measure the Barometer temperature in celcius from the MPL3115A2
  , (Cast(baroTemp as float)-32)/1.8 as barometerTemperature
  -- Measure Pressure from the MPL3115A2
  , Cast(pascals as float) as pressure
  --If in altitude mode, you can get a reading in meters with this line
  , Cast(altf as float) * 3.28084 as altitude
  , PARTICLE_PUBLISHED_AT as ParticleUtcTime
  , PARTICLE_DEVICE_ID as ParticalDeviceId
INTO
  blobsink
FROM
  hubinput

Note: we have to cast the JSON strings to floats before we can calculate with them.

{
"temperature":21.457282222222222,
"humidity":30.476135,
"barometertemperature":22.1875,
"pressure":103716.25,
"altitude":279096.77832742204,
"particleutctime":"2016-12-29T12:00:57.7630000Z",
"particaldeviceid":"3e0025000447343138333038"
}

Conclusion

The Photon is a very nice device and it is very promising. That fact that it both has on board WIFI, deep sleep mode, 128Kb of memory and both digital and analog ports, make it a nice and easy device to work with. And I do not have to attach it to my laptop, every time I want to program it. I just make contact using the online browser.

My Photon will not ‘deep sleep’ in a cupboard anymore!

Epilogue

The IoT Hub integration is easy and powerful. But I also would like to send commands back using the IotHub. Yes, it’s possible to call functions registered on the device but then I have to negotiate, remembering and passing the unique access token. Only then, we have First Class integration with the Azure IoT Plaform!

 

 

 

Advertenties