=================
Ultrasonic Sensor
=================
Sensor Overview
---------------
Before we start, just to acknowledge that the basic premise of working with
the Arduino through a serial port then to python came mainly from the
website of `Paul McWhorter `_,
search through the archives to find his lessons, which cover a lot of
different topics through the years.
The sensor is built as a module, called an HC-SR04 in my kit, it has an
ultrasonic transmitter and receiver, a timing oscillator and 3 chips mounted
on the rear. As a module most of the difficult part has been taken care of,
all we need do is concentrate on the distance measuring. One can directly
connect the module using duPont connectors (male-female) or put the pins
carefully in the small breadboard then connect with normal wires to the
Arduino.
To make a meaningful test we need to know the distance based on the time
delay between the transmitter and receiver. As ultrasonic is really just
sound first find out the speed of sound in air.
Speed of sound 304m/s (776.5 mph)
The ping time given by the sensor is in microseconds, therefore we can
calculate the distance, remembering that we are measuring a round trip, so
divide by 2::
distance = time * speed of sound / 2
cm = t / 1000000 * 331.3 * 100000 / 2
in = t / 1000000 * 741.1 * 63360 / 2
Run the Arduino Sketch
----------------------
Using the example supplied by Elgoo first install the library ``
then you will be able to get the distance in cm directly without having to
do any calculation.
.. topic:: Installing a Library and using it
The Arduino IDE has a simple way to install libraries, place the CD-Rom
in your computer, open the Arduino IDE, then click on /, this will produce a pop-up window, enter the name of your
library, NewPing, in the search entry position, or scroll down, then
click on the `install` button.
It can then be used as it is, since there should be a folder under your
`libraries` directory called `NewPing`.
.. figure:: ../figures/newping.png
:width: 388
:height: 218
:alt: Finding an Arduino Library
:align: center
Often the library will have examples that enlarge the scope of the
simple sketch generally used. These can be found by a directory
search, or using the IDE / then picking the relevant
heading, in our case under `Examples from Custom Libraries`
and we have a choice of 6 Examples.
Starting with the basic sketch all we do is import the relevant library,
define which pins are being used for the trigger and echo, then connect to
the library function with its input parameters. In the setup make the serial
connections, then in the loop show the output for the serial monitor::
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------
#include
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
void setup() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}
void loop() {
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
Serial.print("Ping: ");
Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
}
.. note:: The Starter kit stated that library should be imported,
whilst the Sensor Kit called for . NewPing is newer and has
more example files. Instead of the files having `.ino` they end in
`.pde`, they will load and work in the Arduino IDE without trouble.
It can be a bit perplexing when starting that there are different libraries
- even from the same supplier. However if in doubt one can always search
for different Arduino sketches on the internet. Using NewPing as an example
there are a couple of folders, ``examples`` and ``src``, together with
``keywords.txt``, ``library.properties`` and a ``readme``. Keywords highlight
the relevant words in the sketch. Lookup `Tim Eckel's documentation `_
for a complete explanation. What this does show is that a decent library can
transform a product from a toy into something useful.
The wiring is simple so once it has been wired up test some of his examples.
If you have more than one sensor then he has a 15 (with caveats) sensor
example. Try out his median example, which should be more accurate than the
basic example above. Instead of wiring with 4 connections he also has an
example using 3 connections. The theory here is that the common wire
has transmit and echo signals at different times. Just be careful about
setting the baud rate, its 115200, 12 x 9600, so he's not dawdling::
// a special found in his library
#define PING_PIN 12 // Arduino pin tied to both trigger and echo pins on the ultrasonic sensor.
If you change the wiring so that only one wire comes from the trigger pin
and echo pin to one connection at the Arduino (pin 12), then change the
sketch by deleting the 2 pin lines and substitute the above line it should
work as before.
One other point to consider, what happens when you are not working at 0°C,
then the speed in air will be different, (Imperial units use 20°C, 68°F as
the standard temperature). A better approximation for the speed of sound is
temperature and % humidity dependant, and also to some extent pressure and
CO2 content::
Speed of sound m/s = 331.4 + (0.606 * Temp) + (0.0124 * Humidity)
You should notice that temperature change has a greater effect than humidity
change. However it is an approximation that works well enough for the
equipment we have to hand. Probably we'll find larger errors in the actual
measurement, after all we are dependant on two independant oscillators being
accurate enough over measurements in microseconds. The temperature
sensor should be reasonably accurate, the combined temperature and humidity
sensor DHT11 is only ±2.0°C accurate, whereas a temperature sensor DS18B20
is accurate to ±0.5°C. The humidity is only accurate to ±5% in the combined
sensor.
Use the median example as our base method to build on.
.. container:: toggle
.. container:: header
*Show/Hide Code* NewPingTimerMedian.ino
.. literalinclude:: ../sketches/NewPingTimerMedian/NewPingTimerMedian.ino
.. sidebar:: Inaccurate Readings
First check connections, then make sure that no fluff lies on the detector
and receiver and baud rate is set correctly then maybe calibration will
help. `Arduino HC-SR04 library `_
This is a tad more complex than the original, and should justify the
extra code. As the output is a straight linear measure it should be possible
to check the overall accuraccy of the system. Making no temperature or
humidity allowances the sketch showed 32cm at 30cm an accuracy within 10%,
quite good. For normal working this is good enough. Using a second module I
got much the same results - a pleasant surprise.
Visual Display HC-SR04
======================
Keep all the phsical connections in place, all we are doing is working with
graphical software. If you wish you can compare the ease of working between
python and processing. Any testing can be made in the following manner:-
* Install Arduino software (sketch)
* Verify, before connecting Arduino to the serial port
* Compile the software
* Check that it operates on serial monitor
* Switch off monitor (most important)
* Install graphical software
* With the Arduino connected to the serial port run the graphical software
Try to use the same Arduino setup, with electronic components and compiled
program when testing the graphical software. If necessary disconnect the
Arduino, then reconnect it to the serial port, no further compiling is
necessary.
Simple Rod
----------
.. figure:: ../figures/rod.png
:width: 493
:height: 229
:alt: vpython simple rod
:align: center
Adjustable rod according to distance from object
One can build up on this simple drawing to make a more exciting images, but
the principle remains largely the same. We start with our imports, then
define any custom functions, specify our serial connection. make our image.
That completes the static part, now we have the loop setting the vpython
rate, if the serial is available read in the data, the rod length now changes
according to the distance of the object from the ultrasonic sensor.
The rod is a simple cylinder, with a default length, which is later changed
in proportion to the distance from the object. The ``vector`` property shows
how the rod is orientated relative to the view axes, picking up on the end
of the rod, (-3,0,0) pushes the rod along the x-axis so that the rod's default
centre should lie on the origin, (the other two vector properties - y and
z axes - are 0).
.. container:: toggle
.. container:: header
*Show/Hide Code* ultraRod1.py
.. literalinclude:: ../scripts/ultraRod1.py
Rod, Target and Text
--------------------
.. figure:: ../figures/ultratarget.png
:width: 481
:height: 214
:alt: vpython target with distance
:align: center
Adjustable rod, target and text change with distance from object
We now include some information on the distance from the target, and a
simple representation of the target. For test purposes we print the distance
as well as displaying it on screen. Both the rod length and target position
change with the target distance.
.. container:: toggle
.. container:: header
*Show/Hide Code* ultraLabel2.py
.. literalinclude:: ../scripts/ultraRodLabel2.py
Sensor in a Scene
-----------------
.. figure:: ../figures/ultraview1.png
:width: 358
:height: 100
:alt: vpython scene sensor and distance
:align: center
Adjustable scene target and text, change with distance from object
Change the background colour, add a representation of the ultrasonic sensor.
To make it easier to set up the rod and its adjustment place a red ball at
the origin.
Paul McWhorter's original scripts worked at 9600 baud, remember we are using
115200 baud, also he had an earlier version of vpython, so change the ``import
from visual`` to ``vpython`` and add ``vector`` or ``vec`` to data input::
label(pos=(0,5,0)
becomes::
label(pos=vector(0,5,0)
If you have a colour detector module you can add it to change the colour of
the target according to coloured paper used as the target.
.. figure:: ../figures/ultraview2.png
:width: 755
:height: 483
:alt: vpython scene sensor and distance no autoscaling
:align: center
Using autoscale=false and right click on mouse
.. container:: toggle
.. container:: header
*Show/Hide Code* ultraScene3.py
.. literalinclude:: ../scripts/ultraRodScene3.py
:emphasize-lines: 17