Tag Archives: Photon

Building the hardware for a room sensor

The final sensor housing design

Here at Cranfield University we are putting in place plans related to the new ‘Living Laboratory’ project, part of our ‘Urban Observatory’. This project sits within the wider UKCRIC initiative, across a number of universities. Of the many experiments in development, we are gathering environmental data from IoT devices and building data dashboards to show the data and related analyses. One of our projects will be to investigate air quality on the campus, in our lecture rooms and public spaces. Cranfield is a unique University in the UK for having its own airfield as part of the campus – we want to monitor any particular impacts that can arise from this. In this blog we discuss building the hardware for a room sensor to detect levels for temperature, humidity, barometric pressure and VOC (volatile organic compounds).

In previous blogs, we have explored the use of the fantastic Bosch BME680 sensor from PiMoroni with the equally fantastic Particle Photon board to detect environmental characteristics. This blog post is more about building the hardware for the sensor, describing a prototype design.

An initial issue is how to site the sensor in a room. We were considering at first fixing sensors to walls, and running power to the case with trunking going up the wall from power sockets. This is all pretty unsightly and obtrusive. However, an idea then emerged that offers a perfect solution. Each room has a WiFi router positioned centrally on the ceiling, and each router has a spare USB socket. The design goal was therefore to design a plug-in unit that can be positioned in this USB socket. There certainly shouldn’t be an issue with WiFi connectivity!

WiFi ceiling mounted routers
Routers have a spare USB socket

We therefore looked to find a suitable case to fit a Particle photon, and the sensor, with the ability to plug into the USB socket. We found the perfect case from Farnell, the Hammond 1551USB3TSK USB Plastic Enclosure. We also bought a right angled USB PCB plug. Together with the Photon and BME680, all the parts looked like this.

Components being assembled for build

The next stage involved soldering the PCB USB connector onto a piece of veroboard and cutting it to fit with the trusty Dremmel saw, drill and deburring tool.

After much fiddling with the components, the piece was starting to take shape. The first task was to fit the USB connector. We cut out a piece of veroboard and then cut it to fit. As can be seen this was a pretty fiddly task. The USB plug needed fixing in place so the case could plugged in and removed without the USB plugboard moving. Next time we realised we should use the case pillars better and cut a slot out to fit around them!

Finally, after the USB board was fitted, the rest of the components could be fitted and wired up. The other end of the case then had a small slot routed in to allow the sensor to be stuck through to poke outside. We found that in use the Photon can heat up, so we wanted the temperature sensor located as far away as possible from it and to have the sensor exposed to the air. We then needed to wire the components up permanently which meant soldering wires in rather than using the header pillars that our earlier prototype had used. We had our wiring diagram to work to from our prototype.

We realised there was not enough space in the case for adding header blocks on the Photon or the sensor, so soldering directly to their PCBs was the only way to proceed. Soldering makes a permanent join, but the electronics of both the photon and BME680 sensor are very delicate, so we were careful to use the absolute minimum heating time from the soldering iron to make the joins, and use a solder with plenty of flux. This resulted in satisfactory joins. Also, we needed to get the 5v power to the Photon from the USB plug unit. To to this we took the power lines off and soldered directly to the VIn and Gnd pins on the photon (bypassing the micro USB socket).

The final wiring in place, the unit is ready for assembly

Once the wiring was all in place and all the solder joints checked carefully under a powerful magnifying lens (to check there were no ‘dry’ joints), the components could be packed out with sticky pads to ensure there was no rattling around. Finally we could fit the lid on the case and screw it all into place.

The final assembly was very satisfactory. We could turn it on to test it by plugging it into a USB charger battery. The photon was brand new and so commenced the setup routine with the flashing blue light. We were able to then connect to it with our mobile, claim and name the deice, and then upload the source code previously written. able to save off a JSON structure with all the data included to the Particle cloud on a regular basis. The Photon’s excellent design means that even once one or more units are deployed, their code can be flashed remotely to update their functionality. Multiple devices can be grouped into ‘products’ to allow concurrent code maintenance. We realise we will have to work out how to have photons automatically identify themselves individually when multiple data sources are collated to one database – something to think about next!

The new sensor in use and generating data

A test of the electrical current for the completed unit shows a draw of about 530mAh, which is pretty small for such a sensor and acceptable in that it isn’t drawing off too much current.


The exercise here is more one of hardware than of software – all the code and software methodologies were sorted as described with the earlier prototype. Here we have a physical design which will do what we want, plugging unobtrusively into a spare USB socket located on a WiFi router on the ceiling. The device will be now fixed into place in a lecture room and tested. To extend the project to a campus-wide solution, ideally a custom PCB would be created, designed to fit the case perfectly (or a dedicated case could be designed and 3D printed). Also, to gather the data together, potentially from multiple sources we will need a ‘dashboard’ and a linked database in a system able to receive the data streams. This solution would be bigger than the ThingSpeak tooling we have used for recent prototypes. We have been experimenting with ThingsBoard for this system scale solution, with a provisional version already running on a test Raspberry Pi – perhaps this will become the subject for a future blog.

BME680 and the Particle Photon


Here at Cranfield University we are putting in place plans related to the new ‘Living Laboratory’ project, part of our ‘Urban Observatory’. This project sits within the wider UKCRIC initiative, across a number of universities. Of the many experiments in development, we are gathering environmental data from IoT devices and building data dashboards to show the data and related analyses. One of our projects will be to place environmental sensors in our lecture rooms and public spaces to allow our facilities team to monitor conditions across the campus. In this blog, we show how this project is starting to take shape, and in so doing explain how we are connecting the Particle Photon device up with Bosch’s amazing multifunction BME680 sensor.

The controller we use is the Particle Photon, described in an earlier post. We started with a device without header poles, and then soldered in the ones we will use [D0, D1, +ve, Gnd]. The Photon was then connected to the WiFi network, following the instructions on the particle website Quick Start Guide.


Particle Photon

Next we used a Bosch BME680 sensor. This is able to measure temperature, pressure, humidity, and indoor air quality (IAQ) – the device currently returns gas resistivity in KOhms, rather than IAQ. It is also able to use the i2C interface, which only needs two connections, plus power (4 cables). Here the connection sockets are shown having been soldered in.

Bosch BME680 multi-function sensor

We then prepared four appropriate cables.


and then wired the devices up. The wiring connections used were:



Next, we opened the Particle Photon oneline cloud Web IDE. We created a new app, and located the Adafruit BME680 library and sample code.

The full code is presented below.

  This is a library for the BME680 gas, humidity, temperature & pressure sensor
  Designed specifically to work with the Adafruit BME680 Breakout
  ----> http://www.adafruit.com/products/3660
  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing products
  from Adafruit!
  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

double temperatureInC = 0;
double relativeHumidity = 0;
double pressureHpa = 0;
double gasResistanceKOhms = 0;
double approxAltitudeInM = 0;

void setup() {
  if (!bme.begin(0x76)) {
    Particle.publish("Log", "Could not find a valid BME680 sensor, check wiring!");
  } else {
    Particle.publish("Log", "bme.begin() success =)");
    // Set up oversampling and filter initialization
    bme.setGasHeater(320, 150); // 320*C for 150 ms

    Particle.variable("temperature", &temperatureInC, DOUBLE);
    Particle.variable("humidity", &relativeHumidity, DOUBLE);
    Particle.variable("pressure", &pressureHpa, DOUBLE);
    Particle.variable("gas", &gasResistanceKOhms, DOUBLE);
    Particle.variable("altitude", &approxAltitudeInM, DOUBLE);

void loop() {
  if (! bme.performReading()) {
    Particle.publish("Log", "Failed to perform reading :(");
  } else {
    temperatureInC = bme.temperature;
    relativeHumidity = bme.humidity;
    pressureHpa = bme.pressure / 100.0;
    gasResistanceKOhms = bme.gas_resistance / 1000.0;
    approxAltitudeInM = bme.readAltitude(SEALEVELPRESSURE_HPA);

    // ThingSpeak Channel Info                        
    unsigned long myChannelNumber =999999;      //  From your ThingSpeak Account Info
    const char * myWriteAPIKey = "YOURAPIKEY";  //  From your ThingSpeak Account Info (API KEYS tab)

    String data = String::format(

    Particle.publish("Sensor", data, 60, PRIVATE, NO_ACK);
  delay(10 * 1000);

Receiving data

Note the inclusion of the ThingsBoard API key ‘myWriteAPIKey’ into the JSON structure. ThingsBoard is used below.

Once we verified and flashed this code to the new Photon, it was able to start generating data. It took about 20 minutes to stabilise readings. Data was then picked up from the Particle.publish command in the source code on the Particle Console view. The data JSON structure is shown being generated (key not shown).

Particle Console

ThingSpeak Dashboard

Finally, following the approach outlined in this earlier blog, we built a ‘Webhook’ integration from the Particle web Console to ThingSpeak, and added a new Channel to receive the data to create a dashboard.

ThingsSpeak Dashboard – data shown with spline and averaged over 10 minutes

and as before the range of visualisations can be customised, and indeed the power of Matlab analytics can be blended in also.

Alternate dashboard with gauges


This blog has shown how easy it is to get a Particle Photon working with a Bosch BME680 multifunction sensor. As can be seen, the sensor outputs a range of data streams, barometric pressure, humidity, temperature and gas, and of these it is the gas resistance level, from which an Indoor Air Quality (IAQ) can be calculated, that is of particular interest. To quote Bosch, ‘The gas sensor within the BME680 can detect a broad range of gases to measure indoor air quality for personal well being. Gases that can be detected by the BME680 include: Volatile Organic Compounds (VOC) from paints (such as formaldehyde), lacquers, paint strippers, cleaning supplies, furnishings, office equipment, glues, adhesives and alcohol.’ This opens up a range of applications for this sensor which, combined with our project to monitor continuously public areas around the campus, a lot of options. As the Bosch technical sheet notes, IAQ provides a value from 0-500, with the following classification:

IAQ IndexAir Quality
0 – 50good
51 – 100average
101 – 150little bad
151 – 200bad
201 – 300worse
301 – 500very bad

The current device and software library only returns gas resistance, but a future project can be to link this to the Bosch libraries that calculate IAQ. There is also an interesting thread on the Pi Moroni blog for achieving this oneself, and more information here also.

Using ThingSpeak and a Particle Photon

Here at Cranfield University we are putting in place plans related to the new ‘Living Laboratory’ project, part of our ‘Urban Observatory’. This project sits within the wider UKCRIC initiative, across a number of universities. Of the many experiments in development, we are gathering environmental data from IoT devices and building data dashboards to show the data and related analyses.

One such device we use is the Particle Photon, and a typical attached device for environmental sensing is the DHT11 temperature/humidity sensor. We have discussed building the hardware to do this in an earlier blog. But here in this blog, we consider how to use ‘ThingSpeak‘, the ‘open IoT platform with MATLAB analytics‘ to receive, visualise and analyse the data. In this way, the Particle Photon will be used to collect the data, will transmit it to the Particle Cloud, and from there, a ‘WebHook integration’ will transmit the data to ThingSpeak for further use.

Particle Photon

For the code, we adapted the AdaFruit DHT11 sketch for Photon. Having calculated temperature (t), humidity (h), heat index (hi) and dew point (dp), the values are published (Particle.publish) up to the Particle Cloud.

#include <Adafruit_DHT.h>
// Written by ladyada, public domain
#define DHTPIN 2     // pin we're connected to
#define DHTTYPE DHT11		// DHT 11
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to DHTPIN
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

void setup() {
	Serial.println("DHT11 environment sensing");

void loop() {
	float h = dht.getHumidity();
        // Read temperature as Celsius
	float t = dht.getTempCelcius();
        // Read temperature as Farenheit
	float f = dht.getTempFarenheit();
        // Check if any reads failed and exit early (to try again).
	if (isnan(h) || isnan(t) || isnan(f)) {
		Serial.println("Failed to read from DHT sensor!");

        // Compute heat index
        // Must send in temp here in Fahrenheit!
	float hi = dht.getHeatIndex();
	float dp = dht.getDewPoint();
	float k = dht.getTempKelvin();

        // ThingSpeak
        // See https://community.particle.io/t/how-to-set-up-a-json-for-multiple-variables-in-a-webhook-integration/33172/4
        const char * eventName = "thingSpeakWrite_";        
        // This must match the name of the event you use for the WebHook
        // ThingSpeak Channel Info                        
        unsigned long myChannelNumber =XXXXXXX;
        const char * myWriteAPIKey = "XXXXXXXXXXXXXX";
        Particle.publish(eventName, "{ \"Humidity\": \"" + String(h) + "\", \"Temperature\": \"" + String(t) + "\", \"Dew_point\": \"" + String(dp) + "\", \"Heat_Index\": \"" + String(hi) + "\", \"key\": \"" + myWriteAPIKey + "\" }", PRIVATE, NO_ACK);  

Of note here is how the data are grouped for publication into a JSON block. Normally, Particle.Publish takes the pre-defined variable ‘{{{PARTICLE_EVENT_VALUE}}}’. However, in our case, we want to transmit more than one data value. We do this by building a JSON block and assigning it to an event name (e.g. ‘thingSpeakWrite_’). This is explained well in this blog article. The code (from above):

Particle.publish(eventName, "{ \"Humidity\": \"" + String(h) + "\", \"Temperature\": \"" + String(t) + "\", \"Dew_point\": \"" + String(dp) + "\", \"Heat_Index\": \"" + String(hi) + "\", \"key\": \"" + myWriteAPIKey + "\" }", PRIVATE, NO_ACK); 

will resolve to, for example:


Next in the Particle Photon Cloud interface, we can build a new ‘Integration’, following the Particle Tutorial example. We create a new Integration of type ‘WebHook’, and fill in the basic settings as follows:

Basic WebHook integration settings

Note the request format is JSON. Then, selecting the ‘Advanced Settings‘, we enter the following as the JSON block, attaching each parameter to a field number that will then appear in the ThingSpeak Channel.

  "event": "thingSpeakWrite_",
  "url": "https://api.thingspeak.com/update",
  "requestType": "POST",
  "api_key": "{{{key}}}",
  "field1": "{{{Temperature}}}",
  "field2": "{{{Humidity}}}",
  "field3": "{{{Dew_point}}}",
  "field4": "{{{Heat_Index}}}"

Hitting ‘Save’ should save and start up the Integration. Next, following the Particle Tutorial example, we created a new (free) ThingSpeak account to receive and process the data.


In ThingSpeak, we created a new ‘Channel‘, gave it a name and description, and defined the ‘fields‘ to receive data as above, thus:
field1: Temperature
field2: Humidity
field3: Dew_point
field4: Heat_Index
We also set the ‘Metadata’ setting to ‘JSON’
Finally, we save the Channel, and are ready to then visualise the data.

ThingSpeak allows us to direct the data received into a number of app tools, graphs, messaging utilities, analytics, MatLab and so on. Here we simply directed the output to a line graph and a gauge graphic. In the case below, the line graph type is set to ‘Spline’ on a ’10 minute’ average, and the temperature gauge range set from 0-50.

ThingSpeak Data Visualisation


This exercise has shown how to build a WebHook Integration from a Particle Photon, and to package up multiple data items as a JSON block, to pass this through the Particle Cloud and on to ThingSpeak for visualisation.

Yet to be explored are the many other tools ThingSpeak offers for processing the data: MatLab Analysis and Visualisations, PlugIns, ThingTweet, TimeControl, React, TalkBack and ThingHTTP.

ThingSpeak is a great online tool for handling IoT data, but note it is not the only choice available, and there are other similar online tools that could be used. Alternatively, one could also build a solution ‘in-house’ using packages such as ThingsBoard to receive, process and visualise the data arising from the IoT sensors. A good review of the choices of tools available is online on this blog, and there is lots of choice.

A final note is that in any operational system, data security should be considered, and HTTP authentication can help with this. All the stages of data transport in this example support Authorisation for example. Also the transport mechanisms could be investigated, such as MQTT.