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





Monday, October 10, 2011

Battery cost of sensor sampling

While at Droidcon UK 2011, I was asked to elaborate my claims about the battery cost of sensor sampling in a blog post. These claims can be found in my conference presentation but we thought it would help to describe them more in detail.

Continuous accelerometer sensor sampling introduces significant battery cost in Android devices. For example if you want to write an application that samples the sensor in the background and figures out, whether somebody double-tapped the body of the phone (not the active touch screen but anywhere on the phone's body), then the CPU of the phone can never sleep. You need to grab a partial wake lock to ensure continuous sampling otherwise the processing of the samples will stop when the device goes to sleep - typically some minutes after the keyguard activates. If you obtain partial wake lock, however, then you have to calculate with 1.5-4% battery consumption per hour (depending on sampling speed) which does not look like a lot but if you multiply it with 24 hours, you can see that you cannot sample the accelerometer continuously without spoiling the phone's usability.

Microsoft proposes a low-power co-processor for these background processing jobs with low computational complexity (accelerometer is typically sampled around 10-30 samples per second - you don't need a supercomputer to do that kind of processing). While this approach definitely solves the battery problem, there is the issue of an additional programming model (those low-power microcontrollers don't have full-blown programming environments) and it is very likely that application programmers will not be able to insert pieces of code to run on this microcontroller.

My proposal is to exploit low-power features of the accelerometer sensors widely used in Android devices. For example the very popular Bosch Sensortec BMA150 accelerometer sensor which can be found in variety of HTC devices (and probably others) has a wake up on motion mode.

In its data sheet, this mode is described like the following.

In general BMA150 is attributed to low power applications and can contribute to the system power management.

  • Current consumption 200μA operational
  • Current consumption 1μA sleep mode
  • Wake-up time 1ms
  • Start-up time 3ms
  • Data ready indicator to reduce unnecessary interface communication
  • Wake-up mode to trigger a system wake-up (interrupt output when motion detected Low current consumption in wake-up mode to master)


The BMA150 provides the possibility to wake up a system master when specific acceleration values are detected. Therefore the BMA150 stays in an ultra low power mode and periodically evaluates the acceleration data with respect to interrupt criteria defined by the user. An interrupt output can be generated and trigger the system master. The wake-up mode is used for ultra-low power applications where inertial factors can be an indicator to change the activity mode of the system.

This would allow the main CPU to go into sleep mode and to be woken up by the sensor only if there are movements. So if the device is laying on the table, there would be basically no power consumption due to sensor sampling. This would enable production-quality implementation of a range of applications, for example the Activity Level Estimator which is being researched at the University of Geneva.

The attractive property of this approach is that even though implementing it in Android devices and in the framework is not trivial, it is not very complicated either. The hardware is already in the devices, maybe the sensor's interrupt pin has to be wired up with the main processor. SensorManager needs to be extended with some functions that allows applications to activate this wake up on motion feature. Application model would remain consistent with the current Android application model, no need to fiddle with low-level microcontroller code.

Now there just need to be a device manufacturer that carries this through.

Thursday, April 22, 2010

Monitoring sensors in the background

Once I got the taste of making all sorts of measurements with sensors, I happily started to collect samples. Then I quickly ran into the background sensor monitoring problem. The use case is very simple: the phone is in idle state, keyguard is locked but it collects and processes sensor data. For example I wanted to record acceleration sensor data while cycling. I started the sensor application, started the measurement and locked the keyguard. On the Nexus One it means that there will be no further sensor data delivered to the application until the screen is on.

The source of the problem is that the sensor is powered down when the screen is off. This is implemented below the Android framework (either in the kernel driver or in hardware, I would be curious if anyone knows the answer) because if you recompile the latest sources from android.git.kernel.org, sensor data will be delivered nicely to the application in the emulator even if the keyguard is locked (the stock 2.1 emulator's Goldfish sensor does not emit any event, that is why you have to recompile from source) . The fact remains: if you want acceleration sensor data on the Nexus One, the screen must be on. This pretty much kills all the user-friendly applications that want to analyze sensor data in the background while the phone is idle. In the worst case, the screen must be constantly on (e.g. for a pedometer that needs to measure constantly because you never know when the user makes a step) but the situation for a simple context reasoner service is not much better. Such a service (read the vision paper for background, you need free registration to access) may want to sample the sensors periodically (e.g. collecting 5 sec. of samples in every minute). In order to perform the sampling, the screen should be switched on for this duration which would result in a very annoying flashing screen and increased power consumption.

You can observe these effects in the improved Sensors program that is able to capture sensor data in the background.

Click here to download the example program.

Start and deploy this program and you will see the familiar sensor list. If you click on any list item, the old interactive display comes up. The improvement here is that the application measures the sensor sampling frequency. The rate can be set in the settings menu, from the main activity. If, however, you long-press on the list item, the sampling will be started in the background. In this case there is no interactive display of the samples, they are always saved into the /sdcard/capture.csv file. The background sampler does respect the sampling rate setting, however. The background sampler is implemented as a service.

So far there is nothing extraordinary. You may observe the ScreenOffBroadcastReceiver class in SamplingService that intercepts ACTION_SCREEN_OFF intent broadcasts and does something weird in response. In order to understand its operation, you must be aware that the power manager deactivates all the wake locks that are stronger than PARTIAL_WAKE_LOCK when the keyguard powers the device down. Obtaining for example a SCREEN_BRIGHT_WAKE_LOCK in the broadcast receiver would be of no use because at this point the screen is still on and the wake lock would be deactivated when the screen is turned off. Instead, the broadcast receiver starts a thread, waits for 2 sec (experimental value) and then it activates the wake lock with wakeup option. Try to push the power button when the background sampling is on, the screen will go off for 2 seconds but then it is turned on again and you will see the keyguard screen. If you check the log, you will see that the sensor sampling stops for that 2 seconds then it comes back on. Don't worry, when the background sampling is stopped (by long-pressing the sensor's name in the list again) the screen will turn off correctly.

Ugly? You bet. Not only the solution is a bad hack but it also prevents the device from switching off the screen and those AMOLED displays plus the high-powered processors eat battery power like pigs. The decision that the sensors are powered down when the screen is off prevents the implementation of some of the most exciting mobile applications and significantly decreases the value of the platform.

But enough of the grunting. This is the state of the art in background sensor sampling in Android (as of version 2.1 of the platform), I will continue with signal processing algorithms.