Friday, January 1, 2016

Estimote vs Kontakt.io - Radiated Emission Measurements Comparison

In December, we took a thorough look at beacons in a semi-anechoric chamber. The chamber is equipped with a turn table, antenna for measurements and on the center of the table we placed a cardboard box to be used for mounting beacons in an upright position. This position is always depicted in showcase materials of beacon vendors, so we used it for a default setup. These were the positions the beacons were used in:


The overall setup of the measuring chamber was as follows. Beacons were in their initial position front-facing the measuring antenna. The measuring antenna was always in horizontal position. Beacons were transmitting with the power of +4 dBm.



We were interested in measuring of following factors: transmission channel (i.e. frequency), and radiated emissions in vertical and horizontal polarization. By Bluetooth LE specification. BLE device should use channels 37 (2402 MHz), 38 (2426 MHz), 39 (2480) for advertising. Advertising channels are allocated in different parts of the spectrum to provide immunity against interference from WiFi. 

Circular diagrams visualize field strength [dB(µV/m)] of radiated emissions in corresponding angle. Note that 180° is the initial position. Vertical polarization of the beacon is represented in orange, horizontal polarization is represented in blue.

Estimote beacon

The beacon without its cover reveals antenna located in the top part.





Kontakt.io beacon

Antenna of this beacon is the blue thingy next to the logo.




Conclusion

Both beacons were using all above-mentioned channels for broadcasting. Kontakt.io's transmission levels were stronger than Estiomote's.
When comparing field strength for vertical polarization, we can see that Estimote's field strength varies significantly along the measurement spectrum. The values for horizontal polarization are much more stable. Note that Kontakt.io's sudden drop around 90° and 270° is caused by side orientation of the beacon. Therefore it is desirable to place the beacons in production environments, to be facing the user if possible.
From the diagrams it is visible that calculation of distance based on FSPL is highly unreliable, since emitted signal strength varies not only from device to device, but also from beacon and measuring device polarization.
Any other thoughts?

Credits

Martin Pospíšilík - measurements
Adam Studenič - photos

Sunday, September 6, 2015

Accent Material Colors

How to choose the right accent color? Official guidelines don't help much:

Limit your selection of colors by choosing three hues from the primary palette and one accent color from the secondary palette.

Obviously, some colors are good match, some are not. But what is the key behind pairing a perfect match? If we are aiming for contrast, complementary colors may be the right choice. When placed next to each other, they create the strongest contrast for those particular two colors. They are opposite of each other. And opposite is something we can calculate.


I have created a little demo, to showcase its potential. You don’t have to use this exact shade of complementary color, but simply inverting the primary color, gives you nice starting point. Try it out:


Title Change My Colors
+
Red
Pink
Purple
Deep Purple
Indigo
Blue
Light Blue
Cyan
Teal
Green
Light Green
Lime
Yellow
Amber
Orange
Deep Orange
Brown
Grey
Blue Grey
Black

Tuesday, July 28, 2015

Calculating distance from WiFi AP using RSSI

Certainly the best approach to start looking into this is using a free-space path loss. It is by no means optimal - notice the free-space part of its name, so you actually need no obstacles between measuring device and AP. But it's at least a good approximation.
Wikipedia defines free-space path loss in decibels as follows:


This is for distance d in km and frequency f in GHz. We want to measure distance in m and frequency in MHz, so the formula becomes:


Solving for d, we got:


Now, what to do with the FSPL? Is it equal to RSSI? Unfrotunately no. First, let's understand, what we can expect as FSPL values.


First, we made a series of measurements with different devices to analyze, how RSSI changes over distance and we averaged them (blue RSSI series). We can see that values up to -50 dBm, can be used for somewhat relevant calculation. Lower values are highly unstable.
Second, let's have a look on FSPL values. If we calculate for 2412 MHz, and for the distance we use values (1, 2, ..., 20 m), we can get the FSPL, from the first formula. Note that calculated values are positive, so I took the liberty of inverting them over distance axis (orange calcRSSI series). This looks a lot like our first graph series. We just need to shift it up (gray corrRSSI series).
Now we can say that for measuring on Android, FSPL = approximately 6.7 - RSSI.

My high school physics teacher would probably kick my ass for this, but it works.

So written in Java, the final formula is:
public static double calculateDistance(double rssi, double freq) {
        return Math.pow(10.0d, (27.55d - 40d * Math.log10(freq) + 6.7d - rssi) / 20.0d);
}

Sunday, July 12, 2015

Why is using signal strength at a distance of 1m for estimating iBeacon’s distance not a good idea?

Apple states that:

“To provide the best user experience, it is critical to perform calibration in your deployment environment. As each beacon is installed you should perform a calibration step. Core Location uses an estimation model that requires calibration at a distance of 1 meter away from the beacon.”

This calibration has to be done ideally for every installed beacon. In this way, you will get the best distance estimate. But this is true only if you don’t change the beacon’s transmit power or you keep measuring it with the same mobile device.
Transmit power is degrading itself gradually with time.  But this is the least of your worries. The important part is measuring the beacon’s signal with the same device/antenna. As you can understand, this is applicable only to a limited number of devices. So for Apple, that’s no trouble. But when on Android, you mustn’t rely on estimating distance using this 1m away measured constant broadcasted by beacon.  The results may be misleading, since your device’s antenna may differ significantly, from the reference device’s one.
Better approach would be to build up a list of device specific calibrations and distribute it along with your app. But this is really hard to implement, even though there is at least one vendor using it. And as you can see, it only supports 2 devices so far. So there is obviously some space for improvements, right, Lime?

Thursday, July 2, 2015

Blank Activity with no menu template for Android Studio?

Are you tired of Android Studio generating you only blank Activity with menu, even though you don't need it? Do you hate when it also generates unnecessary Hello World! string resource?


Well, these times are finally over. Let me present you Blank Activity Optional Menu template. Just copy folder BlankActivityOptionalMenu from zip's contents into android-studio/plugins/android/lib/templates/activities/ and restart Android Studio. Now, you can create new Activities without a menu!
Not good enough? You can contribute to this project on Github!

Wednesday, July 1, 2015

PV256: #1 Toto je Android

I apologize for writing in Czech, but the following article is intended as a study material preview for the course PV256 on Masaryk University - Faculty of Informatics.

Celá série přednášek úvodu do vývoje Android aplikací byla přesunuta na Gitbooks.

Tuesday, June 9, 2015

My build.gradle configuration

When inspecting projects of other people, I tend to peek into build.gradle file to look for various useful tweaks. I have gathered a few and now I want to share it with all of you. If you have some useful tweaks of yours not mentioned here, don't hesitate to share them in the comments section.
//keep your version divided into 4 parts, this way it's clearer to understand, than having only one number
def versionMajor = 0
def versionMinor = 1
def versionPatch = 0
def versionBuild = 0 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    //standard gradle naming says almost nothing about your build; this way you can easily distinguish between different builds and versions
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(
                    output.outputFile.parent,
                    "$project.name-$variant.name-$variant.versionName-${variant.versionCode}.apk")
        }
    }

    //define your release config, so you can easily build and run release builds; this way you can avoid painful build->generate signed apk procedure
    signingConfigs {
        release {
            storeFile file(RELEASE_STORE_FILE)
            storePassword RELEASE_STORE_PASSWORD
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
        }
    }

    defaultConfig {
        applicationId "cz.droidboy.whatever"
        minSdkVersion 15 //minimal api level of 15 is sufficient
        targetSdkVersion 22 //always target the latest sdk version

        //keep resources for listed configs only; this way you can reduce apk size by removing unnecessary resources from libraries
        resConfigs "cs", "sk", "en" //keep resources only for listed languages
        resConfigs "hdpi", "xhdpi", "xxhdpi", "xxxhdpi" //since latest phones have insanely high dpis, there's no need to keep resources for those lower than hdpi

        versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
        versionName "${versionMajor}.${versionMinor}.${versionPatch}"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    buildTypes {

        release {
            minifyEnabled false // I don't use proguard
            signingConfig signingConfigs.release
        }

        //it's a good practice to keep debug and release builds distinguishable form each other; I also change debug build's icon to visually distinguish those 2; this way you can also have installed both versions simultaneously
        debug {
            applicationIdSuffix '.debug' 
        }
    }

    lintOptions {
        textReport true // if true, generate a text report of issues (false by default)
        textOutput 'stdout' // location to write the output; can be a file or 'stdout' (standard output)
    }
}

dependencies {}
Local gradle.properties file, which isn't under version control. Define your keystore credentials here.
RELEASE_STORE_FILE=path_to_the_file #use \ on windows, / on Linux/Mac
RELEASE_STORE_PASSWORD=password
RELEASE_KEY_ALIAS=key_alias
RELEASE_KEY_PASSWORD=key_password