Showing posts with label dht22. Show all posts
Showing posts with label dht22. Show all posts

Wednesday, March 2, 2016

Android phone as weather station

The previous post was about a low-cost Bluetooth Low Energy sensor (really, one sensor unit that includes the BLE-enabled microcontroller too costs less than 15 USD and that's just a single prototype, economies of scale come on top of that) and its accompanying Android app that allows obtaining sensor reading manually. That's not bad but manually reading data is sort of inconvenient. If you want to know, what the temperature and humidity was in the dawn, you have to be awake in that early hour. Personally, I prefer to sleep then so I decided to automate the whole process.

Click here to download the sources of the Android application. The content of the archive is the app/src/main subtree of an Android Studio project. In addition to extracting the sources into the app/src/main subtree, update app/build.gradle like this:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.jjoe64:graphview:4.0.1'
}


The project depends on Jonas Gehring's GraphView project, hence this new dependency.

So what can we expect from this new app? In case of the app that came with the sensor in the previous post, you started a manual scan and if the sensor was in range, you got the humidity/temperature data. The new app scans and stores data in the background. Once it is started, it sets up a periodic timer (default timeout is 1 hour but can be changed in the settings menu) and when the timer fires, it makes a scan. If it finds a BLE node whose advertisement fits our criteria (e.g. it advertises services with the UUID I allocated) then it extracts the measurement data from the advertisement message and stores it in a database on the device. This variant does not yet upload the data to a server, that may come later. However, it can visualize the measurements on simple graphs, hence the dependency on GraphView. Like this:






Let's see the interesting bits of this app.

First and foremost, it is an interesting feature of this application that the BLE layer is used in such a way that reading the sensor is not an extra cost for the sensor. As the measurement data is embedded into the advertisement packets that the device broadcasts anyway, it does not matter if 1 or 1000 phones read and store data. So this sort of sensor network can grow into an entire ecosystem - the more phone users install and use the app, the more precisely the measured quantity will be available once the phones upload their catch to the server.

If you observe, how the data is stored (DHT22SensorDataProvider.java), you can recognize an important shortcut that I made: the database structure depends on the sensor being used. This provider depends on the fact that DHT-22 (the actual measurement device) provides temperature and humidity data in the same reading. A different sensor (like the Bosch BME280 sensors sitting in my drawer waiting for their turn) will require a new provider and also a modification of the visualization part. So there's significant development potential in making the app more flexible when it comes to adding a new sensor type.

The actual sampling of the service happens in BLESensorGWService using the AlarmManager to trigger the scan. Now getting the device awake if it was just sleeping is not a simple business. Observe in the list below, that even though there's always an hourly reading, there's a significant variation when the reading happens.



In case of our weather reading, it was not a problem but some sensors may have more variable data. A large number of devices reading and uploading would solve the problem of reading time variations.

GraphMeasurementActivity is the activity that depends on Jonas Gehring's GraphView.  The graphs are very simple so if you have another favourite graph view component, just replace it there.

So we are at the point that we added sensors to our Android device using Bluetooth Low Energy and created an application that samples them producing nice weather-related data series. The next step will be the integration of a cloud-based data analysis. I am still thinking, which one to go for.

And finally, the picture of the sensor, in its "weather-resistant" box.





Tuesday, February 2, 2016

Thermometer application with nRF51822 and Android

I built quite many prototypes on this blog with RFDuino based on Nordic Semiconductor's nRF51822 and I can still recommend that small development board to people who want to get initiated quickly and painlessly into the world of Bluetooth Low Energy programming. The limitations of RFDuino became apparent quite soon and it was time to get deeper. On the other hand, I wanted to stay with the excellent nRF51822 so I looked for a breakout board - as simple as possible.

This is how I stumbled into Florian Echtler's page about low-cost BLE development environment based on the nRF51822 and the Bus Pirate programming tool. So I quickly ordered a no-name variant of Waveshare's Core51822 breakout board, a Bus Pirate tool and a bunch of DHT-22 sensors (because I wanted to measure something in the environment). Also note that the breakout board has a connector with 2 mm pin spacing which is not the usual 0.1 inch pitch. It helps if you have a prototyping board with both 2 mm and 0.1 inch pitch like this one which cannot be found in every store.

Generally speaking, following the instructions on Florian's page was easy enough. I ran into two issues. First, I had no success with the SWD programming software he refers to but Florian's fork (which is based on an earlier version of the programming software) worked well for me. Second, I experienced instability if the GND pins of the breakout are not connected (there are 2 of them).

First about the hardware. The schematic below show only the parts that are connected to the pins of the breakout board, the schematic of the breakout board itself is not included.



Highlights:


  • DHT-22 is connected to P0.17 which is both input and output depending on the communication phase.
  • P0.21 LED provides a feedback about the BLE activities. This is a convention coming from the PCA10028 dev board that we lied to the Nordic tool chain that we have. You can omit this LED if you want to save some energy.
  • SV1 header is a TTL serial port where the example program emits some debug messages. You can omit this header if you are extremely confident. I use a level converter like this to connect this port to a standard RS232C port. The UART operates on P0.18 (RxD) and P0.20 (TxD).
  • SV2 header goes to the Bus Pirate. Check out Florian's document about the connection. Make sure that this cable is as short as possible.
Here is how the board looks in all its glory, the Bus Pirate and the RS232C level converter boards in the background. These are of course not needed for deployment, the board runs standalone after the testing is successful.






Click here (adv_dht22.zip (nRF51822), bledht22.zip (Android)) to download the example programs related to this blog post.

Let's start with the code that goes into the nRF51822 which can be found in adv_dht22.zip. The assumption is that you completed Florian's instructions, including the upload of the S110 soft device. Then unzip adv_dht22.zip and do the following modifications:

  • Edit Makefile and make sure that the RF51_SDK_PATH variable points to the location where you installed the Nordic SDK.
  • Edit upload.sh and make sure that the paths point to the location where you installed Florian's version of the SWD programmer. Also, make sure that the USB device is correct (/dev/ttyUSB0 by default).
Now you can say "make" and then "upload.sh". If all goes well, the code is installed in the nRF51822 and you get debug messages on the serial port. At this moment, the nRF51822 is already advertising the measurements it obtained from the DHT-22 sensor. You can check the content of the advertisements with this test tool.

The code looks quite frightening compared to the super-simple RFDuino equivalent but most of it is just template. My highlights:
  • Check out in advertising_init(), how the advertisement packet is set up. We transfer the measurements in a service data GAP field and I took the liberty to allocate a 16-bit UUID for it (quite far from the standard service UUIDs).
  • Check out timers_init(), timers_start() and sampler_timer_handler() methods how the periodic reading of the sensor and the update of the advertisement packet is accomplished.
  • DHT-22 sensor handling is done in dht22.c. This sensor has a somewhat peculiar 1-wire interface. Read this document and the code will be easy to understand.

Regarding the Android code: this is just the app/src part of the source tree of an Android Studio project. I adopted this rather primitive export method as this super-advanced IDE still does not have code export option that its obsolete predecessor, the Eclipse IDE used to have. Check out onLeScan method in MainActivity.java to see, how the BLE GAP parser introduced in this blog post is used to take apart the advertisement message and filter BLE nodes that advertise DHT-22 measurements.

The outcome looks like this:




Note that each sensor is identified by a 64-bit unique ID (a service of the nRF51822). Now this data just needs to be uploaded into some sort of service and then the big data analysis can start ;-). More about that later.