-
What's it made of
08/02/2021 at 22:56 • 0 commentsThe second picture shows a closeup with the Arduino Pro Micro, the Sensor Board, Power Switch and Output Jack.
The Sensor board is attached to the "front" of the case with Hot-Glue so it's fixed in relation to the case.
The third picture shows the distance sensor chip (the two greenish "windows") in all its splendor.
The next picture shows a small loudspeaker that was carefully removed and cut from the plastic framework surrounding it.
This is one of the most "advanced" features of our project: the user feels timed pulses indicating the distance to the nearest object.
Most other similar products (even commercial) use a simple vibrator that just spins a motor with an ex-centric weight. While varying the voltage on such a vibrator does vary the level of vibration, those "levels of vibration" are much less repeatable and distinguishable than our precisely timed pulses.
-
Project build
08/02/2021 at 22:46 • 0 commentsWe built the project inside a re-purposed case that was holding 3 AA batteries and a small board for flickering a string of LEDs to be placed inside a bottle to look pretty.
The first picture shows the insides from the top without the cover. Hot Glue was used to hold the sensor board at the top-right and the power-switch (top-left).
The black-red wires connect the haptic device to a jack in the side of the enclosure.
The haptic device is a small rectangular speaker salvaged from an old laptop or tablet. You can see the red coil attached to the transparent membrane. As we apply voltage to the coil the membrane will be pushed out and be felt by the skin if applied on a sensitive area.
-
Our current code
08/02/2021 at 22:46 • 0 commentsWe are using the SparkFun VL53L1X Arduino Library by Nathan Seidle of SparkFun (https://github.com/sparkfun/SparkFun_VL53L1X_Arduino_Library) 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 https://github.com/CataCluj/VL53L1_BlindDistanceSensor :)