Haptic Feedback Example Applications: Robot Proximity Sensor
These examples are provided as guides to using the Haptic Feedback Evaluation Kit for potential real world applications. As discussed at the end, these are not full real world solutions, but a useful starting step!
They outline the approach taken to solve the problem. They are not a guide to programming on the Arduino, therefore some prior knowledge of the Arduino language will be useful. Try the Arduino Learning or Reference pages for help with specific functions.
Many modern cars are now fitted with parking sensors, an audible alert that beeps when the car is reversing. As the car approaches an object, such as a wall, another car, or bollard, the beeping becomes more frequent.
Most users are familiar with this type of application and understand the warning can be augmented (or replaced) with haptic feedback, which is why we chose as an example in our Intro Mode tutorials.
However it’s not just cars that can benefit from it. In fact any application that involves remotely controlling the movement of a device that can be damaged through collision can be improved by a haptic warning system.
In this example we will imagine a remote controlled car robot. These are often used in environments where it is not safe for humans, perhaps with a camera mounted to allow for situation assessment, or with other types of sensors (like gas) to detect danger.
Definition And Scope
To provide haptic feedback to an operator depending on the proximity of an object to the robot.
- Reliably measure distance between robot and surrounding objects
- Warn user as distance to object decreases
- Determine at which distances effect will become more urgent
- 1 x Haptic Feedback Evaluation Kit
Our chosen sensor (below) requires access to two digital pins, as we’re not using the OLED screen there’s plenty to choose from. To connect to these pins you can either solder wires to the top of the Haptic Shield (not recommended) or remove the shield and use simple jumpers to the required pins.
- 1 x Ultrasonic Ranging Module (HC-SR04)
An inexpensive and widely available unit. Needs a 5V power connection and two digital pins, one triggers the ultrasonic signal (Trig) and the response is measured on the Echo pin. We calculate the time between the Trig and Echo signals to obtain the distance of objects in front of the sensor.
- 1 x Breadboard
Always good to have around, in this case we need it to give both the Haptic Shield and the HC-SR04 access to the 5V pin on the Arduino.
This software is built from the Development Mode. You can download the code used in this example in the top right of this page.
Note: Before starting and putting effort into making the required wiring, we will be playing haptic effects to the user to warn them of the proximity of objects. If you want to experience specific effects and compare them to others, the easiest way to do this is to use the Engineering Mode. You may wish to select what effect would be a good warning before disconnecting the Haptic Shield.
Let’s start with defining at which distances we want to warn the user. This would be dependant upon the speed and size, a fast moving object with a lot of momentum will need proximity warnings at an earlier stage than light slow moving objects.
In addition to changing the effect, we can increase the frequency of haptic effects to convey a greater sense of urgency. This is the common approach for car parking sensors, the beeps become more frequent until a constant tone signals imminent impact.
For desktop development we’ve decided on escalating the warning to the user when they are within the following distances:
|Distance||Effect ID||Effect Frequency|
|Over 30 cm||51 - Buzz 5 20%||Every 10th measure|
|Under 30 cm||50 - Buzz 4 40%||Every 10th measure|
|Under 20 cm||49 - Buzz 3 60%||Every 5th measure|
|Under 15 cm||48 - Buzz 2 80%||Every 5th measure|
|Under 10 cm||47 - Buzz 1 100%||Every 3nd measure|
|Under 5 cm||15 - 750ms Alert||Every 2nd measure|
There are three steps to our haptic system:
- Measure the distance from ultrasonic sensor
- Calculate the distance group so we know which effect to play
- Play the haptic effect at the prescribed frequency
It is best to remove the Haptic Shield from the Arduino and connect to the pins using jumper cables.
Use the Pin Mapping resource to easily see which pins are required. For this example we’ll need connections for the DRV2605 (red) and the Haptic Grip (blue).
We connected pins 3V3, GND, A0, A1, A4, A5, 4, 6, 7, and 9 straight from the Arduino to the Haptic Shield. We connected the other GND and 5V to the breadboard, as the ultrasonic sensor also needs power. Note the DRV2605 also relies on the 5V connection so be sure to connect the Haptic Shield 5V pin to the breadboard too.
Finally the ultrasonic sensor has one digital input (Trig) and one digital output (Echo), which we have connected to digital pins 12 and 11 respectively. Without the OLED screen, there are plenty of others to use - you can use any as long as you define which ones in the Arduino code.
The Development Mode handles all the initialisation for you to start using the Haptic Feedback Evaluation Kit, so you can just concentrate on the application particulars.
There are some of the default setup lines we have to change and, in a similar fashion, there may be functionality in the code that you are not using - so consider streamlining it at a later date.
Lines 41 - 44 include our global variables that support the functions below, we explain these in turn but the maximumRange and minimumRange values are to let us know when we get an erroneous reading from the ultrasonic sensor. If operating over a larger range, the maximumRange value can be increased (up to the maximum of the sensor).
We will highlight that we have changed line 57 to use the 308-102 ERM:
motor.selectMotor( 2 ); Remember the DRV2605 needs to be calibrated! Line 58 is important!
We also need to set the digital pins that are connected to Echo and Trig. In line 53 we can see that the pin setup has been included in it’s own separate function, this starts at line 75.
Two lines (81 and 82) show that we have set the
TRIGPIN to be an output (meaning we write to it) and the
ECHOPIN to be an input (meaning we read from it). These names have been defined using #define, for the sake of neatness this is included with all the other pre-existing
#defines in the defs.h file (see lines 43 and 44).
After checking the setup, we can take a look at the 4 functions in
This function handles the operation of the ultrasonic sensor. It works by writing a high value to the Trig pin causing it to project an ultrasonic wave (8 x 40 kHz waves). The Trig pin is then turned low and the function
pulseIn(); records how many microseconds it takes for the Echo pin to stop receiving the signals.
This is then used to calculate the distance to an object, where the variable distance is updated.
This is a very simple function that’s used for debugging more than anything functional. It simply prints the value of
distance to the serial monitor (open with ctrl + shift + M in Arduino IDE).
If you want, you can delete this from the main
loop(); but it is recommended to help understand how the program is working. It’s also useful for catching errors.
Here we set the variable
distancegroup depending on the value of the variable
distance. This will make it easier for us to decide what effect should be played and how often it should be played.
For ease, we’ve used a series of if statements. We only have 6 groupings so it is fairly easy to understand, but if you hand many more groups or a more complicated feedback system (such as one with several input variables) it could quickly become messy. Also, what if we decided to change the distances for each group? How easy would it be?
Is there a neater way to program this?
We’ve used a
switch statement to run different sections of code depending on the
distancegroup variable. This enables us to specify a different haptic effect for each case and change the frequency of plays by keeping track of the variable
measurecount. Each case is structured in the same way:
- Check to see if we need to play a haptic effect by checking
measurecountis below the frequency value for that distance group (refer to the Effect Frequency column in table at the start of the guide)
- If true, increase
measurecountby 1 and exit
- If false, play the specified haptic effect using
The function motor
.playFullHaptic(); relies on the files provided with the Haptic Feedback Evaluation Kit Development Mode. The first argument specifies which library of the DRV2605 to use, libraries 1 - 5 are for ERMs, and the second is the Effect ID. Use the Haptic Effect ID table to see all the effects available.
Final Steps and Tips
If you’ve downloaded the code and not made any changes (using the same pin connectors for the digital inputs) you should be able to load the code into the kit, immediately feeling the vibrations on the grip. Use your hand or another object to change the distance to the sensor and notice the different effects and frequency of playback.
Also built into the code (you may have noticed) is a load of text sent up the serial port using
Serial.print();. Open the serial monitor in the Arduino IDE (ctrl + shift + M) to see your distance printed on the scrolling screen. The effect being played is also printed to make it easier for debugging.
How does this relate to the ‘real world’? Whilst this demonstrates one approach to the application, it obviously has several limitations that could easily be improved on.
For further revisions, consider the following points and how you might go about solving them:
- Distance to the sensor
Here we mean distance between the sensor and the microcontroller. Consider a car parking sensor, it is mounted in the rear bumper of the car. What if the gap between your sensor and microcontroller is this large, or further?
What does the distance mean for time sensitive circuits? Are you better to measure the distance locally and transmit the digital value? If the robot is controlled remotely, you may need to send the data wirelessly to the user interface.
- Range of sensor
Our particular model is rated for use 2 cm - 450 cm, certainly more than enough for testing in the lab. As mentioned in the article, larger and faster vehicles will need better range than small slow ones to compensate for their increased momentum.
However if dealing with very accurate positioning, perhaps improved resolution is the key. It is possible to use light and laser based sensors for applications requiring extreme precision.
- Blind spots and Crosstalk
Does your sensor have a very narrow line of site? What about using multiple sensors to get a better understanding of the environment, is it possible that one sensor could pick up the signals from a neighbouring sensor?