Our current code

A project log for Proximity sensor for the blind

Our wrist-mounted proximity sensor can easily be "scanned" in any desired direction to indicate distance to nearest object.

AnaAna 08/02/2021 at 22:460 Comments

We are using the SparkFun VL53L1X Arduino Library by Nathan Seidle of SparkFun ( to get readings from the Time of Flight sensor we used for this project. I won't go through all the code here, but some of the more important parts :)

Some defined values set the min/max frequencies and the distances between which they occur:

// The min/max frequencies
#define FREQ_MIN 2
#define FREQ_MAX 20
// Not exactly mm but ballpark
#define DIST_MIN 100
#define DIST_MAX 3000

Since we want the transition between pitches to be somewhat 'smoothed' in order to reduce the effect of outlier measurements, we initialize a few variables to take a weighted average (heavily weighed towards the newest measurement):

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int DistAvg = 5000; // Start average with something to get there faster
float DistAvgWeight = 0.9;      // IIR Weight of new Measurement. Y[n] = aX[n] + (1-a)Y[n-1]

In loop we start taking the actual measurements when they become available and the signal rate is good (object is not too far):

distanceSensor.startMeasurement(); //Write configuration bytes to initiate measurement
while (distanceSensor.newDataReady() == false) //Poll for completion of measurement. Takes 40-50ms.
{ delay(1); }
unsigned int uiSignalRate = distanceSensor.getSignalRate();
if (uiSignalRate > 10)
    NewDist = distanceSensor.getDistance(); // Get the result of the measurement from the sensor
    DistAvg = DistAvgWeight * NewDist + (1 - DistAvgWeight) * DistAvg;  // Averaging the measurements for the smooth transition between pitches

And finally use the weighted average to set a register which controls the frequency of the haptic output:

// fscale is basically a logarithmic mapping from one range to another
uint16_t ui16_New_OCR = fscale(DIST_MIN, DIST_MAX, OCR_MIN, OCR_MAX, DistAvg, 4);
// setting the register
OCR1A = ui16_New_OCR;

You can see the full code for the device at :)