Previously, I’ve written about how to build a low-power laser engraver from the guts of a DVD burner [see “Laser Cuts Paper,” IEEE Spectrum, June]. My fully automated setup was similar in spirit to that of a commercial engraver, and while effective for small areas, this approach quickly becomes unwieldy if you want to burn larger areas. You need longer rails and leadscrews, bigger stepper motors, more structure, and more space.
As I don’t often require a high level of precision on larger areas, one evening I had an inspiration, and a new laser mouse was born. Normally, a “laser mouse” shines a laser onto a surface in order to track its position. My laser mouse does something different: When I move the mouse across a surface, it uses its tracking mechanism to make sure that an attached engraving laser is shining when it should be. The resulting engraving should look a little like a stone rubbing. (Note that even a small area of charred wood or paper can produce a remarkable amount of smoke.)
So how does it work? The laser mouse requires a host computer, so I coded up something ugly but functional in Lisp on my trusty basement Ubuntu Linux box (you can use the computer and language of your choice, so long as you can get access to a USB port and can read mouse-position information). The Lisp code converts a digital image into an array of brightness values; then it reads “/dev/mouse0”—Linux’s standard software interface for an attached USB mouse—to decode incoming three-byte messages from the mouse into incremental x and y movements. These incremental movements are continually tallied to determine absolute position. Then my program consults the brightness array, and if the corresponding value for that position in the array is less than a threshold set when the program is started, it sends a 1 along a second USB connection to the microcontroller driving the laser. Otherwise it sends a 0.
On the mouse side, I taped a prototyping board fitted with a microcontroller to a US $10 Logitech mouse. The microcontroller I used is a Teensy, a controller slightly shorter and narrower than my thumb, that’s mostly compatible with the popular but much bulkier Arduino microcontroller. The Teensy listens to its USB connection, decodes the packets being sent by my Lisp program, and, as needed, puts a high or a low voltage on an output pin that enables or disables a leftover laser driver connected to a 100-milliwatt red laser I had lying around.
Ideally, I’d like a more powerful laser to draw faster, but did I mention that even a small area of charred wood or paper can produce a remarkable amount of smoke? And even this 100‑mW laser draws more power than the Teensy can supply, so I have to use an additional external power supply for the laser driver. As a consequence, instead of powering the Teensy from the USB connection as I might normally do, I also had to connect the Teensy to the external power supply to ensure a common ground. Otherwise I’d have run the risk of unpredictable voltages on the connection between the controller and the laser driver.
So far I’ve been using a checkerboard pattern as my test image. Initial results produced more or less random scratches, but I’ve proceeded to where there are recognizably denser and lighter regions. The key to improvement has been in reducing the workload on the Linux box to make it more responsive, and I’m creating a stripped-down system that doesn’t run any unneeded software.
Although—or perhaps because—the laser mouse is so simple to build, it made me think about how inept modern desktops and laptops are when dealing with the outside world. I had to use an entire microcontroller just to get on and off signals to the laser driver, because there’s no clean way for an ordinary mortal to tell a personal computer, “Please put 5 volts on this outside-accessible pin.” And I had to carefully configure my Linux setup to allow my program access to the raw messages from the mouse. Normally programs are allowed to access the onscreen position of the mouse only within their own windows, which typically measure no more than 1800 by 1000 pixels. Because I track information from the mouse with my own code, the number of pixels in the image is limited only by the constraints of the available memory and the language, which in my case could mean an image as large as 25 000 by 20 000 pixels. (How big an actual engraving this translates to depends on a scale factor that determines how much the mouse can move and stay within the boundaries of a single pixel. In my system, this can be as small as 0.25 millimeters per pixel and as large as desired, within practical limits.)
On the positive side, one of the things I like about this project is that it is endlessly tweakable: In a single weekend you can have a basic version running with an Arduino and a prototyping board, or you can try being more ambitious by adding orientation sensing for higher accuracy, a custom mouse enclosure, hacks to draw all your laser power from your USB ports, and so forth (I’ve already swapped in a higher-power blue laser, for example). On the software side, you can go from simple positional lookup to complex interpolation, or even graphing code that controls the laser with no reference to a preexisting picture. (Of course, you could also burn or blind yourself, or burn down your house or apartment. If you’re not sure what you’re doing with a laser, don’t do it.)
When I “finish” this project in a few years, I imagine that the ultimate laser mouse will look very different. The microcontroller will detect the mouse’s position directly from the onboard electronics and read an attached SD card for the values of the image array. It will boast a couple of lithium batteries for power and accept additional special parameters via Bluetooth. Then all I’ll have to do is build a mobile robot to wield it.
This article originally appeared in print as "Laser Mouse."