Showing posts with label sensor. Show all posts
Showing posts with label sensor. 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.





Friday, October 25, 2013

Saturday, January 21, 2012

Measuring movement with accelerometer and gyroscope

Santa Claus brought me a present and that sadly means retiring of my trusty Nexus One. Not that the phone has any problem - it still functions perfectly. As Google does not update the Nexus One anymore with new software release, I had to change. And the winner is - well, not the Galaxy Nexus, that's too expensive. I chose a Nexus S because of its attractive price, its update path toward Android 4.x (it is actually the cheapest option today of an Android 4 phone) and its built-in gyroscope.

I wanted to put my hand on a gyroscope-equipped phone for a long time. I discussed in length the problems of using only the accelerometer when identifying movements in my Droidcon 2011 presentation and I hinted that additional sensors could be used to compensate for the motion acceleration that is added to the gravity acceleration and is impossible to separate in the general case. That's what I am aiming to do with the gyroscope in this series of posts.

First let's see the problem. As you can see in slides 23 and 24 of the Droidcon 2011 presentation, there is a problem if the accelerometer is subject to gravity and motion accelerations at the same time. These are impossible to separate in the general case which corrupts both use cases. If the accelerometer is used to measure gravity (e.g. to figure out the device tilt), any motion acceleration distorts the measured tilt. If the accelerometer is used to measure motion acceleration and the exact direction of the gravity acceleration is not known, it is impossible to subtract it and the components of the motion acceleration is impossible to calculate. We need another sensor to acquire additional information to separate the gravity and motion components.

Gyroscope sensor is somewhat rare in today's Android phones. Nexus S was the first to have gyro sensor and since then some high-end phones like Galaxy S II got the sensor. If you want to play with gyro, check, whether your phone has the sensor.

The gyroscope measures angular speed along the 3 axes. As the SensorManager in Android delivers the sensor samples along with timestamps measured in nanoseconds, it is possible to calculate the rotation angle in radian by multiplying the angular speed with the time difference between the current and the previous sample. This means that we know the rotation angles along the 3 axes from the previous to the current gyroscope sample.

Thus the gyroscope can be used to replace the accelerometer when the accelerometer data is distorted by motion acceleration. If we have a reliable gravity vector measurement, we can use the rotation angles measured by the gyroscope to rotate this vector to its new position. As the gyroscope is not subject to motion acceleration, the gravity vector updated by the gyroscope rotation angles will not be affected by the motion acceleration.

The example program is available here.

How exact could this tracking be? I have made a simple sensor sampling application that samples the accelerometer and the gyroscope paralelly. If you try it out, please check that both the accelerometer and the gyroscope sensors' name is displayed - this means that they are available. Move the device only slowly - we don't want motion acceleration in this measurement. The sample file is saved in the file capture.csv on the SD card - typically /sdcard/capture.csv. Fetch this file and you can analyse it with this Sage script called gyro.py. This script expects the measurement data file in the current directory with the name of agx.csv - you can easily change it in line 244.

As the figure below demonstrates, the real gravity vector (blue line) is pretty close to the gravity vector simulated with the gyroscope (red line). Eventually the cumulative errors will make the simulated vector diverge from the real gravity vector - more about later.