Have you ever heard the expression “yak shaving” before? Allegedly invented at the MIT AI lab a decade or so ago, it’s what you call all the stupid, annoying work you have to do first in order to be able to do what you’re trying to get done. When you find yourself looking for a tool to make a tool that you can use to make the tool you need (and which you could buy from Enco for $25), you’re shaving a yak.
Anyway, I spent a good six hours today trying to figure out the best way to cut a hole in a piece of plastic. To be specific, to cut out two holes in the face of the enclosure for the keypad and the LCD display. In order to do this, I need a way to clamp the enclosure securely. Neither a vise or double-sided tape would work, and there’s not enough room to get step clamps snug enough. So, it was going to require a fixture.
The enclosure front panel luckily has a bunch of holes with threaded inserts (to hold the two halves together), so I figured I could just use these to screw it down to a piece of tooling plate. So, all I had to do was precisely drill 12 holes (4 for dowel pins to locate the fixture, 4 1/4″ holes for screws that hold the fixture to the mating plate on the mill, and 4 for the screws that would hold the enclosure to the fixture). As this was one of those cases where every .001″ counted, it was slow work.
Nonetheless, I happily test-fitted the hold-down screws for the fixture (spot on), the hold-down screws for the enclosure (3 perfect, one hole needed to be drilled .010″ oversize), and the dowel pins (one came out oversize due to cheap drill bit, but 3 pins should be plenty). The screws that hold the fixture to the mill come down from the top. The screws that hold the enclosure come up from the bottom. So, you need to screw the enclosure to the fixture, then screw the fixture down onto the mill. Easy enough, if time-consuming.
Can you see what’s coming? When I tried to actually put it all together, I realized that once I screwed in the workpiece, it covered the holes where the hold-down screws for the fixture went. If I screwed the fixture down to the table first, there’d be no way to attach the workpiece. So, this would be me:
So, long story short, I’m going to have to make some clamps to go around the edges that can be secured from the top. The earlier efforts weren’t entirely in vain as they’ll make it easier to attach straightedges to locate the workpiece properly, and the end result will be a fixture that’s easier to use as I’ll be able to swap workpieces without having to unmount the fixture. Still, I’ve probably got another 4-5 hours of work ahead before I can even *try* the CAM program I wrote to mill out the two holes. Anybody need some extra yak hair?
Just thought I’d throw up a shot of the first completed board from last night. The photo below shows it laid on top of what I hope will become its enclosure. The tricky part, which I hope to work on this weekend, will be working out the mounting and keypad overlay.
One of the lessons I’ve taken from the success of the Shumatech DRO is the importance of having a good enclosure solution as part of the plan/kit. These are real tools meant for use in a quasi-industrial environment, so the enclosure is as important to the functionality of the pendant as the software or firmware.
At this point, my plan is to finish up the enclosure, and then start working all the kinks out of the software. I’m ready to get back into the shop for a while after spending the past few months bent over a breadboard and deciphering data sheets!
After spending nearly 3 weeks (!) in Chinese customs and a day waiting for the most recent snowstorm to blow over, the first run of boards finally landed on my desk. The order said 12 pieces, but as sometimes happens, I actually ended up with 13 boards. Now I get to find out if I got everything right–wish me luck!
EDIT: WOOHOO! Assembled the first board, and after chasing my tail with what turned out to be a software bug (I reversed some pins from the perfboard prototype), the board appears to be working! All the pins line up where they’re supposed to, and the switches are being read properly, and the LCD works. Now I just have to hook up the encoder….
OK, so, the PCBs I was supposed to get early this week got stuck in customs in Shanghai, so I decided to take a few hours and put together a minimal Arduino-EMC case study with source code for those of you trying to follow along at home.
This example code is designed to control a normally-open switch and two LEDs, and is wired up to the machine on/off switch. I chose that configuration to test a cool new doohickey I got with my last Digikey order, which is a two-color illuminated pushbutton switch from NKK Switches (see here). It’s got a pushbutton plus two LEDs in a nice little package. It’s not sealed up the wazoo like a true industrial component, but it shouldn’t do any worse than the mice and keyboards people use in their shop. Either way, you should be able to replicate this example with any two LEDs and switch you have laying around–the Arduino and EMC parts won’t be any different.
I’ve attached all the code for this example as pages on this blog (WordPress is annoyingly whiny about file attachments other than common types like JPG, DOC, etc.). Here’s a basic outline of how to do this for yourself:
- Create the Arduino sketch using my sample code. Wire up a breadboard with 2 LEDs and a normally-open switch and connect them to the Arduino. Just to be safe, I strongly suggest firing up the Arduino serial monitor and trying to send and receive commands there just to be sure you have the circuit and Arduino working properly before proceeding.
- Once that’s known good, you’ll want to install the Python module in your /usr/bin directory. First, copy and paste the source code into a text file and save it as “simple_arduino” without any file extension. Then, move that file to your /usr/bin directory and make it executable using these commands:
sudo cp simple_arduino /usr/bin
chmod +x /usr/bin/simple_arduino
- Configure your HAL file: This uses the HALUI module to pass commands to EMC. See here for my sample HAL configscript. Make sure that your machine .ini file loads the HALUI module and runs the script.
If the comments in my code don’t answer all your questions about how it works, feel free to leave questions in the comments. Good luck and have fun experimenting!
I have an order of 12 boards on a UPS truck that refuses to show up at my office when I am there. Hopefully this will end Monday. I’m putting together a parts order so I can stuff the board and find out whether I made myself a set of green coasters. One of the joys of this game is that it’s never easy to get everything you need from Digikey or Mouser, there’s always one part that you need to order from the other guy.
This cropped up as I was shopping for encoders. The one I’ve been using contains tasty lead, which means it’s a no-no for our friends in Europe. So I found a new one for about the same price which might be much better. It’s a Honeywell 128-count encoder, which is 4x the resolution of what I was using, but it doesn’t have detents (which I like). It’s marked as end-of-life, but both suppliers have 500+ in stock, so hopefully it will be available at least for the next few months or so.
Cheap Encoders Considered Harmful
I also had a chance recently to test out some $3 Panasonic 24-count encoders I ordered on a lark with some other items. At that price, I had the idea of doing a board with 3 encoders, one for each X/Y/Z axis, plus the spindle and feed overrides. Unfortunately, my first experience with them wasn’t very encouraging. I found that they missed counts very badly when turned any more than a single click at a time. I could see them still being usable for a secondary control like an SRO/FRO, but for axis control I think they’d start to stink pretty fast. Live and learn.
Another thing I’ve had to educate myself on that has proven surprisingly complex is the world of cables and interconnects. Every electronic project I’ve done has gone great until it came time to run wires between the PCB(s) and the other bits. At that point it went one of two ways:
- Solder nice long leads on while still on the bench, then roll it all into a bird’s nest and jam it in the enclosure. Works if appearance, interference, and space aren’t concerns.
- Mount everything in the enclosure, then spend HOURS cutting, stripping, and soldering wires into place. Pray to the deity of your choice that you never need to remove or replace any of it.
For that reason, I’ve designed this to (1) require as little cabling as possible, and (2) to permit maximum flexibility where it is required. Any connector that uses .100″ spacing will work, and there are literally hundreds of options out there. Many require special tools, so I’m ordering a few different ones to see which are easiest to do without special tools. I have a funny feeling that in the end, plain-old screw terminals may prove the best compromise….
My D’OH! Moment
The first big OOPS I noticed too late in the game was that I did not provide for a reset switch for the Arduino. The on-board switch will be blocked, so this means the only way to do a reset will be to pop the cord. Normally you shouldn’t need to reset the Arduino during operation, but I’d like to provide for the option so this will get fixed on the next rev. If I’m lucky, this is the only oversight, as it’s more of an inconvenience than a fatal error.
Why I’m Not Releasing the Source Code–YET
I’ve gotten a LOT of requests for source code, and the answer is still “no.” Here’s why:
- Always trash the prototype: What I have right now is a bunch of hacks and half-measures stitched together to prove that I could get it to work. One of the most important rules of software development is to build a prototype, and then throw it out and start over when it’s time for the production code. Looking back over the four months or so since I started this, I see a lot of things I want to do differently in an architectural sense, which I’ll write more about later.
- I can’t support it: I want to spend my time building the V1 production code, not helping people to get this crud working in their setup. If I sent the code to somebody and it didn’t work, I’d feel obligated to help them, and right now, I don’t have the time to do that *and* move the more important part forward.
- So? I can use what you have: Probably not. My code is a big pile of spaghetti built around exactly the hardware setup I’ve built. Even if you had exactly the same hardware I do, you’ll find a lot of features that work halfway (on a good day). If you want to just use a few switches and an encoder with no LCD for instance, you’ll find most of it needs re-writing. In that case, you’re going to be better off starting from scratch and building it all your way. In a previous post, I laid out a roadmap for exactly how to do that. Trust me, that’s going to be easier than dissecting my code. I ran into exactly this problem when trying to re-purpose Jeff Epler’s original Arduino-EMC example and ended up redoing everything from first principles. If doing that is beyond your abilities, I suspect my code would prove equally useless.
- We shall sell no wine before its time: From a commercial standpoint, I think it makes more sense for me to not release the software until I have boards for sale. Now, I have no objection to anyone taking that and using it to build their own without buying diddlysquat from me. Likewise, once it’s out there, It’ll be open for anyone to learn from and make a better product than mine. C’est la vie. But, at this moment I do have a little wiggle room to maximize my first-mover advantage. If you’re frustrated because you want to start your project, just think of that waiting as the price you’re paying to have me do the hard work for you 🙂
I have thought about publishing a mini-tutorial on how to push single bits and signals back and forth from EMC through HAL to the Arduino and back, but this would be more hours of work, for which please see (2) above. So I’m planning to do this after the PCB and V1 software are ready. In the meantime, please don’t hate me too much!
So things have been a bit quiet lately while I was focused on designing an Arduino shield based on my stripboard prototype. This includes:
- Arduino shield pattern for easy mounting
- 25-key matrix with diodes on all switches to minimize ghosting problems
- headers and trimpot for connecting a standard parallel LCD
- header for encoder +5V, GND, PhaseA, PhaseB
I decided not to incorporate any encoder-specific circuitry so people could pick their own. There’s a wide variety and this design pretty much just provides power and the two Arduino interrupt pins on a header so you can roll however you want. My Grayhill encoder needs a couple resistors which can be attached on any little bit of stripboard.
I’ve attached a couple of PDFs with the schematic and board layout. If anyone finds any bugs, please leave a comment. I’m going to order one or two boards this week to verify the design, and then I’m planning to order a small batch of a dozen or so which should sell for ~$15-20 or so just to cover my costs. Any commenters will get dibs on the first boards of course!
Looking towards a final version, I’m seeing a cost breakdown something like this, based on single-piece retail pricing for the components:
- Arduino board: $30
- Encoder: $26
- LCD Module: $18
- Raw PCB: $17
- Small components: $15 (switches, pin headers, resistors, diodes, etc.)
That gets you to a total price of $106. The Arduino is optional if you have one already, and you could omit the LCD as well, but it’s pretty cheap for what it gives you. If there’s demand, though, I might do a different design either with more keys or with LEDs for more simple feedback. Another option is to go with either a cheaper encoder (I’m testing a $3 Panasonic one now) or a more expensive one made for use as an MPG.
I’m also starting to design out an enclosure strategy for this. One lesson I’ve learned over and over is that the least fun part of most electronics projects is finding a place to put the $#@! board. This project by its intended use really demands a well thought-out approach in order to be usable. I’ve seen some nice “grabber” hand-held instrument cases for about $30.
Where all this gets interesting is if demand is decent, I might look to offer complete parts kits. As it is, the parts for this come from at least three different places, so you’re going to get hit with close to $30 in shipping and handling charges. If I could order in quantities to do at least 25 at a time, it would make it possible to do a full kit for the same or less than buying all the parts yourself, and of course save the hassle of navigating the Mouser and Digikey ordering systems. So if you’re interested, please leave a comment–no commitment!
I was flattered to receive a thumbs-up from Bob Warfield on my previous post. Bob is in my mind one of the leading figures in the new wave of CNC practitioners, and his new product, GWizard, is among the most interesting out there. Bob asked a question I’ve heard dozens of times since putting this project online: “what about using an Arduino to generate steps?” As my reply to Bob got longer I decided to make a post of it.
Basically, my position on this question has long been, “why would you want to do that?”
While it’s true that you don’t find parallel ports on laptops or new Dell cheapo boxes, you can easily assemble a brand-new Intel Atom system capable of running EMC2 very nicely for less than what a Mach license costs. These motherboards are so cheap, they come with the CPU and sell for about $75, retail. If you can still get a parport header on a $35 motherboard, where they are going to wring every fraction of a penny out of the manufacturing cost, my sense is that we probably have many years left before they disappear from the earth.
There are a couple of projects I know of in this vein: RepRap uses drip-fed G-Code for its main control chain, and as I understand, there are some issues with the interpretation of arcs that have yet to be addressed; they may not be problematic for RepRap’s own use. There’s another, seemingly more sophisticated effort in the GRBL Project, which uses optimized AVR-native C code to turn an Arduino into a proper interpreter. However, it can’t do trajectory planning, homing, or spindle control, let alone threading, rigid tapping or control of auxiliary mechanisms. Like most open-source projects, it’s the pet project of one or two guys, and with no updates to the website since this past summer, it’s quite likely it’s reached the end of its evolution.
Part of the reason why I feel compelled to rain all over this idea is that the open-source CNC community is tiny and yet has plenty of overlapping and duplicative projects underway. In the past year, we’ve seen two separate groups of people launch new GUIs for EMC. One of them, Touchy, doesn’t provide a toolpath preview, and according to the author, there’s no plans to add it, presumably because he doesn’t want it. The other, Mocca, has all that and more, but is built in OpenLazlo, which one commenter memorably referred to as a “bizarre moon language,” virtually guaranteeing that no one but the original developers will ever touch it. Meanwhile, other people are finding ways to adapt Axis to use a touchscreen despite it being a mess of spaghetti code even the original developers are reluctant to go near.
In fairness to all involved, they’re giving their efforts to the community freely, and one of the points of open source is precisely to enable individuals to scratch their own itches, their way. I’m not complaining. But fragmentation brings costs. HAL files of more than trivial complexity remain byzantine, and GUI customization remains largely an unfulfilled goal. A trip to the EMC forums or mailing list shows dozens of people trying to figure out how to get some part of their machine to work. Meanwhile, a trip to the Mach forums finds hundreds of people writing macros, wizards, or screen layouts. It makes one wonder if the vision of openness and flexibility has it all backwards.
Now it’s true that above a certain level, Mach doesn’t cut it. If you happen to have some seriously large iron around with a dead control, it’s EMC or something far more costly than a Mach license. And there is the little bit of uncertainty that Windows will cause your machine to have a “senior moment” once every so often–while EMC seems rock-solid. But these points are arguing over the area between the 99th and 100th percentiles, when large gaps remain between 50 and 75.
I’ve had numerous people ask me about why I chose the Arduino when there are “better” options available that have more IO pins, true USB, better CPU speed, etc. The simple reason is that Arduino is far and away the most widely-known, used, and supported platform out there, and platforms have enormous value beyond the stuff that fits on a spec sheet. Pretty much the entire history of the PC is a story of platforms beating technologies, and I am not going to fight that.
Likewise, while I do intend to commercialize this project in the form of PCBs, kits, or instructional DVDs, I’d rather capture 10% of several thousand users than 90% of a hundred or so. My biggest marketing problem is going to be to get people to notice, and if the cost of doing that is helping 90% of people to do it for free, I still think the remaining 10% will more than make up.
One of the things that still sets “real” CNC machines apart from DIY conversions (apart from the thousands of pounds of cast iron, spindles with more torque than a small car, etc.) is the use of dedicated control panels. Bob Warfield’s site has a great page showing a number of panels from manufacturers like Fanuc along with some very impressive homebrew solutions. Besides giving direct access to frequently-used functions, these panels also provide a more natural feel, especially for semi-manual operations, which are especially common in home shops.
Despite their utility, the vast majority of hobbyists seem to get by with mouse and keyboard-based control. There are a variety of commercial solutions available, but they’re generally not cheap. Moreover, interfacing them to the PC tends to be messy. The easiest way to do it is through the parallel port, but you run out of pins really fast. I/O cards can give you a lot more pins to play with, but they add further cost and complexity.
Enter the Arduino open-source microcontroller board. For about $30 you get a powerful, complete, easy-to-program platform with 16 I/O pins and a serial-over-USB interface to any PC. This looked like a perfect solution, and Jeff Epler, one of the main developers behind the Axis GUI, had published a demo project proving that it could be done. But while it got a lot of people excited, it didn’t seem to lead to much else: I don’t recall seeing a single post or email on the list about Arduino-based human-machine interfaces (HMI).
As I installed and ran Jeff’s code, I think I figured out why. It ran perfectly the first time, which is kind of a record for me, and got me excited too because this really proved that it worked. Lots of times people publish code that doesn’t quite compile, run, or function as it’s supposed to, and this was the sort of thing that had the potential to be quite finicky.
But while it ran exactly as described, Jeff’s code was an example of obfuscation through optimization: at every level from the firmware to the serial protocol to the Python-HAL interface, it did everything with such economy of code that it was quite difficult to make sense of, at least to a semi-engineer like myself. So rather than trying to extend Jeff’s code, I ended up starting over from scratch, writing something that is no doubt less efficient, but a lot easier for mere mortals like myself to work with. And the good news so far is that I think it’s efficient enough to get the job done.
The basic principles of the system are easy enough to understand, provided that you’re somewhat comfortable with how EMC configurations actually work:
- HAL Config: HAL provides a virtual breadboard of sorts that lets you map pins and signals to each other. Some of these are physical, i.e. you can wire the E-stop function to be triggered by Pin 10 on the Parallel port, but they can also map a signal (e.g. “turn flood coolant on”) to a virtual pin provided by another piece of software.In this case, I use the hal_postgui config file to wire up all the functions that the Ardunio-powered panel will talk with. If you’ve wired up an e-stop switch, it’s pretty much the same idea.
- Python-HAL User Module: HAL provides a mechanism for users to create their own modules in Python. These modules implement whatever functionality the user wants, and then expose that functionality via standard HAL pins and signals. There’s a Python script, which imports a “hal” library that allows the programmer to create HAL objects and declare the externally-visible inputs and outputs. If you’re a programmer, these can be thought of just like objects and method signatures. If you’re not, just think of it as a way for a custom program to talk with HAL in HAL’s native language.
In this application, the Python module is responsible for managing the serial communication layer on the PC. HAL signals get converted into serial messages which can be sent to the Arduino, while the Arduino’s serial messages get converted into HAL signals. In other words, HAL talks to the Python module and the Python module talks to the Arduino over the serial port, and vice-versa.
- The Arduino is responsible for taking serial messages and converting them to physical output signals, and for taking physical input signals and converting them into serial messages back to the PC.
When you get down to it, there’s virtually nothing going on here but translation from one layer to another, times three, and back the other way. It’s less computer science than computer plumbing, and I found more than a few idiosyncrasies along the way, particularly in getting the serial communications to work as needed.
While I may have seemed to be slagging Jeff’s code earlier for being too hard to understand, another factor is that getting this stuff working, from scratch, requires you to understand each layer (HAL-EMC, the Python user module, serial communication, and Arduino) somewhat well. Going into this I had a moderate amount of experience with the Arduino environment and have written quite a bit of software for a living, but the rest was a mystery to me, and it took a couple dozen sessions of banging my head against every available wall before I got most of it working.
While I’ll be documenting and publishing my source code in more detail, for those immediately interested in trying this out, here’s my cheat sheet for getting into it:
- Get comfortable with the Arduino environment and libraries.
- Get comfortable with basic Python (it’s easy if you’ve used Java, PHP, or Ruby before), and particularly the PySerial library. One of the trickiest parts for me was understanding how to send structured data over the serial line; it’s a VERY low-level protocol compared to anything remotely modern. The best way (I think) is to structure everything as fixed-length messages along the lines of this example. Before you try to talk with EMC, write a Python program that sends and receives messages from the Arduino. Once you’ve got that working, you’re about 80% of the way there.
- Work through the HAL Advanced Tutorial first, then do the Creating Userspace Python Components tutorial.
Once I got the basic pieces working, I began working towards a more complete system, including an encoder for jogging, a 25-key keypad, and a 20×4 LCD. While the Arduino only has 16 usable I/O pins, I was able to fit 25 keys in by using a matrix scanning approach, just as you would with an LED matrix. While you could step up to an Arduino Mega and get a lot more I/O pins, I wanted to keep the initial version cheap and accessible for those who already had an Arduino on hand.
I initially chose to use the LCD partly for the heck of it, as I happened to have one in my parts pile, but also because it created a lot of opportunity for powerful display features. With just 6 digital pins, I got the ability to display darn near anything that could be rendered as text. Part of me would have liked to have physical LEDs right on the keypad for certain things (like designating the active axis for manual jogging), but I’ve found ways to display it on the LCD that I think are pretty good. On the flip side, it’s allowed me to create a remote display of a number of things that I think will be quite useful, especially if your main monitor is not right next to your machine. In the long run, I think this will provide a lot more upside than the regular LEDs would.
About three years ago I was hit by a sudden and overwhelming urge to start building stuff again. Growing up, my favorite part of the house was the garage, from which it seemed almost anything could emerge. But college and the career path that followed took me to Boston, where garages have attendants and apartments have neighbors who don’t necessarily take kindly to soldering on the kitchen table or bandsawing a few pieces of 2″ 6061 round bar.
Along the way I started a software company, now in its 6th year, and eventually ended up in an apartment building whose owner thought it was perfectly reasonable for me to rent a piece of the basement to use as a shop. There’s no 220V service, the ceiling is under 6′, and the only way to get anything in is to carry it down a narrow flight of stairs, but it was more than enough to get a benchtop mill and lathe and start causing real trouble. I quickly discovered the home-shop CNC community, and now have a CNC’d X2 mill, 7×10 lathe, and two smaller scratch-built routers (the Brute and 7th Sojourn) based on John Kleinbauer’s excellent plans.
As an entrepreneur, I think the small-scale CNC space is still in a fascinatingly early phase of its development. As in other areas, the Internet has made a wealth of information available to interested amateurs, who are routinely doing things considered state of the art not all that long ago. At the same time, there are a couple of feelings/suspicions I cannot shake:
- Many, perhaps most DIY builds fail: Following threads on CNCZone, I get the sense that a very large number of people who start DIY CNC projects never finish them. While this is probably true of every hobby, DIY CNC faces some steep challenges. Even the prosumer turnkey machines like Tormach leave you largely on your own to integrate the control system with Mach or EMC. Between the mechanical, electromechanical, electronic, and software layers, there’s an enormous amount to do and a lot that can go wrong.
- Of those that succeed, many (most?) gather dust: As complex as building a machine is, it’s still only a ticket to the world of CAD/CAM. My father jokes about guys who buy $10,000 table saws and build nothing but birdhouses to test how well-aligned their fence is. For a lot of guys, building the machine is the hobby, and that’s fine. But, I think a lot of the lack of useful output is due to the fact that these machines are just not at all easy to use.
In just the past few years, we’ve seen a number of great new options addressing the first point. At the high end, there are more choices in turnkey machines under $10k than ever before (a product category that didn’t really exist 10 years ago), while the number of proven plansets and suppliers for the 100% homebrew crowd grows even faster. For the most popular machines and designs, there are known-good paths that builders can follow with high assurance of success.
The software side, though, still feels deeply problematic to me. As I’m more of a software guy than anything else, this is where I’ll be focusing my attention.