I worked on this project with my teammate Akhilesh Yarabarla, who did most of the math and a lot of work on calibration; I did most of the hardware and code. If you’re looking for the Devpost, it’s here and the GitHub repo is here (as badly coded as any of my other hackathon projects).

# Price Breakdown

• Reflective IR LED - 10 cents
• DC motor - $3 • Breadboard (not actually required, could get by with a small$1 one)
• Continuous rotation servo - $7 • Arduino clone -$3 to $10 • Gears (entire bag, not just the few used) -$3
• Electrical Tape + Cardboard + Wires + Resistors - around $1 All in all, around$18 on the upper end, assuming your Arduino comes with a USB A Male - USB B Male adapter (which even all of my \$3 ones did). It probably helps that I buy most of my hardware from Aliexpress, though.

We started off trying to make something to vertically move the scanner. I’ve generally had bad experiences with trying to make pulley-based systems at hackathons, and this was no exception, so after having a lot of trouble trying to get that to work, I looked in my tackle box of hardware and found a rack to use in a rack and pinion gearing, and it luckily came with holes to attach the reflective IR LEDs on there. I also put a cylinder of electrical tape on it to try and make it pick up less noise, which actually worked pretty well.

Then we tried making a flat base and attaching it to a dc motor. We first tried taping a few pieces of cardboard together and using the hole in a zip tie to attach it to the dc motor and hold it in place. It didn’t work; it ended up too wobbly to actually get any decent measurements on, though.

We were lucky, though: the dc motor I used had basically the exact same diameter as one of the gears in the gear set, so we were able to tape cardboard circles to the gear in order to provide a larger base, and this gave us less wobble than our earlier design.

Left to right in order of progress made. Once we got this working, we also needed to hold the rack and pinion together using a bunch of zip ties, cardboard, and duct tape. The motor also broke apart a couple times and the metal inside needed to be repositioned using pliers, and we also needed to calibrate everything, which can probably take a section on its own.

# Calibration

Calibrating the z-axis was pretty easy, we just figured out the speed of the motor when moving vertically and found the z position as a function of time. To find the angular velocity of the dc motor for the x and y axes, I measured the length of 10 rotations and divided by 10 (to reduce error) and Akilesh made a function to put all of the data together and generate x/y/z coordinates given distance and time. The distance needed to be given by the reflective IR LEDs, though, and for that we needed some data points to get a curve best fit from. I didn’t actually have a ruler, but I had a pencil, paper, and Chrome dev tools, where you can view a ruler. I didn’t actually confirm that it was to scale, since I didn’t have a real ruler, but this doesn’t actually matter, since the only thing it’ll change is the scale factor. I first moved the scanner down and placed the ruler directly perpendicular to it, starting at the end of electrical tape wrapped around the LEDs. I was then able to put a piece of cardboard on the scanner at every centimeter mark and write down the raw values outputted by the scanner. By putting those points into Wolfram alpha, we were able to get this function:

Which is pretty ugly, but then again, we’re using raw sensors, so it should be expected. I ended up making a lookup table since taking an inverse didn’t work, and I was too tired to spend time on that when I knew I could write a lookup table in less time, but thinking back on it with a bit more sleep, it probably would have been easier to flip the X and Y values and taken the curve best fit on that, though I haven’t tried it. Akhilesh could probably give you more info on exporting STLs from the point cloud we have, as well as using Wolfram notebook, but the general gist of it is that we didn’t have enough time, and really finished this up pretty last-minute.

# Rationale/Specifics

All of the data is passed via serial from the Arduino to the laptop, where all of the processing is done in Node. It’s pretty fast that way, and you don’t need to worry about processing time too much since you’re not doing anything on the Arduino except use it as a glorified MOSFET and analog to digital converter. Data is sent from the Node instance to the Wolfram notebook through the wondrous OS X clipboard (we sat down late at our demo table and I had ~5 min to figure out how to graph the info, since we couldn’t get it to work through simple POST requests, probably due to huge size). It takes a long while to graph the data, mostly due to lag caused by the MVC used on Wolfram notebook though, and not Wolfram actually graphing it.

Reflective IR is used instead of sonar/laser/etc., simply because I have experience with it, so I had a bunch in my hardware kit. Sonar was probably available at the hardware checkout, but it’s not as good at low resolution. I hadn’t used it for precise distance measurements, and was pretty suprised when it worked as well as it did, though it did mess up a lot with more glossy surfaces, especially metal. Here’s a nice stackexchange link I found that’s kind of relevant, as well as one of the helpful images that probably helps explain our function we got above, as well as why our sensor bottomed out after 8 or so cm (I assume the sensors used to make this graph were a bit higher quality than 10c Aliexpress-bought LEDs, and got better info longer distances because of it):

The circuit we used was something like this one:

At least as far as the reflective IR LEDs were concerned. No other OP amps or instrumentation amps were used, and the wiring for the servos and dc motor was also pretty standard.