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 read and write methods, we will learn how to send ultrasonic waves with the sensor, and we will discover some issues. GPIO Requirements We use a with pre-installed (version 1). Raspberry Pi 3 Android Things Developer Preview The sensor is an . (I ordered from .) HC-SR04 Ultrasonic sensor 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 you can download the datasheet of the sensor. here Setup As in the , I suggest to follow Google’s tutorial to prepare your Raspberry Pi 3 for Android Things development. previous project Please follow the steps here: _Raspberry Pi 3 Model B is the latest iteration of the world's most popular single board computer. It provides a quad…_developer.android.com Raspberry Pi 3 | Android Things Wiring Now it is the time to connect the sensor to our Raspberry Pi. As you see in the picture the has 4 pins.The needs to be connected to a 5V power pin, the obviously to a Ground pin, and the and the pins connect to a GPIO. Ultrasonic sensor VCC GND Trig (Trigger) Echo And here is how I connected it to my Raspberry Pi: → 5V (Pin 2) VCC → GPIO 21 (BCM21, Pin 40) Trig → GPIO 20 (BCM20, Pin 38) Echo → GND (Pin 34) GND 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) Software 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 _Things apps use the same structure as those designed for phones and tablets. This similarity means you can modify your…_developer.android.com Create an Android Things Project | Android Things Before we start implementing the necessary code, I explain a bit how the Ultrasonic sensor works: to start a measurement, the pin must receive a pulse of (5V) for at least 10us (10 microsecond) Trig (Trigger) HIGH this will initiate the sensor and it will transmit out 8 cycle of ultrasonic burst at 40kHz and wait for the reflected ultrasonic burst when the sensor detected and ultrasonic wave, it will set the pin to (5V) and delay for a period (width) which proportion to distance. Echo HIGH to obtain the distance, we need to measure the pulse. width of the Echo 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 pin ( ) for read: Echo BCM20 And the ( ) pin for write: Trigger BCM21 And now the fun begins. We need to to the pin and for the beginning and the end of the response pulse. send a 10us pulse Trigger listen on the Echo , because I discovered some performance issues in some cases. (It is possible that my implementation is not correct in the under-performed code) I will show you two ways to do this 1. implementation The first one is the , the way how you do it on an Arduino device, or in C or 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. “old school way” Python You can run this code in different ways, with a , or just in a new , etc… Handler Thread 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 section) Findings 2. implementation The second way is the Android Things API provided . asynchronous GpioCallback() way To use the callbacks, we need to register our listener on the pin: ECHO I defined a callback 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. Handler Usually you just register your callback with the method. That means you listener will be called on the same where you called the register method. Sometimes (in a lot of basic example) this is the UI . And the slowness of your UI has impact on your callbacks. registerGpioCallback (GpioCallback callback) Thread Thread In our cases of the distance measurement. the impact is 1,5cm in the accuracy 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 way what we used in the 1. implementation, or we can use a to execute our calculation: Thread Handler 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) Findings The accuracy of the measurement results are the same (between a certain range) in both implementation. The minimum measurable distance with the 1. implementation is around 8cm. (Same as you write your code in C or Python) The minimum measurable distance with the 2. implementation is around 12cm. If we use lot of computation in the callbacks, between the catch of the 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! ECHO You can also experience with the duration of the methods.In the first implementation in the if you put back the time logging methods you will see.Processing a method takes almost 10x more time than assigning a value to a variable. while loops Log.d() 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. Notes The error cases are not handled in the example app. The measurement capability of the sensors are not the same. I ordered a pack of HC-SR04 sensors from Amazon (pack of 3 pieces, same sensors), and e.g. one of them can measure properly only for 160cm, and an other one measures properly for 240–300cm. If you want to measure properly, you need to first verify the distance with a ruler or with a tape measure, then adapt your code. When you measure a distance, I suggest to do 2–3 measurements and calculate an average of those, because the results have 1–2cm dispersion. Always check the datasheet of your sensor to implement correct algorithm 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: _Contribute to AndroidThings-UltrasonicSensor development by creating an account on GitHub._github.com Danesz/AndroidThings-UltrasonicSensor