Tuesday, October 18, 2016

Android phone as weather station with improved sensor

The previous two posts introduced a BLE-enabled weather sensor (temperature and humidity) and the Android application that extracts data from this sensor. I hinted that I intend to proceed with a more sophisticated sensor, Bosch Sensortech's BME280 but other projects diverted my attention (shameless self-promotion: read this paper about microcontrollers, image processing and low-power wide area networks if you are curious, what kind of projects took my time). But I never forgot my BME280 temperature/humidity/pressure sensors sitting in my drawer and once I had a bit of time, I resurrected the project.

The idea is the same as with the DHT-22. The nRF51822 combined ARM Cortex-M0 microcontroller/Bluetooth Low Energy radio unit will make the sensor data available over Bluetooth Low Energy (BLE) access. The smartphone will read this data and display it to the user. Later (not in this post) I intend to upload the data into some web service for analysis. We have already done this with the DHT-22, now we extend the sensor range with the BME280.

Click here to download the Android application. Click here to download the nRF51822 projects that are running on the sensor hardware.

Let's start with the sensor. Below is the schematic for the hardware (click to enlarge).

The difference between this and the previous one is that the DHT-22 was connected to a simple GPIO pin while the BME280 uses the more sophisticated I2C bus. As the BME280 is quite miniature, I used a breakout board for the sensor too. LED1 and the serial debug port are optional (but quite useful). Debug messages are emitted to the serial port, you need a 3.3V-to-RS232 converter on the TxD pin if you want to observe those.

As described previously, the circuit is realized with a low-cost nRF51822 breakout board and is programmed with the Bus Pirate programmer, adapted to nRF51822 by Florian Echtler. The only thing I changed in this setup is that this time I moved the projects to the latest version of the SDK which is the 12.1.0. Also, the soft device (the program module implementing the BLE stack) was bumped from S100 to S130. These decisions caused quite a headache because there's significant difference between the old SDK and the 12.1.0. Therefore I decided that in the nRF51822 project file I share not only the sensor project (called adv_bme180) but two simpler ones (blinky_new and blinky_new_s130) as additions to the instructions on Florian's page. As a recap: the soft device need to be flashed into the device before any BLE application is flashed and the starting address of the BLE application depends on the size of the soft device. This has changed between S100 and S130, hence the updated projects. In both blinky_new_s130 and adv_bme280 you will find the  convert_s130.sh and upload_softdevice.sh scripts that convert into binary format and flash the S130 soft device that came with the Nordic SDK.

Once you uploaded the S130 soft device, compile the project in adv_bme180 and upload it into the nRF51822. The sensor node works the same way as the DHT-22 version. The MCU in the nRF51822 acquires measurements from the BME280 by means of the I2C bus (called Two-Wire Interface, TWI in the nRF51822 documentation), once in every second. This includes temperature, humidity and pressure. Then the measurement values are compensated by the read-only calibration data also stored in the BME280 that the MCU reads in the initialization phase. The BME280_compensate_T, BME280_compensate_P and bme280_compensate_H functions come from the BME280 user's manual. The result is the compensated temperature, humidity and pressure values that the MCU puts into the BLE advertisement data. The advertisement data also contains the nRF51822's unique ID that is used to identify the sensor. The sensor has no name as the measurement+ID data is now too long to allow sensor name info too, BLE readers now recognize the sensor purely by its unique UUID.

Now on to the Android part. The architecture of the application is pretty much the same as described in the previous post. Creating an Android Studio project works the same way as described there: create an empty Android Studio project, write over the app/src/main subtree with the content of the archive that you downloaded from this post and update app/build.gradle file with the GraphView dependency.

The BME280 functionalty was inserted in three places. First, BME280 data has its own data provider (BME280SensorDataProvider.java). This new provider is able to handle pressure data that DHT-22 measurements don't have. BLESensorGWService properly recognizes BME280 sensor nodes beside the DHT-22 sensor nodes (so both are handled), parses BME280 advertisements and puts the measurement data into the BME280 data provider. MainActivity knows about the BME280 data provider, uses its data to create the sensor list and invokes BME280GraphMeasurementActivity if the sensor in question is BME280 sensor. This new visualization activity has pressure graph too.

This is how the sensor list looks like with a DHT-22 and a BME280 sensor (DHT-22 does not have pressure data, BME280 does).

And this is how the pressure graph looks like in the BME280 visualization activity.

And at last, some words about the deployment. I got a question, how the power supply works. After more than half a year of operation, I ended up with a discarded 12V motorcycle battery as power source. This battery used to have 6Ah capacity, now it has about half which is not enough to feed a motorcycle but is quite enough to yield 1-2 mA per sensor node for a long time. Also, this battery is designed to withstand quite severe weather conditions. I can only recommend discarded but still functional motorcycle/car batteries as power source if the place available for the sensor permits it.

Here is how the BME280 sensor looks like in its protective plastic box. The small panel in the foreground is a cheap DC-DC converter (not shown in the schematics) which makes the step-down from 12V to 3.3V.

And here is how the sensor nodes sit in an outdoor box with the battery. The lid of the BME280 node is removed for demonstration, the other box contains the DHT-22 sensor.

Now the part that is really missing is the data upload/data analysis functionality.