This was on everyone’s minds in June, when Jennyfer Peterson spotted a neat device to help keep visitors at a suitable distance from you. It was the Aura Aware distance warning device. It is lovely but a little expensive.
So I thought it would be a reasonable thing to make. Nova Labs has tools that would enable making an identical copy. But – we were closed, and I do not have all the skills anyway – although there are makers there that could imitate it exactly. So I thought – what can I do instead? And came up with a distance indicating device with a COVID flair.
You want to see how near you are? Then I will make a NEAROMETER. This is the story of how I made it.
The first thing was to look at the needs. Basically it has to indicate you are more or less than 6 feet away. The Aura also provides an optional tone for warning. I would look at all of these, and use a microcontroller to run it. I looked at Arduino UNO then decided on the D1 MINI 8266 clone instead. I had one, and it was smaller and faster and had just enough pins to manage this – plus I could use the same programming interface.
The immediate thought was to use either ultrasonic or infra-red distance sensors. The best Infrared sensor for that range of 0-12 feet that I could see was the VL53L1X – so I ordered a breakout board from Sparkfun. I already had HC-SR-04 Ultrasonic sensors, and I would have to test them both for this application. The IR sensor uses a digital I2C interface and the SR0-04 uses timed pulses.
I decided that I could use 4 bands, in 3 foot zones out to 12 feet, and use a pointer and LEDs to indicate the target’s range. Appropriate colors would be RED, YELLOW, GREEN and BLUE for the safety of the range increment, and I would give each a suitable legend. For the pointer, I decided to give it a VIRUS picture at the end.
Here is the first display concept. (image here)
The D1 Mini microcontroller gives out a 3.3V digital signal but I wanted something louder than it could drive so I found a 2.5W amplifier board from Adafruit and a little speaker that would be enough.
Testing each function separately was fairly straightforward. There were examples for each device I had to use on the Internet or in the Arduino Libraries that I could use as a resource.
LEDs were the simplest; I needed to light each color when the pointer was in that zone, and so I used the pointer angle to decide which LED to light. I also needed to choose LED series resistors to get approximately the same brightness in each one. (Another reason for picking those colors was that I had LEDs to match each zone color on hand.)
The Servo was a bit trickier. It was a 180 degree servo, and the pointer range was about 90 degrees. Moreover lining up the pointer to the zones would require servo positioning before adjustment and calibration. I knew there was a mapping function I could use once I had established the range endpoints.
Of the two sensors, they both tested usable over the distance (0-12 ft.) but the IR sensor seemed better for the longer range, although the angle of detection was narrower than the SR-04.
I had decided to make the assembly from foam core board so after testing the servo and LEDS on a breadboard, I mounted the face picture on a piece of 8.5×11 foam core board. I drilled out the holes for the LEDs and hot glued them in. Then I wired them up into a harness with a jumper plugs at the end and tested it with the breadboard. Similarly I cut a hole for the servo, hot glued it in and tested it with the breadboard.
The breadboard connections were a little intermittent and the microcontroller occasionally would get a forced restart, and the servo was erratic at times, so I decided I could not use the breadboard for the final assembly. I found some prototyping shield boards for the D1 Mini microcontroller and figured I could build what I needed on there, making all the devices pluggable. That also would allow me to provide external 5V from USB power input for the servo via the shield, so it did not have to be powered through the microcontroller.
I was getting some erratic behavior. One possible source could have been that the D1 Mini microcontroller outputs only a 0 to 3.3V signal, but the servo runs off 5 Volts and really expects a 0 to 5V signal. I found mixed information on that with a number of sources saying they used 3.3Volts to drive 5V servos with no issue but I figured I would try a level converter to see if I got improvement. I found a design for a simple level converter using an FET and 2 resistors and it seemed to work fine. The behavior seemed to improve. Now, I had to design the shield. I designed the location for the connections and the components and connections, somewhat like laying out a Printed Circuit, and built it up on the proto shield board. It got a bit ugly, but it seemed to hold together.
Now the servo was in, I could calibrate the pointer position to the programmed angle, to line it up with the ends of the panel picture pie segments.
The other calibration needed was for the distance. The IR sensor has 2 ranges, short and long distance. In long distance, getting close was reliable, but at a distance the sensor needs enough reflected light to work reliably. Over 10 feet, if a person is narrower than its field of view, it has a tougher time getting a good reading, but it will still detect targets. I tested the distance readings using cardboard boxes as the target, spaced away by using my 1 ft. floor tiles as the measure.
Once I got the reading (in mm) established for 3, 6, 9, 12 feet, I was able to map that to the servo angle. I also used the calculated angle to decide when to light the LEDs.
Arduino has a tone function. I could get the tone to work by itself. I could not get the tone and the sensor/servo to work together despite trying several different tone libraries. My conclusion was that the libraries were using the same interrupts in the microcontroller. I did not want to make the tone an inline event, adding a delay between making readings, so I eventually decided to defer the tone function until I finished the rest, but build in the hardware access for a cable to attach the amplifier.
To input USB 5 Volt power, for the servo and D1 Mini, I needed a standard micro USB socket on a breakout board to wire to the shield. Of course, nothing is simple! I had to use solid wire to fit the takeoff holes in the board (the stranded wire I had would not fit) but I wanted flexible wire to attach to the shield so it was not pulled by the power wires, so I had to make a wire splice, ugly again. I then tacked the flexible power wires onto the shield and added a smoothing capacitor to filter noise. I say tacked, because I was layering connections into a solder blob rather than having a nice separate hole for each wire connection as I ideally would on a printed circuit board. Ugly. Conveniently, the D1 Mini can be powered from this 5V source connected to its 5V pin or from the programming USB to the PC.
Here it is partly assembled with the header pins below for the wiring, and sockets for the D1 Mini header pins.– not too ugly yet. But as you can see, it will get a bit busy on there once it is all wired up.
I plugged the LED, servo and sensor cables into the shield and tested them one at a time and they all worked. Then I tried them all together – they worked, but…… the behavior needed some fine tuning. I put in an averaging function to smooth out the sensor measurements as there was too much variation at the longer ranges and with no target it was all over the place. Fortunately as a digital interfaced sensor, reading status was available over the I2C interface, and I could suppress bad readings. That did not get rid of it all but improved it. When I suppressed a bad reading I replaced that with the prior good reading. I also limited the high end usable reading to a maximum of 12 feet, for the far extreme of pointer movement.
The ability to read at distance also depends on the target size and the reflectivity. Setting bounds on range, scaling measurements and eliminating bad readings are a big part of dealing with sensors.
I had a front panel with LEDs and Servo, but I needed a place for the sensor. I assumed since the sensor had a small field of view that I could use an aperture in the panel barely larger than the sensor chip on the board, since light goes in a straight line. WRONG! When I located the sensor behind a hole in the panel, it showed a reading of ZERO! I had to enlarge the hole significantly to get it to read the distance properly. I think it must have been picking up reflected light from the edges of the hole which was certainly unexpected and left me with a bigger hole than I wanted. Ugly! Possibly I could have stopped that by making the hole edges black, but I did not try that.
I cut thick foam board for the base and hot glued the front panel to it, then made sides from the thinner board, angling them for a sloping back. To provide a firm seating for the USB socket, to survive plugging and unplugging, I hot glued it to a small piece of plywood and glued that to the base. The D1 Mini and its shield were glued down with double sided sticky tape.
I wanted access to the interior so I made the back hinged and fastened it using Velcro hot glued on. I put hinges at the top and Velcro fastening at the lower sides.
I finally decided against a beep, thinking that it would get annoying after a bit, and I also had not figured a way to make the tones work with the rest of the functions, although I tried a variety of things. I am sure there must be a way, but looking online I found I was not the only one having issues of this kind which made me feel a little better about it. I think it was the timer use, and I might have been able to modify the library to use a different timer, had I pursued it.
I donated the completed unit to Nova Labs so I hope you may see it somewhere there and you can test your own distancing estimates. If not, you can see it here.
https://drive.google.com/file/d/18MZaub7FI9E0Ype1dD8q_NdSjJFJ12Sl/view?usp=sharing
Doing this again, I would not use the “map” function for interpreting the servo angle. The “map” function returns integer results, so the pointer moves in 1 degree increments, which are visible jumps in position. I could improve this by using my own floating point math instead. The 8266 microcontroller provides 1024 increments in PWM to move the servo rather than the Arduino’s 256 increments so smoother movement would be possible.
Other considerations for improvement would be to figure out the pesky tone interrupt issue and how to get the IR sensor operating behind a neat small aperture.I am forced to remember “Perfect is the enemy of good”.
https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good
We are open! See our COVID-19 Phase III reopening guidelines.
|