WPF Sonar application using Arduino and PING))) sensor

by Ryan Lane on February 8, 2010

I’ve been playing around with the Arduino more and more lately and really wanted to find a way to make it work with my other world of C# and WPF.   The idea was to make an application that changes the screen based on how far away the user is.  The only way that I could easily think about doing it was to use an Arduino as a serial device to help communicate with the sonar sensor. 

I picked up the PING))) from Parallax to use as the sensor from the Makershed and searched on the Arduino site for some samples and quickly found two great resources first is was this Ultrasound Sensor Tutorial and second was this fantastic Ping Library for Arduino by Caleb Zulawski, which made it even easier to work with.

Here’s a top view of the setup mounted on a Wooduino

Here’s the sketch code for the Arduino:

/*  This code initializes a Ping))) sensor on pin 13 and
outputs the information over a serial connection */
#include <Ping.h>

Ping ping = Ping(13,0,0);

void setup(){
  Serial.begin(9600);
}

void loop(){
  ping.fire();
  Serial.print(ping.microseconds());
  Serial.print(",");
  Serial.print(ping.inches());
  Serial.print(",");
  Serial.print(ping.centimeters());
  Serial.println();
  delay(1000);
}

This sketch sends out microseconds, inches and centimeters.  I have them sent as one comma delimited line per sonar pulse.  The code on the WPF side reads in that line and converts it as needed.

Here’s the XAML for the WPF app:

<Window x:Class="PingArduino.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded" Unloaded="Window_Unloaded">
    <Grid>
        <StackPanel VerticalAlignment="Center">
            <TextBlock x:Name="tbJustData" HorizontalAlignment="Center" FontFamily="Segoe UI">0</TextBlock>
            <TextBlock x:Name="tbPingMessage" TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Segoe UI" FontSize="30pt">Waiting...</TextBlock>
        </StackPanel>
    </Grid>
</Window>

It’s a very simple StackPanel with two TextBlocks. 

Here we can walk through the code behind:

using System.IO.Ports;
using System.Windows.Threading;

I’m using System.IO.Ports to easily access the Arduino over the serial port.

It’s fairly simple to create the serial port in the code and then interact with a device over the serial port.  I have a couple of Arduino devices and each time I plug one in Windows defaults by adding it to a new COM port.  In the example below I’m on COM9 you’re mileage my vary here.  You can see which port your Arduino is using from the Sketch editor under Tools > Serial Port.

//create a Serial Port object
SerialPort sp = new SerialPort("COM9", 9600);

//Create a DispatcherTimer
DispatcherTimer timer = new DispatcherTimer();

string pingStatus;
public Window1()
{
    InitializeComponent();

    //enables the Data Terminal Ready (DTR) signal during serial communication
    sp.DtrEnable = true;
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    //Open Serial Port
    sp.Open();

    //give it 2 seconds for the sketch to start up
    System.Threading.Thread.Sleep(2000);

    //Setup interval of DispatcherTimer
    timer.Interval = TimeSpan.FromMilliseconds(500);

     //configure and start the thread
     timer.Tick += new EventHandler(timer_Tick);
     timer.Start();
}

void timer_Tick(object sender, EventArgs e)
{
    //throw new NotImplementedException();
    string pingData = sp.ReadLine();
    string[] datapoints = pingData.Split(',');
    pingStatus = datapoints[1];
    double pingInches = Convert.ToDouble(pingStatus);

    tbJustData.Text = pingStatus + " inches away";

    if (pingInches > 50)
    {
        tbPingMessage.Text = "Hey I'm over here!";
    }
    else if (pingInches <= 50 && pingInches > 30)
    {
        tbPingMessage.Text = "Hello there how can I help you?";
    }
    else if (pingInches <= 30 && pingInches > 5)
    {
        tbPingMessage.Text = "Let me show you a few things";
    }
    else if (pingInches <= 5 && pingInches > 2)
    {
        tbPingMessage.Text = "I'm getting a little uncomfortable here.";
    }
    else if (pingInches <= 2 && pingInches > 0)
    {
        tbPingMessage.Text = "Stop touching me!";
    }
    else
    {
        tbPingMessage.Text = "You are " + pingInches + "inches away" ;
    }
}

Here’s a little video of everything in action:

Share and Enjoy:
  • Digg
  • Twitter
  • FriendFeed
  • Posterous
  • del.icio.us
  • TwitThis
  • Live
  • Mixx
  • Google Bookmarks
  • Yahoo! Bookmarks
  • LinkedIn
  • email

Related posts:

  1. SEO for Silverlight
  2. Simple CSS based wireframe annotation
  3. Silverlight 2.0 Twitter Widget
  4. Silverlight 2.0 Flickr WordPress Widget
  5. David Kelley Demos the Touch Tag

{ 1 comment… read it below or add one }

Caleb Zulawski July 30, 2010 at 3:48 pm

Great to see someone’s using my library!

Leave a Comment

{ 2 trackbacks }

Previous post:

Next post: