This post marks the beginning of "Out of Boredom" series. It will be about creating stuff with my recently purchased Arduino Uno. Let's have a break from chores of professional programming and create something just for fun :)
My first Arduino based project is Sonar. It utilizes ultrasonic range sensor, servo, SignalR and canvas to create sonar image:
I am splitting the description into two posts. First post will focus on hardware components and Arduino sketch and the second will be about .NET and JavaScript applications. You can get complete code in this GitHub repository. You can also click here to see short video of the whole thing working.
Here are hardware elements used:
Element | Role |
Arduino Uno R3 | Handling HC-SR04, controlling servo and communicating with PC |
HC-SR04 Ultrasonic Ranging Module | Measuring time it takes sound to bounce back from objects |
9g Tower Pro Micro Servo | Moving sensor to get 180 degree view |
Red LED | Signalling ready state |
330 Ohm resistor | Limiting current going through diode |
Breadboard and few jumper wires | Connecting components without soldering |
That's it, just a few cheap components! Virtually no electronics skills are required to complete this project. I assume, however, that you have basic Arduino knowledge and you know a bit about C# and JavaScript.
Here is the software stack:
Element | Role |
Arduino sketch (firmware) | Measuring distance, moving servo and sending data to PC over serial port |
.NET/C# 4.5 console application with SignalR library | Receiving data from Arduino using SerialPort class and broadcasting angle and distance information to clients |
HTML5 page with JavaScript SignalR library | Receives data from server and creates sonar image using canvas element |
Above might sound a bit overwhelming but I assure you that the code is short and not that complicated.
The basic idea goes like this: HC-SR04 sensor measures time it takes an ultrasonic signal to bounce from obstacles and this gives as a chance to calculate distance to these obstacles. Position of the sensor is controlled by servo. Information about distance to objects and direction in which the sensor is pointing is sent to PC that is running console application with SignalR sever. PC receives the data and sends it to JavaScript clients that are capable of presenting sonar data in nice visual way using HTML5 canvas element...
More details!
The main component (except for the Arduino of course) is the HC-SR04 Ultrasonic Ranging Module. This sensor works by sending sound signal at 40 kHz (so above human perception limits) and detecting the echo. That's why this project is called "Sonar" and not "Radar" - it uses sound waves (not radio waves) do detect objects. The sensor should work in ranges from 2cm up to 400cm at accuracy of few millimetres. But keep in mind that the shape an material of objects might affect performance. I tested it at maximum distance of about 2 meters and was happy with the results. You can use this sensor without any libraries. That requires doing things like putting HIGH
value on Trig
pin for 10uS to emit ultrasonic signal, measuring duration of HIGH
pulse on Echo
pin and calculating distance knowing that speed of sound in the air is around 340m/s... But there's a better way: you can use NewPing
lib (link) to get the distance. If you don't know how to include new library in your Arduino sketch click here.
The second important component is the servo. HC-SR04 sensor has measuring angle of about 15 degrees. But if we move it around by attaching it to servo's arm we can easily get 180 degree view. I won't get into details on how servo works and how it is controlled in this post. I plan to make another post about shooting paintball marker with Arduino+laptop and I will describe it then. For now all you need to know is that Arduino comes with Servolibrary which makes it very easy to move servo into desired position (angle)... I utilized 9g Tower Pro Micro Servo in this project. It's powerful enough to move the sensor yet can be powered directly from Arduino's +5V pin.
Last physical components are LED used to signal the ready state (that is when setup
function had completed) with its accompanying resistor. Making a diode shine is electronics equivalent of "Hello World!" so I'm sure you know how to handle LED. Even if not, you can always use the tiny built-in LED connected to pin 13 of Arduino Uno...
This diagram shows how hardware components should be connected:
Here's the whole code that should be uploaded to Arduino:
#include <NewPing.h>
#include <Servo.h>
const byte setupReadyLedPin = 8;
const byte triggerPin = 10;
const byte echoPin = 11;
const byte servoPin = 12;
const byte maxDistanceInCm = 100;
byte angle;
byte angleStep;
byte angleStepDelayInMs = 50;
NewPing sonar(triggerPin, echoPin, maxDistanceInCm);
Servo servo;
void setup() {
pinMode(setupReadyLedPin, OUTPUT);
angle = 0;
angleStep = 1;
servo.attach(servoPin);
servo.write(angle);
Serial.begin(9600);
digitalWrite(setupReadyLedPin, HIGH);
}
void loop() {
alterServoMoveDirection();
measureAndSendDistance();
angle += angleStep;
servo.write(angle);
delay(angleStepDelayInMs);
}
void alterServoMoveDirection() {
if (angle == 180) {
angleStep = -1;
} else if (angle == 0) {
angleStep = 1;
}
}
void measureAndSendDistance() {
byte distanceInCm = sonar.ping_cm();
byte sonarData[] = {255, angle, distanceInCm};
Serial.write(sonarData, 3);
}
As stated before, I assume that you know something about Arduino programming and things like const
, pinMode
, delay
, setup
and loop
don't require explanation...
First lines which should capture your attention are:
#include <NewPing.h>
#include <Servo.h>
NewPing sonar(triggerPin, echoPin, maxDistanceInCm);
Servo servo;
Above lines let us use NewPing
and Servo
classes to measure distance and move the sensor. Notice also that setup
function has such lines:
servo.attach(servoPin);
servo.write(angle);
These exist to set the pin used to control the servo and to move the servo into initial position at 0 degrees.
This line:
Serial.begin(9600);
allowes Arduino to talk to PC (in my case a laptop with Windows 7) over serial port. That's right, even though Arduino Uno is connected to computer via USB cable it actually uses COM port to communicate. On my machine its called "COM3" (screen shown below comes from Device Manager - my Windows is in Polish):
The value passed to begin method determinates baud rate (communication speed). It's important to have the same value used in software that communicats with Arduino.
The loop
function moves servo and invokes measureAndSendDistance
function which uses NewPing
to calculate distance and Serial
to send data to PC. This is how easy it is to get distance in cm thanks to NewPing
lib:
byte distanceInCm = sonar.ping_cm()
If measured distance exceeds the maximum value specified as last parameter to NewPing
constructor the value of 0 is returned. Check NewPing
docs to see other useful functions of this lib.
And finally this is how Arduino sends data to PC:
byte sonarData[] = {255, angle, distanceInCm};
Serial.write(sonarData, 3);
The first array element (255
) is used as a marker/separator to easily distinguish pairs of angle-distance values. Its role will become clear in the second post which will describe SignalR server and clients... I assume that maxDistanceInCm
const will never be set above 200 so distanceInCm
will never have value of 255. 255 will never be sent as an angle
too because our servo moves in 0..180 degrees range. Sure it might be a good idea to create const and avoid 255 magic number. Some validation would be useful too... But screw it, this project is just for fun! :)
Ok, you survived to the end of the first post about Arduino/.NET/JS/HTML sonar. The second post should be ready in about a week.
Update 2014-09-29: Here's the second part: http://www.codeproject.com/Articles/823304/OoB-Sonar-with-Arduino-Csharp-JavaScript-and-HTM