Background and Tutorial

This is a tutorial that instructs the user how to create a device similar to the sonic sensor distance measuring device we use in this design project with the use of Arduino, ultrasonic distance sensor, and basic circuity.



The concept of this design is to input data based on distance into a system and return to the user a variant haptic response. To accomplish this task first it is necessary to have the capability of surveying the surrounding environment and process that data. To process the data and communicate with multiple sensors and haptic driver motors an Arduino Mega 2560 microcontroller was utilized, as it provides adequate processing speed and ample digital I/O as well as I2C capability. Four concentrically placed ultrasonic distance sensors were wired and sewn to the exterior perimeter of the hat, while a fifth sensor was mounted to the brim. A minimal distance of 30ᵒ is necessary to avoid unwanted signal interference between the sensors which may distort the data collection process. The HC-SR04 model distance sensors used rely on a four-pin wiring configurations which includes a 5V VIN pin, a ground pin, a digital I/O TRIG pin, and a digital I/O ECHO pin. The TRIG pin is used to trigger the sensor, while the ECHO pin is used to communicate the data back to the microcontroller. To control the sensors Arduino has a template script “NewPing” which can be modified to accommodate this system (the source code for this system can be found on S.A.V.E.’s blog site). The ultrasonic sensor then returns a time difference in microsecond (µs). The relation between distance and time difference is presented in the following equation:

d=v*t = 343/10^6*t

The VIN and ground pins of the front three sensors are tied into one another as are the rear two sensors before returning to the microcontroller.

To give the user the ability to turn sensors on and off when desired four push button power switch breakout boards were supplied. The breakout board design is convenient as no coding is required to control them. The breakout boards were soldered inline on to a proto-board with the main 5V power and ground wires from the microcontroller wired to the first switch which turns off all the systems sensors. The ground and power out lines run to the main power bus of the proto-board which provides power to all other switches. The second and third switches are wired to the front and rear hat sensors.    The fourth switch powers a sixth ultrasonic sensor with a similar wiring configuration which is housed in the front of a handheld enclosure. This sensor is intended to give the user a more precise and controlled view of the surroundings. To mount this sensor two 17mm (± 1.5mm) holes were drilled 25mm (± 0.75mm) on center through the front of the enclosure to accommodate the cone housings of the sensor and a two-part epoxy was used to secure the sensor in place.

In addition to the switches and ultrasonic sensor the enclosure also houses all the systems electrical components attributed to processing and data output. To provide haptic feedback to the user haptic driver motors must be used to initialize the signal. The DRV-2605L breakout board allows for the use of 116 preset waveform patterns to be sent to a LRM or ERM (vibration motor). The 5V driver motor is controlled by I2C, SDA and SCL input. Where SDA provides data transmission and SCL provides time pulses. I2C is very convenient for controlling multiple devices however each device must have a unique I2C address. To provide haptic feedback to each sensor six haptic drivers are necessary, each DRV-2605L is manufactured with the address 0x05 which is not able to be modified. Since the Arduino microcontroller only provides one set I2C outputs a multiplexer must be used to assign each device a unique address. Again, to simplify the process a manufactured break out was used, the SDA, and SCL outputs from the microcontroller along with ground and 5V are wire directly to the inputs of the multiplexer. The TCA9543A multiplexer used provides eight outputs with I2C addresses ranging from 0x71 to 0x78. Each address has its own SDA and SCL outputs which are ran to the DRV-2605L driver motors. The outputs for the driver motors are simply 5V and ground. Except for one line used to control haptic feedback to the handheld enclosure; the outputs are run from the drivers back towards the hat. Each sensor has an allocated LRM mini disc which is hot glued into the sweatband of the hat.

For the LRM’s to provide distinguishable feedback the user can logically interpret the motors must have a degree of variance. The six DRV-2605L’s outputs are controlled by using library Adafruit_DRV2605.h.  In which effect #14 is used to set the feedback from the motors. This was chosen because it produces strong buzz over a short period which allows for distinct feedback to the user. The intensity of the motors is controlled by changing the delay time (td) between each impulse this time is proportional to the distance. Through testing it was determined that the best delay (Td) is represented by the following equation:  

Td = 64.746 ln⁡(Distance) - 113.91


The following table shows some sample values of the delay time (td) correspond with distance (d).  To enable real-time feedback to the user the above equation is applied within fractions of a second within the prototype's Arduino to relay information to nearly instantaneously.   




Drexel University Hat: The hat is the wearable structure which houses five ultrasonic sensors and five vibrating mini disc motors. The sensors are sewn into pockets placed concentrically around the outer base of the hat with the front-most sensor mounted to the brim of the hat. The vibration motors are sewn into the inner channel respective in location to the sensor in which it is controlled. Power and data wires will leave the top rear of the prototype hat and travel to the prototype enclosure; in future development, the hat would most likely work via Bluetooth technology with an isolated power source. 




Prototype Enclosure: A mid-sized, handheld plastic enclosure which will house all the circuitry and power supply. The enclosure features four push button momentary switches that control various power features. In addition, this remote will also house a sixth ultrasonic sensor and vibration motor which grants the user a more acute depth of perception and freedom of choice as to the vector of ultrasonic feedback.

Perma Proto-Board: A permanent solderable bread board used to secure electrical components. The advantage of using this model compared to other proto-boards is the availability of power rails located on either side of the bread board.

Arduino AT Mega 2560: This component is the powerhouse of our design. The Mega 2560 is a 5V, 8-Bit, 16 MHz open source microcontroller. It boasts 54 digital input/output pins as well as 16 analog input/outputs which provide S.A.V.E. with all its necessary processing demands. Because it is an open source microcontroller it can be programmed to perform various commands with minimal effort.


Power Supply:

HC-SR04: The HC-SR04 is an ultrasonic ranging module which emits high frequency pulses. As these pulses contact objects then are reflected towards and received by the module. Utilizing the Arduino Library “New Ping” code the HC-SR04 can calculate distance based on the time the sound wave traveled relative to its speed. The ultrasonic sensor has a working range of 2cm – 400cm and accuracy of ±3mm.


DRV-2605L and Vibrating Mini Disc Motor: Haptic driver motor, DRV-2605L, is preprogrammed with over 100 effects that can be controlled via the I2C ports on the Mega-2560. Standard control of vibration motors is normally achieved by analog control of power to and from the vibration motor. The DRV-2605L allows for a greater variance of control. By utilizing preset functions S.A.V.E.’s operator will be able to better interpret the distance of objects by the vibration motors various patterns.


TCA9548A I2C: To fully submerse the user of this technology in his or her environment it is necessary to have multiple ultrasonic sensors triggering multiple haptic drivers simultaneously. Due to the limited number of I2C ports on the Arduino Microcontroller it is necessary to use a multiplexer to control multiple driver motors individually and in unison.


Push Button Power Switch: Four push button power switches are utilized in our design to give the wearer the ability to power multiple functions. One switch will act as the main power switch while the other three will control power to the ultrasonic sensors allowing the user to power the front and rear sensors of the hat individually as well as the handheld unit.


22-AWG Wire Spool Set: 25 foot spools of wire in multiple colors for power, ground, I/O, and I­2C connections from components to the microcontroller.



Current S.A.V.E. Source Code for Arduino Mega2560

#include <NewPing.h>
#include <Wire.h>
#include "Adafruit_DRV2605.h"
  Adafruit_DRV2605 drv;

#define TRIGGER_PIN  22  //  trig pin on the ultrasonic sensor attach to pin22 .
#define ECHO_PIN     23  //  echo pin on the ultrasonic sensor attach to pin23.
#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.

#define TCAADDR 0x70
//----------------------------------------------------------------------------------------------------
void setup(){
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
  drv.begin();
  drv.selectLibrary(1);
  // I2C trigger by sending 'go' command
  // default, internal trigger when sending GO command
  drv.setMode(DRV2605_MODE_INTTRIG);
}

void tcaselect(uint8_t i){
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

int motor(){
  drv.begin();
  drv.setWaveform(0, 12);  // play effect
  drv.setWaveform(1, 0);       // end waveform
  // play the effect!
  drv.go();
  // wait a bit
  return 0;
}

float sensor(int number){
  float distance;
    int TRIG= 22+2*number;
    int ECHO=23+2*number;
    NewPing sonar(TRIG, ECHO, 250);
    unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    delay(10);
    distance = uS / US_ROUNDTRIP_CM;
    Serial.print("Distance: ");//print"Ping: "
    Serial.print(distance); // Convert ping time to distance in cm and print result (0 = outside set distance range)
    Serial.print("cm");//print"cm"
    Serial.print("           ");
    Serial.println(number);
    return distance;
}

//-----------------------------------------------------------------------------------------------------

float dist;
int count = 0;

void loop(){
//Wait 100ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  for (int count = 0; count <= 6; count++){
    dist = sensor(count);
    if (dist < 5 || dist > 100){
        tcaselect(7);
        motor();
    }
    else{
        tcaselect(count);
        motor();
        delay(64.746 * log(dist) - 113.91);
    }
  }

}