In this Android Things project we will use an Ultrasonic sensor with a Raspberry Pi 3 to measure distance.
We will work with the standard GPIO read and write methods, we will learn how to send ultrasonic waves with the sensor, and we will discover some issues.
The sensor is an HC-SR04 Ultrasonic sensor. (I ordered from Amazon.)
The HC-SR04 ultrasonic sensor uses sonar to determine distance to an object like bats or dolphins do. It offers excellent non-contact range detection with high accuracy and stable readings in an easy-to-use package. From 2cm to 400 cm or 1” to 13 feet. It operation is not affected by sunlight or black material.
From here you can download the datasheet of the sensor.
As in the previous project, I suggest to follow Google’s tutorial to prepare your Raspberry Pi 3 for Android Things development.
Please follow the steps here:
Now it is the time to connect the sensor to our Raspberry Pi.
As you see in the picture the Ultrasonic sensor has 4 pins.The VCC needs to be connected to a 5V power pin, the GND obviously to a Ground pin, and the Trig (Trigger) and the Echo pins connect to a GPIO.
And here is how I connected it to my Raspberry Pi:
And this it how it looks together:(On the left side you can see a pinout diagram which illustrates the locations of the available ports exposed by the breakout connectors of the Raspberry Pi 3 board)
To configure a new project, you can follow the (already mentioned) tutorial from Google, or you can use and modify the source of our previous application.
Before we start implementing the necessary code, I explain a bit how the Ultrasonic sensor works:
This is how it looks on a timing diagram:
The timing diagram of HC-SR04 (source)
Let’s see the code!
First we declare the GPIO pins:
Then we need to setup the Echo pin (BCM20) for read:
And the Trigger (BCM21) pin for write:
And now the fun begins.
We need to send a 10us pulse to the Trigger pin and listen on the Echo for the beginning and the end of the response pulse.
I will show you two ways to do this, because I discovered some performance issues in some cases. (It is possible that my implementation is not correct in the under-performed code)
The first one is the “old school way”, the way how you do it on an Arduino device, or in C or Python e.g. on your Raspberry Pi under a Linux operating system. This is a universal, synchronous, procedural way, you don’t have callbacks, asynchronous methods.This code performs well, as good as you would implement it in C or Python.
You can run this code in different ways, with a Handler, or just in a new Thread, etc…
I run it now in a separated Thread :
It works properly. You can put something in front of the sensor, move it farther and closer, and you will see the distance in cm in the console.
(I will mention the commented lines in the Findings section)
The second way is the Android Things API provided asynchronous GpioCallback() way.
To use the callbacks, we need to register our listener on the ECHO pin:
I defined a callback Handler also, because it has an impact in the measurement.I spent a lot of time to get correct results with the async implementation, and this helped also.
Usually you just register your callback with the registerGpioCallback (GpioCallback callback) method. That means you listener will be called on the same Thread where you called the register method. Sometimes (in a lot of basic example) this is the UI Thread. And the slowness of your UI has impact on your callbacks.
In our cases the impact is 1,5cm in the accuracy of the distance measurement.
So let’s prepare the Handler:
And here is our method to “read” the distance asynchronously:
Basically it does nothing, except triggering the measurement on the sensor.The real calculation happens in the callback:
To run the whole calculation we can also use the separated Thread way what we used in the 1. implementation, or we can use a Handler to execute our calculation:
Done.Run your code and check the measurements in the ADB log. It works quite well.
(Oh yeah, and do not forget to close your resources in both implementation, if you don’t need them)
If we use lot of computation in the callbacks, between the catch of the ECHO high/low pulses, it will impact your measurement. You see a lot of commented log lines. If you put them back, the minimum measurable distance will be around 20 cm, because the device needs some time to process your logging. And if you measure your time in nanoseconds, it matters!
You can also experience with the duration of the methods.In the first implementation in the while loops if you put back the time logging methods you will see.Processing a Log.d() method takes almost 10x more time than assigning a value to a variable.
Avoid from the UI Thread.E.g. If you have a combination of heavy computation or logging and callbacks on the UI Thread you will see a really huge impact on your measurements. The minimum measurable distance can easily jump above 30cm.
I was not able to reproduce the same performance in the 2. implementation as we have it in the first one.
Maybe I missed something, I implemented something on a wrong way or this is an API issue in Android Things.
I am not sure yet.I am still continuously thinking and testing, hopefully I will figure it out.
If you have any idea, any remarks, please feel to free to comment or send me an e-mail, or modify the source of the project: