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).

What is it?

Spin to Win is the name of our HackPrinceton hack, which was a 3d printer for under $20 (if you sub an authentic Arduino for a clone). It uses reflective IR to scan a 3d surface which is rotated as the scanner is lowered in order to get a mostly complete side scan.

The final product, with the motors running a bit faster so it’s not as boring

Some example scans generated when plotting the raw data through Wolfram.

On left, a paper cone. In the middle, the same cone, but one guy we were demoing to wanted to wave his hand between the cone and the scanner for a bit while it was running. On right, a slightly deformed paper cylinder.


Akhilesh thought of the idea while we were sitting around in the Philly public library, and since my hardware kit isn’t super expensive, it happened to be under $20, which is nice. I’ve used reflective IR LEDs for a few other hackathon projects, for different things, mostly because they’re really cool, cheap (like 10 cents each), and versatile (sense distance, color, luster, heat, etc.) sensors. I initially wanted to go for a rotating arm around a stationary scanned object, but we quickly scrapped that idea in favor of a simpler rotating base and a scanner that moves only vertically due to easier construction and less error due to shaking.

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.

How we made it

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.


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.


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.

That’s about it…

I wouldn’t really recommend making one of these manually, you’d probably need 3d-printed parts for it to be calibrated accurately enough to scan anything decently well. It was a fun project to make by hand though, and the experience and results were pretty rewarding. It’s also not that great at scanning anything too glossy, and considering most of the things people want to scan have some metal/plastic in them, it’s probably better as a desk ornament, or would be, if it didn’t get crushed in my duffel bag after walking, riding on the train, and flying back home.