About
Reading Hack a Day I found an interesting challenge: drawing their logo somewhere. And the fact that was even more interesting: “preference will be given to the largest and smallest submissions“.
I started figuring out how to do something like that with the things I had around, and settled for using a laser and two servos. Even though I missed the deadline for submissions, it became a very interesting project and I learned a lot.
*
See my project featured on Hack A Day and my personal blog post for full details!
Images
Get the code!
I took the time to upload the code to my GitHub account. You can download the Arduino code, both Processing scripts and even the Python code I used previously from the laserdriver repository. It’s all released under the MIT license.
Github
What I learned/what's next
WHAT’S NEXT
I learned a lot by making this. These are some of the things I’d like to change in the future:
- The line algorithm must be enhanced in some way.
- I must redesign the frame to take advantage of the servos’ definition.
- The laser is weak. I should use something more powerful.
- I could store the canvas boundaries‘ variables using the EEPROMex library, so they don’t need to be entered at startup.
- The drawing array consists of 3 integers per point. It’s a huge waste of memory, given that the coordinate values are usually below 3000 and the laser status is just a binary value. Memory usage can be optimized.
- A physical button to start/stop drawing would be somewhat easy to add (to dispense serial communication)
- An automatic camera trigger would be helpful. I didn’t have an opto-isolator for that.
The Project
Here is an annotated version of how I built this:
GETTING STARTED
I built the structure using only what I had at home and because of that many design choices were governed by that. There are many ways to draw with a laser and I think the best one is using a moving mirror, but sadly I didn’t have a tiny mirror for this, so the next option was moving the laser directly. The main disadvantage of this design is that I can’t replace the laser easily, but I can live with that.
I started by cutting a piece of cardboard to fit the servo arm. Once that was done, I attached the second servo to that cardboard using a copper wire and some ninja knitting technique.
My laser pointer was convenient at pointing things but not so much at being an electronic part for my project. It was inside a large cylinder and it was necesary to push a button to turn it on. The solution: a hacksaw (a tool with a cool name, by the way).
After tearing open the laser pointer I soldered two cables to the laser (bypassing the switch) and it was ready to be used.
The second servo (which holds the laser) had a cardboard piece too, but it was bulky and (more importantly) useless, so I attached the laser to the arm with high technology (masking tape).
THE ELECTRONICS
The circuit is nothing too complicated, but there are a few important considerations: servos need more current than what Arduino can provide safely, so I had to add an external battery (6 Ni-MH batteries). This battery pack outputs 7.2V when fully charged, and goes below 4.8V when depleted. The servos need 5 volts (I don’t know exactly what tolerance they have), and I’m pretty sure that 7.2V are too much for them. To keep them at 5V all the time, I used a switching regulator (LM2956). Once set, this IC works very nice.
Now that the servos are sourcing their power from the battery pack it is important to join its ground with the GND pin of the Arduino, so the servos work with the PWM.
The laser draws 43 mA, which is over the maximum limit per pin in the Arduino. To circumvent this limitation I used a NPN transistor. The laser is connected to the Arduino +5V pin and the ground goes through the transistor. When the laser pin is set to HIGH the transistor closes the laser circuit.
A potentiometer is connected to A0 in order to manually move the servos (calibration).
MAKING IT MOVE!
With this simple rig I started writing code to drive the servos and do the first tests. I promptly had my servos moving, but it was obvious that each step would be abrupt using Servo.write(). Remember that with this design I can move the laser 180° in both the X and Y axis: this means I can’t use the whole range to draw over a wall! So instead of 180 points I have… less (it depends on the distance to the wall). Setting limits to both axes solves that at the cost of less drawing points. Fortunately I learned there’s a way to handle the servos much precisely: using Servo.writeMicroseconds().
Servo movements are determined by the length of the pulse received via their signal cable using PWM. In the case of the TowerPro SG90, the acceptable values range from 600 to 2300 (I tested it). It’s not safe to drive the servos to their limits! (they will draw more current) Speaking of servos and current, according to this, servos draw more current doing small steps.
DRAWING
It was time to get the Hackaday logo and transform it into something Arduino could understand. My code stores drawings as an array of points. Specifically, for each point stores the laser flag (1=on, 0=off) and 0-based X and Y coordinates (no offsets). The laser flag determines the status of the laser until it reaches the corresponding coordinates. Example:
Drawing{
{0, 50, 50},
{1, 70, 50},
{1, 50, 70},
{1, 50, 50}
}
My embarrasing odyssey through file types began with the SVG file provided by Hackaday. I imported it into Adobe Illustrator and exported it to PDF. Then I went to AutoCAD and imported that PDF to re-draw it since I wanted a simpler version of the logo. All this reminded me of this XKCD comic. From AutoCAD I managed to get a TXT file with lines formatted like this: X1 Y1 X2 Y2.
*
See proper formatting for the code on my blog post. You can also read the full description of how I drew the logo there!
Comments