Hello everyone,

today I was playing with my new Raspberry Pi 2 running Windows 10 IoT Core and I am pretty excited about the way it works and how awesome it is to build apps for it.
I am going to use it to build a maze solving robot for ITU Robot Competition which takes place in Istanbul, Turkey every year.

What will we need?

  • Raspberry Pi 2
  • HC-SR04 Ultrasonic Sensor
  • Breadboard
  • Female-to-Female Jumper Wires
  • Resistor 1kΩ
  • Resistor 2kΩ

 

What is a Raspberry Pi?

The Raspberry Pi is a computer that is very cheap and quite small. It has hardware pins called GPIO pins that allow you to connect all manor of sensors, control boards, and other things. The GPIO pins can then be accessed directly by your code.

RP2_Pinout.png
Here is a super useful image showing every pin usage on Raspberry Pi 2.

 

 

What is an HC-SR04 Ultrasonic Sensor?

It’s a cheap sensor that can be used to measure the distance between itself and an object in front of it by sending an ultrasonic pulse and listening for its echo. The HC-SR04 can be connected to many things including the Raspberry Pi.

hc-sr04.jpg

 

Why do I need the resistors?

The sensor’s output signal (ECHO) is rated  at 5V. However, the input pins on the Raspberry Pi GPIO are rated at 3.3V.
Sending a 5V signal into that unprotected 3.3V input pin could damage the GPIO pin of the Raspberry Pi 2, which is something we want to avoid! We’ll need to use a small voltage divider circuit, consisting of two resistors, to lower the sensor output voltage to something our Raspberry Pi can handle.

A voltage divider consists of two resistors (R1 and R2)hc-sr04-tut-1 in series connected to an input voltage (Vin), which needs to be reduced to our output voltage (Vout). In our circuit, Vin will be ECHO, which needs to be decreased from 5V to our Vout of 3.3V.

 

 

 

 

 

  • Hardware part

There are four pins on the HC-SR04 sensor. The pin labelled VCC requires connecting to a 5V pin, the pin labelled “Gnd” requires connecting to a ground pin, and the pins “Trig” and “Echo” need to be each wired to a unique GPIO pin on the Raspberry Pi.

I am going to use the following pins:

VCC -> 2nd pin
TRIG-> 12th pin
ECHO-> 16th pin
GND -> 6th pin

rpi2hcsr04_bb.png
Here is a simple demonstration on how to wire up your Raspberry Pi 2 with HC-Sr04 sensor.

 

I think it is pretty straight-forward (and I am not a hardware guy 🙂 ) so I am gonna leave it as it is, hope you don’t mind.

 

  • Software part

Here is the easy, yet cool part. Note that, you can use the exactly same code for every board running Windows 10. ( Raspberry Pi 2, MinnowBoard Max, DragonBoard410c)

Developing for Windows 10 on these boards gives us a bunch of options. From UWP App (which I am going to build today) to Express Node.js Web App.

The first thing you have to do is to setup your environment. I am not going to dive into this as there is a detailed tutorial on Microsoft IoT GitHub page, HERE.

Assuming that you have already set up your environment, it’s time to start coding!

First, let’s create a new Blank Universal Windows App by going to

File -> New -> Project -> Installed -> Visual C# -> Windows -> Universal -> Blank App (Universal Windows)

You can name it as you like, I named it IoTUltrasonicApp.1.PNG

 

Now you have to add a reference to Windows IoT Extensions for the UWP in your newly created project. Right click on the References section and click Add Reference… Then you will find it under

Universal Windows -> Extensions

Click on Windows IoT Extensions for the UWP tick it and press OK.

Capture1.PNG

 

Time to add two TextBlocks to our MainPage.xaml file. The one of them will be used to present the calculated distance and the other to present the status of the our GPIO Controller / Pins. I just drag ‘n’ drop them somewhere on my page.

2.PNG

Here is the code of my Grid for a quick copy / paste.


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="gpioStatus" FontSize="20" HorizontalAlignment="Left" Margin="10,531,0,0" TextWrapping="Wrap" Text="Status" VerticalAlignment="Top"/>
<TextBlock x:Name="distancetb" FontSize="20" HorizontalAlignment="Left" Margin="453,299,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top"/>
</Grid>

Now, let’s open MainPage.xaml.cs.

 

Use the following namespaces


using Windows.Devices.Gpio;
using System.Threading.Tasks;
using System.Diagnostics;

 

Let’s declare our variables and constraints. I am gonna explain them all soon.


private const int ECHO_PIN = 23;
private const int TRIGGER_PIN = 18;
private GpioPin pinEcho;
private GpioPin pinTrigger;
private DispatcherTimer timer;
private Stopwatch sw;

The 2 int constraints are the number of the pins (something like ID) I use for the echo and the trigger I/O of my ultrasonic sensor. You can find them in the raspberry image above. (GPIO X, the X is the number we need.)

The GpioPin objects represents the pins we will use to write to and read from the sensors.

Also, we are going to compute the distance frequently so we need a timer. For that purpose I am gonna use a DispatherTimer.

The Stopwatch is going to be used to calculate the distance.

 


public MainPage()
{
this.InitializeComponent();

InitGPIO();

timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(400);
timer.Tick += Timer_Tick;
if (pinEcho != null && pinTrigger != null)
{
timer.Start();
}

}

We first initialize our GPIO, and if the initialization is successful, we start our timer at 400ms interval.

 

private async void InitGPIO()
{
var gpio = GpioController.GetDefault();
if (gpio == null)
{
pinEcho = null;
pinTrigger = null;
gpioStatus.Text = "There is no GPIO controller on this device.";
return;
}

pinEcho = gpio.OpenPin(ECHO_PIN);
pinTrigger = gpio.OpenPin(TRIGGER_PIN);

pinTrigger.SetDriveMode(GpioPinDriveMode.Output);
pinEcho.SetDriveMode(GpioPinDriveMode.Input);
gpioStatus.Text = "GPIO controller and pins initialized successfully.";

pinTrigger.Write(GpioPinValue.Low);

await Task.Delay(100);
}

Here, we get the default GpioController and check if it null. If it is, something is wrong with our board and we can’t communicate with it’s GpioController. If it isn’t, we open the echo and the trigger GPIO in order to use them. We set the DriveMode of the Trigger and Echo pins to Output and Input respectively. That means that we are going to write to the Trigger pin and read from the Echo one. Then, we just turn Trigger off by writing GpioPinValue.Low to it and we wait for 100ms.

 

And now the tricky part.

private async void Timer_Tick(object sender, object e)
{
pinTrigger.Write(GpioPinValue.High);
await Task.Delay(10);
pinTrigger.Write(GpioPinValue.Low);
sw.Start();
while (pinEcho.Read() == GpioPinValue.Low)
{

}

while (pinEcho.Read() == GpioPinValue.High)
{
}
sw.Stop();

var elapsed = sw.Elapsed.TotalSeconds;
var distance = elapsed * 34000;

distance /= 2;
distancetb.Text = "Distance: " + distance + " cm";
}

To calculate the distance, some things need to be done in the following order.

  1. Turn the Trigger on to send an ultrasonic wave, wait a bit and turn it off. The ultrasonic wave should hit an object and come back to the sensor.
  2. Start the timer and wait for the ultrasonic wave to come back to the sensor.
  3. Stop the timer when Echo doesn’t have anything more to read.
  4. Multiply the elapsed time with the speed of sound (in cm/s) at sea level.
  5. Divide by 2 because the ultrasonic wave traveled the current distance twice.
  6. Voila, we set the text of our TextBlock to the text we need.

 

Capture.PNG

That’s it!
Now, you can start playing with your board and create amazing IoT and Robotics things.

Don’t forget to comment below.
Here is my project hosted on GitHub.

I will probably write more IoT and Robotics tutorials like this one in my spare time on my blog or on StudentGuru Tutorials.

Till then, happy coding!

PS. Sorry for bad code formatting, it’s WordPress not me!

Thanks for reading!

George