CNC Mini Mill #11: A little more work on the air spring

It seems like every time I conclude with saying the mill is now operational, I realize there’s something else I want to improve.

After making the new air spring bracket, I finally wanted to fix the air spring scraping against the inside of the column. This would require making a new bottom mount for it, so it’s spaced further out from the inside of the column.

It’s not a complicated part, but I’ve had other stuff going on (more posts on that soon) so it took me a while to get to it. Here it is:

The new air spring mount, mounted on the air spring piston. The black steel one is the original.

The new air spring mount, mounted on the air spring piston. The black steel one is the original.

The new mount puts the bottom of the air spring directly under the link on top, which moved when I switched to the bracket I made, so it should now be completely vertical. It’s also far enough from the inside of the column that it doesn’t touch. It’s also taller to provide more support for the twisting action, now that the air spring is attached further out from the wall.

Maybe now I can start making non-mill-related things…

 

CNC Mini Mill #10: A better air spring bracket, and some tweaks

As I mentioned in the last post, one of the things I wanted to make was an improved bracket for the air spring that takes some of the weight of the spindle. The stock bracket is a ~300mm long, 10mm diameter steel rod, mounted with two M6 screws on the side of the spindle, threaded into another steel rod at 90 degree angle at the top. This is attached to the top of the air spring, which is the damped kind typically used for trunk lids on cars. The force of the spring and its damper when the Z-axis moved up and down is substantial, so this assembly flexes back and forth and has already been permanently bent. I figured it would be simple to make a beefier one out of a piece of 6061 bar.

This was the first machining project that would use the CNC-controlled coolant and spindle, so the first thing I discovered was that the spindle RPM control worked fine until I turned the stepper motors on. Then the spindle started erratically speeding up and slowing down. The oscilloscope showed substantial noise on the PWM signal from the TinyG when the motors were powered, so I figured this was the same problem I had with the limit switches. A low-pass filter was needed.

Luckily I had de-soldered a resistor from the input voltage divider on the CNC control board, so all I had to do was add a 0.5uF capacitor on that pad. In combination with the in-line 1k resistor that was already there, this would make a low-pass filter with a 1us time constant. That’s about equal to a single timer tick on the Atmega8A that’s measuring the PWM signal, so that should not give appreciable distortion to the pulse widths.

The back side of the spindle control board. The capacitor added to make the low-pass filter is marked "R2", right next to the jumper that connects the incoming PWM signal to the input capture pin.

The back side of the spindle control board. The capacitor added to make the low-pass filter is marked “R2”, right next to the jumper that connects the incoming PWM signal to the input capture pin.

With the capacitor added, the RPM control now works fine even when the motors are powered. Time to proceed with the bracket.

I had some trouble getting Fusion360 to do what I want when it came to the CAM setup. I was going to make it out of a 2″ x 0.75″ bar, and it needs to be about 360mm long. The biggest issue was that this is more than the maximum travel on the mill, so I had to figure out how to split the tool paths. As you will see, it’s a pretty simple part, though, so once I figured out how to do it, it wasn’t a big deal. It just means you have to reposition the part and re-set the zeropoint numerous times, which makes it more cumbersome.

Since the last post, I also mounted a LED ring that I got off ebay around the spindle. It’s 80mm diameter, which fits perfectly on the little plastic cover plate around the bottom of the spindle. Unless the endmill is very short, like a miniature, 1-2mm one, they are large enough in diameter to not have the spindle cast a shadow on the endmill.

The LED ring illuminates the area around the cut very well. In this picture there is a shadow from the spindle, but the spindle would be higher up unless the endmill is tiny.

The LED ring illuminates the area around the cut very well. In this picture there is a shadow from the spindle, but the spindle would be higher up unless the endmill is tiny.

This was the first time I used my G-wizard trial to calculate feeds and speeds for the “adaptive clearing” operations in Fusion 360. This creates toolpaths that have constant engagement, which means you can be a lot more aggressive on the feedrate since you know the tool won’t go into a corner and load up. G-wizard spit out a 1mm stepover and a feedrate of 1600 mm/min for the 2mm deep cut I was making. This was by far the most aggressive cut I’ve done, but it worked great. I made a short video of the operation:

That as about the only thing that went well though. The “Spra-Kool” coolant nozzle works, but it’s a but touchy on the adjustment. It’s easy to get no coolant at all or to drench the stock. It doesn’t even seem to be fully repeatable, sometimes it worked fine only to not have any coolant at all after it’s paused for a tool change. I also fat-fingered G-code when trying to set the zeropoint and snapped off my edgefinder. It was only $7, but still. Then I accidentally started milling the wrong side for the operation that was cutting the screw holes. Luckily two of the holes are symmetric and lined up perfectly even after the stock was flipped. The third hole was offset enough that the bad hole didn’t interfere with the good one. It just looks bad. This is how you learn things…

Here's the final part. The hole without the counterbore is the one I accidentally drilled by putting the stock wrong side up.

Here’s the final part. The hole without the counterbore is the one I accidentally drilled by putting the stock wrong side up.

I’m also pretty happy with how the Lexan chip shields are working out. It’s a bit of a pain to move them out of the way when working on the mill, but otherwise they do a great job of keeping the chips confined. And there were a lot of chips made here.

At the conclusion of the milling operation, the chip shields had held in quite a lot of chips. Without them, I'd be walking through that...

At the conclusion of the milling operation, the chip shields had held in quite a lot of chips. Without them, I’d be walking through that…

Luckily, that bracket fit perfectly. I could make it even better by making a new bottom mount for the air spring. The stock one mounts it a bit too close to the inner surface of the column so it’s not quite vertical. And I need to get an M10 bolt for the horizontal bar on top. The only thing I had that was threaded M10 was the original bracket, which works but looks pretty ridiculous since it’s 300mm long…

The new bracket in place. The horizontal bar at the top is now screwed in with the old bracket, which looks pretty ridiculous, but I didn't have an M10 bolt around.

The new bracket in place. The horizontal bar at the top is now screwed in with the old bracket. I didn’t have an M10 bolt around.

So I think that’s a success, even if there were some teachable moments along the way. I think the mill is pretty much operational now.

 

 

 

CNC Mini Mill #9: Spindle and coolant control

With the limit switches working, it was time to tackle the spindle control. The spindle is normally controlled with on/off switches and a speed knob on the spindle itself, but for CNC use it’s useful to have the ability to run the spindle from the G-code. I ordered a “CNC spindle control kit” with the mill, but didn’t touch it for a long time since there were more pressing things to fix.

The kit consists of a small circuit board and a PDIP28 IC that replaces the one in the motor controller. The IC turns out to be an Atmega8A, and there’s another one on the circuit board. The board is powered with 110V and has inputs for spindle on/off, direction, and speed. The instructions aren’t really clear on how the inputs are supposed to be driven, though, so the first step was to figure out how the board was wired.

It’s not a very complicated board, so there’s not that much going on. The 110V inputs go to a transformer, a full-wave rectifier, and then to an L7805 5V voltage regulator, providing 5V power.

There are 5 optocouplers on the board. Two are directly connected to the forward/reverse and on/off inputs, where sinking current will turn on the optocoupler. I looked up the datasheet for the optocouplers and the current will be about 10mA. This is too much to connect directly to an Arduino Due, but I knew this when I designed the shield so it has two MOSFETs to handle these. (There is also a third optocoupler connected to an input called “FLN” that is not described anywhere…)

The remaining two optocouplers are hooked up to the Tx/Rx lines on the Atmega8A, and the speed input to one of its AD converter pins through an adjustable voltage divider. The instructions say to adjust the pot until you get full speed, so clearly the speed input is an analog voltage. Apparently common boards like the Geckodrive G540 have an analog voltage output for this purpose, but this is not so good for hooking up to the TinyG sinc its spindle speed output is a 100Hz PWM signal with the duty cycle determined by the speed.

I could have attempted to low-pass filter the PWM signal to turn it into an analog voltage, but given how much noise there was in the limit switch lines I wasn’t convinced an analog input was the way to go. Instead, I figured I could just reprogram the Atmega8A, which is just a smaller version of the chips used in the Arduinos, to decode the PWM signal directly. Since that’s a digital signal, it’s much less susceptible to interference.

The problem was of course that this required me to reverse-engineer what the existing Atmega was sending over the serial line. By hooking the Tx line up to the oscilloscope and using the adjustable pot to shift the voltage on the input, I was hoping to figure out what it was doing.

It turns out it wasn’t that complicated. The serial protocol consists of sending  a 0x55, two 8-bit numbers, and then another 8-bit number that’s the sum of the two previous ones (presumably as a checksum). The two 8-bit numbers contain a 16-bit number between 0 and 1023 (coincidentally exactly the range of the 10-bit AD converter on the Atmega), where 0 is for 0 input voltage and 1023 is for 5V.

Hence, all I would need to do was program the Atmega to decode the duty cycle of the incoming PWM signal, turn it into a 10-bit number, and then send it over the serial port. Shouldn’t be a big problem. I was not able to pull the original program off the chip, it appears to be locked, but a new Atmega8A is $3.

The spindle control board from Littlemachineshop.com. The transformer has been replaced with the two white jumper cables. The 4 loose wires are for hooking up the SPI connectors to the AVR programmer.

The spindle control board from Littlemachineshop.com. The transformer has been replaced with the two white jumper cables. The 4 loose wires are for hooking up the SPI connectors to the AVR programmer.

As for the 110V input, that seemed unnecessarily complicated. Since the connections to the motor electronics all go through optocouplers, there’s no need to isolate this board. Instead, I can just use the 12V from the step-down controller on the Arduino shield and send that along with the inputs to power the Atmega8A on the board. So I de-soldered the transformer and jumped it with some wires. That way I can plug either of the 110V inputs to 12V and the rectifier will handle the polarity.

Programming the Atmega8A wasn’t difficult. The code is in the bitbucket repo if anyone wants to check it out. It uses the input capture interrupts to record the value of the 16-bit timer when the input switches value. Calculating the duty cycle is then simple: at every (say) positive edge, you calculate (now – last_negative_edge)/(now – last_positive_edge). It turns out to be extremely accurate – by sending S commands to TinyG I get exactly what I expect over the serial port, to the full 10 bit resolution. The most complicated thing is how to handle duty cycles of 0 or 1, since then there are no edges to detect. This is done with the timer overflow interrupt, such that if no edges have been seen for an entire timer overflow (32ms) it will just read the value of the input as either zero or one. The timer overflow also sets a lower limit on the PWM frequency that can be used of ~31Hz. Since TinyG uses 100Hz, that’s fine.

The one bug I’ve found is that for duty cycles very close to 0 or 1, there’s not enough time to record the timer value and switch the interrupt polarity before the next edge, so it ends up missing it and wraps around to the next cycle. The only manifestation of this is that if I command a spindle speed of 2499 rpm, I get something like 1250 (because it ends up calculating a duty cycle of 50%). 2500 works fine, as does 2498. I find it hard to believe I would ever use 2499 rpm, so I’m not too bothered by this. If it turns out to be necessary, it can be avoided by limiting the duty cycles to be between something like 0.01 and 0.99 rather than 0 and 1.

I mounted the spindle control board in the box with the other spindle electronics at the back of the mill and ran a 6-part shielded wire to the stepper control box.

The motor control box with the CNC spindle control board mounted in the lower left.

The spindle motor electronics box on the back of the mill, with the CNC spindle control board mounted in the lower left.

The setup seems to work. I can turn the spindle on and off using the M3/M5 commands in TinyG and set the spindle speed. The spindle is advertised as 100rpm, but it actually runs slower than that. It’s not very usable, though, because the motion is quite uneven at such low speeds. It’s got a lot of torque, though. If you grab the spindle with your hands, it will slow down momentarily and then you can hear the motor current ramping up and controlling back to the set speed. Then when you release, the spindle will speed up momentarily and then quickly ramp back. In any case, I limited the minimum speed to 100rpm in the TinyG settings.

One thing that doesn’t work is the forward/reverse setting. I think this is just that it’s not enabled in TinyG, but since I’m not sure why I would want to run the spindle backwards anyway I haven’t looked into it yet.

While I was at it, I finally made a wire for the coolant solenoid and hooked it up, too. That also works, so now there’s both working coolant and spindle control. Check it out:

I think that actually completes all the necessary mill setup. Wohoo! Time to make something. I want to make a better mounting bracket for the air spring, the standard one flexes all over the place, so I think that’s going to come next.

Checklist for using the spindle control board with TinyG

In case there’s anyone else out there that wants to use this spindle control board and feed it PWM from TinyG, here’s the full list of things I did:

  • De-solder the transformer and add jumper wires as shown in the picture above, if you want to run it with DC rather than 110VAC.
  • On the back of the board, remove the 5k resistor marked “R2”. This resistor attenuates the input signal too much.
  • Solder a jumper between pin 14 on the Atmega and the pad of the resistor you just removed. (The pad connected to the adjacent 1k resistor, not the ground pad, that is.)
  • Adjust the pot with 5V on the VFD input so that the voltage on the Atmega input capture pin 14 is as large as possible. It will end up being around 4V. This is sufficiently large to be reliably read as a one. (If it wasn’t, the pot would have to be desoldered too, but no point in making unnecessary damage.)
  • Order a new Atmega8A from mouser.
  • To program it, you’ll need something like the AVR pocket programmer. The procedure is the same as that described in the Xbee wireless bootloading How-To.
  • You’ll also need a way to connect the programmer to the SPI pins, like the soldered leads in the picture.
  • The spindle control board contains a 16MHz crystal, so program the fuse bits to be 0xff/0xc9 for the low and high bits, respectively.
  • Clone my arduino library on bitbucket and build the “spindlecontrol” project by running make in that directory. (You’ll need a working avr-gcc environment for this to work.)
  • Program the Atmega with the generated hex file using avrdude. This will be something like “avrdude -p m8 -c usbtiny  -U flash:w:build-cli/spindlecontrol.hex:i”.
  • If you now hook up a TTL serial receiver like Sparkfun’s FT232 breakout board to the Tx output on the Atmega you should see it sending a repeated string of 0x55 0x00 0x00 0x00 when the VFD input is disconnected and 0x55 0x03 0xff 0x02 when it’s connected to 5V. The easiest way to make the connection is with female headers to the 10-pin connector. Hook 5V to pin 10, ground to pin 1, and the Rx on the receiver to pin 9.
  • Follow the instruction that came with the kit for replacing the IC on the motor board and hooking it to the spindle control board with the supplied 10-pin cable.
  • Now you can hook the spindle control board to the TinyG (or any other motion controller that provides PWM output, like grbl.) Just remember that the on/off and forward/reverse inputs require sinking 10mA to turn them on. Make sure whatever you’re connecting them to can handle this.

 

CNC Mini Mill #8: Limit switches

One of the remaining things to hook up to the mill were the limit switches. This has taken forever, but I was waiting on some shielded 2-conductor wire I ordered on ebay. It arrived a few days before Christmas, so now it was time to check that item off the list.

I briefly talked about mounting the Y and Z switches back in part 4. The X switch was a bit more tricky and that had to wait until the X-axis ballscrew alignment issue was fixed.

The Y-axis limit switch is on the right, mounted on a small piece of aluminum angle. An M2.5 screw on the saddle makes the trigger point adjustable. The X-axis switch on the left is a roller switch left over from the ShapeOko. I made a cutout in the X-axis motor mount so the limit switch can act against the saddle. Without this cutout, the switch would trigger against the base of the mill, where the point of contact would depend on the position of the Y axis.

The Y-axis limit switch is on the right, mounted on a small piece of aluminum angle. An M2.5 screw on the saddle makes the trigger point adjustable. The X-axis switch on the left is a roller switch left over from the ShapeOko. I made a cutout in the X-axis motor mount so the limit switch can act against the saddle. Without this cutout, the switch would trigger against the base of the mill, where the point of contact would depend on the position of the Y axis.

In order for the X-axis switch to trigger on a consistent point, it has to touch the saddle. For this to be possible, the X-axis motor mount had to have a slot cut into it. Similarly to how I worked on the Y-axis motor mount, this was accomplished with another episode of “2D milling”, with the mill X-axis locked.

With the X-axis taken care of, all three switches were operational and ready to be wired up. The back panel on the electronics box needed to have another hole cut into it for the new connectors, and I milled the panel mount cutouts for the Micro-Fit 3.0 connectors from a design in Fusion360. This was a lot better than the ones for the stepper motors that I did manually. The cutout in the box was still done manually, and it shows…

The 5 new Micro-Fit connectors in the back panel. The three on top are for the XYZ limit switches, the two on the bottom for the coolant solenoid and general 12V supply.

The 5 new Micro-Fit connectors in the back panel. The three on top are for the XYZ limit switches, the two on the bottom for the coolant solenoid and general 12V supply. There’s a spare hole, too.

The internal wiring for the limit switches was pretty easy, a single piece of ribbon cable between the limit switch connector on the Arduino shield and the three 2-wire connectors on the back.

With the limit switches and the wires to the coolant and 12V connectors done, the internal wiring of the electronics box should be complete.

With the limit switches and the wires to the coolant and 12V connectors done, the internal wiring of the electronics box should be complete.

When I hooked up the switches for testing, however, they did not really work. I had not bothered to add any filtering to the switch lines on the circuit board, but hooking up the switch inputs to the oscilloscope showed that whenever the motors were energized, there was over a Volt of induced noise on the line. There were also severe contact bounces. Finally, the inputs use the 3.3V internal pull-up resistors on the Arduino, which on the Due are 100k Ohm. This does not make a very strong pull-up.

Reading a bit on the web showed that people seemed to be happy with limit switch performance using external, 330Ohm pull-up resistors and a RC low-pass filter consisting of a 10k resistor and 0.1uF ceramic capacitor. This gives a filter time constant of  1m, plenty fast for what we need but still much longer than the frequencies of the noise features.

The problem was of course how to add those components… It took a little soldering gymnastics, but they are now ghetto-hacked onto the back of the circuit board. That shield is getting pretty crowded with deadbugged components and jumpers. (At least version 2 of the circuit board, if one is ever ordered, will have all these issues fixed…)

With the noise filters, the switches perform flawlessly. I have also enabled the TinyG soft limits, so after running a homing cycle, it now refuses to perform moves that it knows will run into the end stops, which is nice. That has definitely happened too often, from mistyping commands. Of course, this only works with the fixed end stops, not for running the Z-axis down into the table or crashing the end mill into the vice, so caution is still necessary.

The movie below shows a G28.2 homing cycle with TinyG.

 

CNC Mini Mill #7: Another kind of shield

After talking about the ill-fated Arduino shields, here’s something more pedestrian. Whenever I’ve used the mill, I get chips everywhere and they get dragged into the house. It also feels a bit sketchy using the Superfly cutter without any kind of protection, since if the insert holder were to come loose it would go flying off at high enough velocity to give someone a bad day. So I went down to Home Depot, got a sheet of Lexan, and made a chip shield:

The Lexan chip shield.

The Lexan chip shield.

It’s pretty simple, I reused some aluminum angle left over from the storage rack and screwed the Lexan to it. It’s a pretty amazing material, only about 2mm thick but super strong and flexible. I’m pretty confident that anything coming off the mill will ricochet off that thing and not go through, because it’ll flex enough to absorb the kinetic energy of the projectile.

In case you are interested, I found this rather entertaining video demonstrating the difference between polycarbonate (Lexan) and acrylic on youtube:

I’ve tried the shield and it works very well, no chips are really thrown high enough to go over it. On the other hand, it is just a tad too tall for me to comfortably be able to change an endmill or move the stock around, and it’s kind of a pain to get out of the way when working on the mill. Maybe I can design something that lifts it out of place when not needed…

Oh, and I heard back from CNCFusion about the mismatched X-axis. They agree and are puzzled. It seems the most likely case is that the mill has been redesigned since they designed their kit, so they are going to ask some other customers if they see a similar mismatch.

CNC Mini Mill #6: The Arduino shield

In the post that talked about how I burned out the Arduino, I concluded with the need for a dedicated 48V-to-12V converter that would supply power to the Arduino but also to the coolant solenoid and various other things that might need 12V.

Unfortunately a switching buck converter is a bit more complicated than just wiring up an LM317, so it took me a little time to find a suitable component and then study the data sheet to come up with a design. I was going to use the LT1766 from Linear Technologies, but was having trouble getting clear guidance from their data sheet when I discovered that ST Electronics has a complete on-line design tool that allows you to input your specifications and pick components from a library. This was so user-friendly I just had to support them, so instead I ended up going with the L7987, a 61V 3A integrated regulator. 3A should be plenty (the air solenoid uses 0.5A).

With that design help, I started drawing the board in Eagle. I had two options, either make a small board just for the converter, or make a full-size shield for the Arduino Due. I decided to go with the second option, even though this would make the circuit board a lot more expensive, since that meant I could break out dedicated connectors for the motors, limit switches, LEDs, and so on. This would be a lot better than having anonymous headers where you have to remember what goes where. It would also save me the hassle of mounting a tiny board somewhere in the box.

Apart from the layout of the switching regulator, which is somewhat critical because of the high frequencies involved, it was a simple matter of just getting the correct TinyG pins wired to the various connectors. I wanted polarized connectors, so I got a bunch of Molex KK254 ones of various lengths.

With the design completed, it was just a matter of uploading it to OSH Park and wait. It was actually fairly quick, total turnaround from upload to getting the boards in the mail was less than two weeks. I also got a new Arduino Due from “SainSmart”. The solder job on it looked a lot better than the one on the $15 “Chinarduino” even if it was eight bucks more. The circuit boards cost something like $30 for 3 and are really high quality.

Here's the black "SainSmart" Arduino Due clone along with the purple PCB for the shield from OSH Park.

Here’s the black “SainSmart” Arduino Due clone along with the purple PCB for the shield from OSH Park.

I’ve hand soldered surface-mount components before, but the L7987 would be a new challenge. Like most of the voltage converters that can handle reasonably high currents, it has a large exposed pad on the bottom that needs to be soldered to a ground plane for heat dissipation. This presents somewhat of a problem for hand soldering since you can’t get to it. They’re meant to be reflow-soldered where solder paste is applied to the pads and the whole board then heated up so the solder paste melts. This takes some specialized equipment, but apparently it’s possible to do with the help of a hot air gun and an IR thermometer, too. So I decided to go for it.

First step is to tin the pads where the L7987 is supposed to go. The large square is the thermal pad that connects to the PCB ground plane on the opposite side of the board through the large numbers of vias on either side. The more connections to the back side, the better the thermal conductivity.

First step is to tin the pads where the L7987 is supposed to go. The large square is the thermal pad that connects to the PCB ground plane on the opposite side of the board through the large numbers of vias on either side. The more connections to the back side, the better the thermal conductivity.

After tinning the pads, I applied flux and carefully placed the chip on the board and started heating. The recommended heat profile is something like 1-2 minutes at 150C (to pre-heat the components) and then 30-60 seconds to go up to 260C and back down to 150C, so with the IR thermometer and a timer, I adjusted the distance of the hot air gun to keep the board at the recommended temperature. After the pre-heat, I went in and focused the heat on the chip until I got up to 260C+, and then quickly back down again. It actually worked really well.

This is the L7987 after the hot air gun session. It worked really well. Note that the tin on the vias have also flowed into them, which should improve the thermal conductivity further.

This is the L7987 after the hot air gun session. It worked really well. Note that the tin on the vias have also flowed into them, which should improve the thermal conductivity further. For reference, the size of the chip is about 5mm square.

With the hardest part done, it was just a matter of putting all the remaining components in place, not hard but somewhat time consuming. I hit a small snafu when I realized that I had neglected to get a 0.1uF capacitor (for “CBOOT” in the picture above). I have a bunch of 0.1uF caps but they are 25V and I realized (luckily before trying it) that those caps see the full input voltage, so the completion of the circuit was put on hold until I could get a few 100V ones from Mouser.

Another small snafu was that I realized I couldn’t hand solder the big 47uH inductor either, so I had to pull out the hot air gun once more. This was a bit more tricky because the inductor has so much mass that it heated up much more slowly than the rest of the board, but I got that done without overheating the rest of the board, too.

This is the completed shield along with the Arduino.

This is the completed shield along with the Arduino. All the white KK254 connectors and their pins are labeled. I didn’t bother soldering in the connectors for motors 4-6 now, since I’m not going to use them.

The shield has a DC plug for the 48V input. In the interest of circuit protection, it also has a 4A polyfuse (the big brown disk) and a 16V Zener diode. In case the converter malfunctions and shorts the input to the output, the zener will shunt the excess voltage to ground and the polyfuse will interrupt the circuit (hopefully fast enough that the zener diode doesn’t vaporize…). The 12V output from the converter feeds the coolant output, an always-on 12V power out, and the Arduino through the Vin pin.

One thing I realized I forgot to put in the schematic was a blocking diode that prevents power from backfeeding from the Arduino into the shield if the Arduino is powered but the shield is not. I hacked this in by cutting the trace to the Vin pin and soldering a diode between the pins on the back of the board.

After the previous mishap, it was with some trepidation that I powered up the voltage converter, but it seems to work perfectly well. I haven’t really tried to pull the full 3A out of it yet, but it did 1A from a 30V input with essentially perfect regulation. Hooked up to the full 48V input, it still worked perfectly.

Eager to test it out, I mounted the shield to the new Arduino and wired up the new motor connections. It sure looks a lot better than before. That’s when things went south.

If you look at the pictures above, you will notice that both the shield and the Arduino have a DC power connector… Clearly the 48V supply is supposed to be plugged into the voltage converter on the shield, not the 16V max Arduino power input. However, that’s exactly what I, in what can not be described as anything but a brief lapse of brain function, did. Hence, when the power was turned on, there was yet another puff of smoke and the voltage regulator on the brand new Arduino was history.

I don’t know how to explain this. All I can say is that after a full day of working on a bunch of different things I did not follow the rule of “always double check the power connections before turning power on”. Oh well, these are the kinds of mistakes that make you learn. Hopefully. At least I had added that blocking diode on the shield so the 48V didn’t backfeed to those circuits. I don’t think that 16V Zener would have been too happy about that with no polyfuse to protect it.

Amazingly, this Arduino seems to have survived, too. They’re apparently more rugged than you give them credit for. The voltage regulator is toast, but I’ll get a new one and solder it back in. One trace was burned off, too, so I’ll have to make a little jumper. Maybe it’ll be fine.

But just in case, I have yet another Arduino on order. Let’s hope that’s the last.

P.S. As I mentioned, I got three circuit boards. I don’t anticipate needing more than one, so if someone else is wiring up a TinyG motor controller and wants one of these shields, let me know.

 

CNC Mini Mill #5: Correcting the X-axis

In the previous post I talked about how the mount for the X-axis stepper motor in the CNCFusion kit didn’t line up the motor with the ballscrew axis. I realized that the clearest way of showing this was to bolt the motor mount directly to the thrust bearing mount. Any misalignment should then be obvious.

This is the blue thrust bearing plate screwed directly onto the aluminum stepper motor mounting plate. Apologies for the out of focus picture.

This is the blue thrust bearing plate screwed directly onto the aluminum stepper motor mounting plate. Apologies for the out of focus picture.

This is the view from the opposite end, down the ballscrew axis. It's obvious that the location of the thrust bearing in the back is not concentric with the stepper motor cutout in the front piece.

This is the view from the opposite end, down the ballscrew axis. It’s obvious that the location of the thrust bearing in the back is not concentric with the stepper motor cutout in the front piece.

As is obvious from the above view, there is a considerable misalignment. The CNCFusion plate mounts the motor too far to the back (left in the picture) and too far down. By measuring the location of the ballscrew axis relative to the bolt holes in the two pieces, I ended up with a mismatch of 2.6mm horizontally and 1.8mm vertically. Machining a new mount from scratch would be a big deal, it’s made out of a large chunk of solid aluminum. Instead, I designed a plate that would bolt onto the CNCFusion plate and move the motor the required amount. (Luckily the ballscrew is long enough that moving the motor back by up to ~10mm isn’t a problem, in the normal position both the motor shaft and the ballscrew are mounted very far into the coupler.)

This is the motor adapter plate design in Fusion360. The countersunk screws bolt into the holes for the motor in the original plate. The rotated set of holes, concentric with the machined hole, are for the new motor bolts.

This is the motor adapter plate design in Fusion360. The countersunk screws bolt into the holes for the motor in the original plate. The rotated set of holes, concentric with the machined hole, are threaded and for holding the motor in its  new position. To avoid interference between the sets of holes, the new holes are rotated by 20 degrees. 

 

So, the first real machining project would be this plate. It’s made out of 3/8″ aluminum, and nothing too advanced. The external dimensions don’t really matter, so I faced the bar stock and squared the sides “manually” by typing G-code. Then I could clamp the piece and do all the holes in one shot, so there wouldn’t be any mismatch in their locations.

It all went pretty well, although it was a learning experience. I had to rerun the code for the countersunk holes a second time because the first time didn’t go well. First, I had designed them too small. Second, the 1/8″ endmill I used the first time didn’t sound good, so the second time I used a 3/16″ one instead. It’s possible I just pushed it too hard.

Drilling the holes was also an interesting experience. When you program the drill cycles, you have to specify how fast the mill should lower the drill. When you drill manually, you just sort of add a certain amount of pressure and the drill goes as fast as it wants, and I didn’t really have any reference for how fast to make the move. I think I made it too fast, because I ended up pushing the drill bit into the chuck, so the holes gradually became shallower and shallower. I had to manually drill them out at the end.

But the end result was a very usable piece. I made a short video of the process:

 

This is the finished product. It actually looks like the design!

This is the finished product. It actually looks like the design!

Apart from finishing up drilling the holes and tapping the holes for the four screws holding the motor, I also had to enlarge the large hole for the motor flange a bit. I’m still a novice at this, so when I looked up the dimensions of a NEMA23 stepper motor, I input the size of the motor flange. Of course, the hole needs to be a bit larger than this for the pieces to fit together without interference, but I didn’t think of this. After a little sanding, though, the motor slipped into place.

The adapter plate mounted on the X-axis. Its hard to see in the picture, but the motor mount is now much more concentric with the ball screw.

The adapter plate mounted on the X-axis. It’s hard to see in the picture, but the motor mount is now much more concentric with the ball screw.

The motor mounted on the new plate. Unlike before, the motor shaft now slipped right on the coupler and the flange slid into the hole, indicating that theres now very little side force.

The motor mounted on the new plate. Unlike before, the motor shaft now slipped right on the coupler and the flange slid into the hole, indicating that there’s now very little side force.

With the motor mounted on the new plate, I could slide it right onto the coupling. I then loosened the thrust bearing and re-tightened it, so the ballscrew was aligned with the line from thrust bearing to motor. Unlike before however, I could now spin the ballscrew without getting any wobble in the ball nut.

After readjusting the gibs and tightening the ballnut down to the table, I can now run the X-axis back and forth without feeling any binding at all. I think this fix was a success!

(I still haven’t heard back from CNCFusion about whether they agree this is a mistake in their kit.)

CNC Mini Mill #4: Small tweaks

In the previous posts I described the electronics box and motion controller. (Newsflash: The Arduino Due survived! There was only a shorted input capacitor. When I removed that, it worked again, and I so far haven’t found anything that’s really broken. Amazing, dodged another bullet there.)

This post will focus on the physical mill setup. There were a few things I wanted to add, like limit switches and add a rubber chip guard for the Z-axis way and ball screw, and some things that needed checking, like tramming the column and measuring backlash. There were a couple of instances where the ball nuts contacted the table, so that needed to be fixed. And then of course figuring out what the rather severe wobble in the X-axis ballscrew shown in the video in the first post comes from.

So, in no particular order:

Tramming the column

Tramming is the adjustment of the mill Z-axis to be normal to the table, so the Z-axis motion and the axis of the spindle is perpendicular to the X-Y motion. You measure this offset by putting a dial indicator in the spindle, offset radially from the spindle axis, and then checking that the measurement in one direction and in the opposite direction are the same. Any “lean” to the spindle will show up as a difference here, and then you adjust the column until the readings are the same (and you do this in both axes). The column is bolted onto the base, so the way to adjust it is by adding shims around the bolts.

This is where the column mounts to the base. By adding shims to the four points where it is bolted in, it can be adjusted to be perpendicular.

This is where the column mounts to the base. By adding shims to the four points where it is bolted in, it can be adjusted to be perpendicular.

I had noticed when taking the column off before that it did not contact the base at all 4 points, but wiggled ever so slightly when the bolts were loosened. The space, measured with a blade gauge, was about 0.025mm, not much but noticeable. Initial measurements of the deviation from perpendicular was quite severe, at 0.6mm over about 300mm in the X-direction and 0.16mm over 150mm in the Y. After calculating the proper shim thickness that would take this tilt out (and make all 4 bolt points touch at the same time), I cut them out of the steel shim stock I got from Amazon and put them around the bolts.

This is one of the shims, this one 0.1mm thick. The slot is so it can go in around the bolt and support it on both sides.

This is one of the shims, this one 0.1mm thick. The slot is so it can go in around the bolt and support it on both sides.

After tightening the bolts back, the difference was much smaller, 0.015mm/dm in X and 0.025mm/dm in Y. This is less than a hundredth of a degree in angle, and it’s also less than the amount the colum flexes when I push and pull on it, so it seems kind of pointless to try to do better.

Another thing I learned by running the table back and forth with the dial indicator still mounted was that the table is slightly bowed, the center is about 0.05-0.1mm higher in the middle than at the ends (depending on which direction you measure.)

Backlash

Backlash is the amount of play in the mechanism that leads to “lost motion” when you change direction. If you go in the same direction, you don’t notice this because it’s always to the same side. This means that if you command the table to move by 1mm in the same direction you moved previously, it will move very close to 1mm. If you now try to go back by 1mm, though, you don’t quite get back to where you started, because the play in the mechanism is now to the other side. This makes the position of the mill slightly dependent on how you got there, which affects the precision of your cuts.

The backlash mostly comes from play in the ball nuts and in the thrust bearings that hold the ball screws. When ordering the ball screws, there’s an option to have them be loaded with as-large balls as possible, which takes up most of the play. I ordered this option. To really get to zero backlash, you need preloaded ballnuts (which basically consists of two ballnuts that are locked together but such that they push in opposite directions. These ballnuts are a lot more expensive than the regular ones, so that seemed a bit excessive.

I believe the play in the thrust bearings is negligible compared to the ball nuts, because all bearings have two races that are preloaded against each other. If adjusted correctly, this should eliminate all the play.

Anyway, measuring this by running the axes back and forth, I concluded that my backlash is 0.02mm in the X, 0.05mm in the Y, and 0.06mm in the Z-axis. This is indeed less than the standard ball nuts are specified for, so I’m willing to believe that CNCFusion didn’t shaft me and indeed did match the ball sizes in the nuts. I guess we’ll see going forward if this is small enough to not affect the quality of the cuts.

X-axis ballscrew

I took the table off to see if I could trace the source of the wobble in the X-axis ballscrew, and the first thing I discovered was that the ball nut had been contacting the bottom of the table. To solve this, I just took out the Dremel and ground a small relief in the bottom of the table.

The X-axis ball nut had been contacting the table, so I gave it some more space by grinding off a small amount of material right above where it runs.

The X-axis ball nut had been contacting the table, so I gave it some more space by grinding off a small amount of material right above where it runs.

When I mounted the ball screw in the thrust bearing to see if it would wobble or if the ball nut contacted the table, I noticed that there’s something fishy going on with the CNCFusion parts. I mounted the ball screw in the thrust bearing (which is a stock mini mill part) and aligned it so it didn’t wobble when turned. Then I added shims to the thrust bearing mounting plate so the ballscrew was aligned with the center of the table. However, after doing this it didn’t align at all with the mounting plate for the stepper motor on the other end of the table.

Here the ball screw is aligned, to the very best of my ability, with the axis of the thrust bearing (on the opposite side of the ball screw shown here). This also makes the ball screw go very closely down the center of the table. However, the hole for the stepper motor in the   mounting plate on this side is plainly not lined up with the ball screw.

Here the ball screw is aligned, to the very best of my ability, with the axis of the thrust bearing (on the opposite side of the ball screw shown here). This also makes the ball screw go very closely down the center of the table. However, the hole for the stepper motor in the mounting plate on this side is plainly not lined up with the ball screw.

The offset is large, about 5mm laterally, and the motor mount also appears to be slightly offset in height with the axis of the thrust bearing.

This is the stepper motor mounting plate from the CNCFusion kit. It's obvious that the hole for the stepper motor  isn't in lined up with the center of the holes for the two M6 bolts that mount this plate to the table, but is offset to the side.

This is the stepper motor mounting plate from the CNCFusion kit. It’s obvious that the hole for the stepper motor isn’t in lined up with the center of the holes for the two M6 bolts that mount this plate to the table, but is offset to the side.

This appears to be a design error in the CNCFusion part, because the offset between the hole for the motor and the midpoint between the two M6 bolts is also visible in the pictures of the kit on the CNCFUsion web page.

This is disappointing, but I think it can be fixed by making an adapter plate that would mount on the outside of this one and offset the motor mount “back” to where it should be. The ball screw is long enough that adding a 1/4″ plate shouldn’t be an issue. I haven’t heard back from CNCFusion whether they agree that this is a mistake or not yet.

This actually explains the X-axis wobble, though. When I mounted the ball screw initially, I didn’t tighten the thrust bearing down until I had mounted the motor. Since this makes the entire ball screw “cocked” in the bearing, it will then wobble when turned. After realizing this, I tightened the thrust bearing first and then mounted the motor. This still pulls a bend in the ball screw, but it did eliminate most of the wobble. (However, the bend still means that it will bind when the ball nut is tightened to the saddle and the table run back and forth, so the real solution is to correct the motor position.)

Chip guards

The mill comes with two rubber flaps that cover the Y-axis ways and ball screws. There is nothing protecting the Z-axis from chips though, and when chips stuck on the ball screw get ingested by the ball nuts as they run over them, the bearing won’t move smoothly any more. If the chip is big enough, it can lock up completely, and it certainly won’t be good for the lifetime of the ballnuts either. Adding a chip guard seemed prudent.

Littlemachineshop.com sells extra rubber flaps, so I ordered one of those and mounted it between the bottom of the column and the spindle. I had to use some aluminum angles I had left over from the storage project to get it to fit properly, but the Z-axis is now almost completely protected.

The machine with the added Z-axis chip guard and improved attachment of the Y-axis ones.

The machine with the added Z-axis chip guard and improved attachment of the Y-axis ones.

The front Y-axis guard required a small revision of its mount, because it would bunch up and get stuck between the front of the table and the Y-axis stepper motor mounting plate. To fix this I used the mill for the first time (in “1D” mode since the Y-axis was disabled) and milled a large chamfer in the motor mount plate so the rubber flaps wouldn’t get stuck as easily.

The "1D milling" down of the Y-axis motor mounting plate. Since I could do this by just running an endmill back and forth, I just locked the Y-axis gibs in place and typed G-code manually to run the table back and forth. A bit primitive, but it worked.

The “1D milling” down of the Y-axis motor mounting plate. Since I could do this by just running an endmill back and forth, I just locked the Y-axis gibs in place and typed G-code manually to run the table back and forth. A bit primitive, but it worked.

With the sharp corner removed and a slightly improved mounting arrangement, all rubber flaps now move smoothly and do not limit the range of motion of the machine.

Limit switches

Something that’s not entirely required but helpful is to have limit switches on each of the axes so the machine can establish where it is at boot. This isn’t really a requirement for using it, since you’ll normally line up the work coordinate system with the stock piece anyway, but the homing switches define the machine “absolute” coordinate system that TinyG uses for deciding whether a commanded move will run the axis into the end stops and stopping the move before the mechanical limits. Since I’ve accidentally run into the end stops several times already by mistyping G-code, this seems like a prudent thing to have.

Figuring out where to put the switches takes some thought. You want them to be located such that they’re out of the way, are attached to a fixed point on the machine (this avoids needing to deal with cable motion when moving), are somewhat adjustable, and only depend on the motion of a single axis. The Y and Z axes are pretty easy, since they move against a fixed part of the machine.

The Y-axis homing switch.

The Y-axis homing switch contacts the head of an Allen screw threaded into the saddle.

The Z-axis switch contacts the top of the head when it's in the highest position.

The Z-axis switch contacts the top of the head when it’s in the highest position.

I haven’t mounted the X-axis switch yet. I think I know where to put it, but until I get the X-axis motor mount fixed the table won’t move all the way in that direction because the coupler that mounts the stepper motor shaft to the ballscrew (the black, cylindrical piece at the end of the ballscrew in the pictures of the X-axis above) runs into the saddle. Once it’s all wired up and operational I’ll revisit this topic.

So that’s it for now, a bunch of small little things that hopefully will make the mill more usable and useful. I’m still waiting on the circuit board I designed for the 12V regulator/Arduino shield, that will probably be the next post.

 

The mini mill electronics box

The last post explained what the motion controller needs to do. This post will deal with the actual assembly of the electronics.

The G251X motor controllers can run up to 50V, and higher voltage makes higher speeds possible (you need the higher voltage to counter the back emf from the motors, which gets higher the faster they move) so most people recommend getting a 48V power supply. The motor controllers also need heat sinking, so I got a large aluminum case that should provide a sufficient heat sink if the motor controllers are mounted to them.

The guts of the electronics box. Front and center is the Arduino Due running TinyG, mounted to the case on the left are the motor controllers, in the back in the 48V power supply. In the upper right is the linear regulator supplying 12V to the Arduino.

The guts of the electronics box. Front and center is the Arduino Due running TinyG, mounted to the case on the left are the motor controllers, in the back in the 48V power supply. In the upper right is the linear regulator supplying 12V to the Arduino.

The G251X motor controllers can supply up to 3.5A to the motors, but the ones I got run on 2.7A so they aren’t even really being pushed. They still get plenty warm though. Interestingly, when I got them there was no thermal paste between the driver MOSFETs and the aluminum heat sink. In fact, some of them weren’t even making contact. I asked Geckodrive support if that was intentional and they basically said “it’ll be fine”. I thought that was strange because the instructions say that you must use thermal paste between the heatsink and the case when mounting them… I added some paste.

These are the three G251X motor controllers. They are mounted to a thick aluminum plate and then to the case for heatsinking.

These are the three G251X motor controllers. They are mounted to a thick aluminum plate and then to the case for heatsinking.

One drawback with the G251X controllers is that they have no protection circuits. If you short the motor outputs to each other or to ground, you’ll burn the MOSFETs. The instructions state this, so it was with great dismay I popped one of them when I attempted to measure the motor voltage on the oscilloscope and didn’t make the “connection” that the ground lead on the scope really is connected to ground… Luckily it was a simple matter de-soldering the bad RFD3055LE (it was shorted, so it was obvious which one it was) and replacing it with a new one from Mouser. That lesson could have turned out much more expensive than 60 cents!

I used MicroFit 3.0 connectors for the motors and spindle control. I have a whole set of them and they are good to 5A so that works well. The only problem is that you have to cut out a rather intricate shape in the panel to mount them. Luckily I have a new mill! I did this by hand-milling, before the CNC kit had arrived. Working with the 1/16″-per-turn hand wheels did require some mental exercise, but by the 4th connector I was pretty good at it… I’m not sad to see them go, though. The whole case is too large to fit in the mill, so I used a 1/8″ aluminum plate and milled the panel cutouts in it, and then just cut a large, square hole in the case and screwed it in place. It worked out OK, but the connector holes aren’t quite lined up because I took out the plate for inspection between holes.

The back side with the connectors for the motors and spindle controller. The spindle controller connector isn't mounted yet.

The back side with the connectors for the motors and spindle controller. The spindle controller connector isn’t mounted yet.

On the front side, I added some LEDs to show whether the motors and spindle are powered, as well as a lockout switch that prevents TinyG from starting the spindle so you can change tools etc without risk of getting your hand milled off. There’s also the USB connector so you can connect to the Arduino, and an emergency stop.

The front has three LEDs indicating whether the box has power, the motors are enabled, and the spindle is enabled. There is a spindle lockout switch that can be used to make sure the spindle doesn't start when you are changing tools. And then the emergency stop, which kills power to the whole box. And yes, I am cronically unable to put labels on straight...

The front has three LEDs indicating whether the box has power, the motors are enabled, and the spindle is enabled. There is a spindle lockout switch that can be used to make sure the spindle doesn’t start when you are changing tools. And then the emergency stop, which kills power to the whole box. And yes, I am cronically unable to put labels on straight…

So far everything was pretty straightforward. All I had to do was wire the motor outputs from the Arduino to the motor controllers, and I successfully could run the motors. The only small snag was that the “motor enable” input on the G251X is high for enabling the motors, but TinyG (which otherwise is quite configurable) has a fixed polarity of enabled-low for the enable outputs. I’m not the only one who ran into this problem, and I found suggestions for how to make this polarity configurable on the TinyG issue tracker. First win for open source solutions!

Of course, the Arduino needs power to run (it can take power from the USB cable, but you really don’t want it to die if the cable is unplugged) so I added a LM317 voltage regulator to convert the 48V from the power supply to the 12V that is the max input voltage to the Arduino. It really runs on 5V and 3.3V, but I wanted 12V to power the spindle and coolant outputs. Using a linear regulator like the LM317 to step down from 48V to 12V is hugely inefficient, but the Arduino doesn’t use much current so I bolted it to the case and it didn’t even get particularly warm.

However, I mentioned coolant. With the mill I got a little mist coolant sprayer that runs on pressurized air. For the Arduino to switch the coolant on and off, I ordered an air valve solenoid that runs on 12V. It’s a pretty small one, so it only uses 0.5A, but that’s a whole lot more than what the Arduino pulls. It’s switched with a MOSFET controlled by the coolant enable pin on the Arduino, but this is where things started going south. It worked fine, but pulling 0.5A through the LM317 would mean a power dissipation of (48V-12V)*0.5A = 18W. That’s a lot. When I issued the command to turn the coolant on to TinyG, the bottom of the case where the voltage regulator was mounted quickly became so hot I couldn’t touch it. This was not going to work.

The solution to inefficient linear regulators is of course: use a switching step-down converter instead. The problem is that actually requires a real circuit, and high switching frequencies means you can’t really hack it up on the Veroboard. You need a dedicated circuit board.

Then I remembered that I actually have an abandoned board with a MC33063 step-down controller that was a first edition for the fan control Arduino in my computer. I don’t remember why I abandoned it, but maybe I could re-purpose that circuit? After some measuring, troubleshooting, and substitution of components, I actually got it to work. The problem is that the max input voltage to the MC33063 is only 40V, so I’d still need the linear regulator. Oh well, stepping down from 48V to 39V is still a whole lot better than from 48V to 12V… Should work.

The ill-fated, repurposed buck controller board mounted on top of the LM317 sticking out to the left. Note the bulging top on the output capacitor on the right...

The ill-fated, repurposed buck controller board mounted on top of the LM317 sticking out to the left. Note the bulging top on the output capacitor on the right…

The picture above shows the buck converter board strapped to the top of the LM317. I tried the board on the bench power supply first, but it only goes to 30V, so I didn’t have a way of testing it at the full input voltage without actually hooking it up to the 48V supply. I did, and it seemed to work. The output was 11.7V, so I plugged it in to the Arduino and fired it up. No problems. Time to try switching the solenoid.

With the solenoid plugged in, I typed the command to turn it on. It seemed fine, so I typed the command to turn it off. A second later I was rewarded with a loud pop and a puff of smoke from the Arduino! What the?

I unplugged the regulator from the now-smelly Arduino and turned the power back on. Output voltage, 24V! That’s not right! A second later, another loud pop and the 16V output capacitor on the regulator board burst.

Sadness. I’m not sure what happened, but it appears the switch transistor in the MC33063 is now shorted. If that happens on a buck converter (see for example this schematic on Wikipedia), there is a direct connection from the input, through the inductor, to the output. Maybe I picked the 39V input too close to the 40V maximum. When the switch opens, the voltage across it will rise until the diode conducts, so perhaps that was enough to cause the switch to break down?

In any case, the Arduino is dead. Luckily the laptop USB port is OK, so it didn’t shoot the voltage out that way. I’m not sure about the motor controllers, since I have no way of testing them without the Arduino. I sure hope they’re OK, otherwise this lesson will turn out to be a lot more expensive than the 60-cent one earlier…

So it’s back to the drawing board here. A new Arduino is on order, and I’m going to design a real circuit board with the stepdown regulator, with over-voltage protection on the output this time, and add all the little circuits I needed for the coolant switch, spindle control (which I haven’t talked about yet, that’ll be another post). I’ll just make this board fit over the whole Due so I don’t have to deal with jumper cables to collect all the output pins. Less loose connections means less things to wire wrong. It’ll be better, but getting that board manufactured will set the project back quite a bit… Oh well, in the mean time I can work on mounting the limit switches.

The mini mill motion controller

The last post described the physical setup of the mini mill CNC conversion. Apart from adding motors to the mill, you also need something to control those motors. Most people seem to just get a G540 motor controller from Geckodrive and hook it up to the Mach3 CNC software. This seems to be a nice “turnkey” solution if you just want to get things up and running, but I didn’t go that way. Let’s back up a second and talk about what functionality is necessary here.

To run a CNC machine, you need a way of making it perform the precise moves necessary to mill the part. This requires some form of “language” for specifying motion, and the standard here is NRS-274, commonly known as “G-code” since most commands consist of the letter G and a number.

When you design the machining cycle with your CAM software, the output is a bunch of G-code instructions that describe the machine motion. So how do you make your machine perform according to those instructions? Stepper motors are controlled with motor controllers, like the G540 mentioned above, that translate step pulses into energizing the phase windings that make the motor turn. They are fundamentally position-commanded actuators; give the motor controller a pulse and it will move the motor one “step” in the specified direction. (Most motors have 200 steps per revolution.)

So, how do you go from G-code to motor pulses? Something needs to interpret the G-code, calculate the exact path the machine should follow, and then convert that path to a series of pulses. Note that this is a “hard-real time” task — the pulses need to arrive at the exact times necessary or the motors won’t move smoothly. If the jitter is too large, the motor may even miss steps, and at that point it’s game over since that means the controller no longer knows where the machine is.

Here’s where one of my big problems with Mach3 is: it runs on Windows and outputs the pulses through a parallel port. A PC desktop operating system is not a realtime OS, which means you are always at risk of having something else on the machine do something and screw up the realtime task.

Instead, this seems like a perfect task for a dedicated microcontroller. For the ShapeOko, I ran grbl on an Arduino. The microcontroller does nothing except calculate motor pulses, so there is no possibility of having something interfere with the real-time task. All the host computer has to do is send the G-code instructions through the serial port to the Arduino.

From using it with the ShapeOko, I know grbl has some disadvantages that made me less enthusiastic about using it for the mill. However, there is another Arduino-based G-code interpreter: TinyG. TinyG has a more advanced “constant-jerk” motion algorithm than grbl’s “constant-acceleration”, which makes the machine move more smoothly. It also controls all 6 axes (3 linear + 3 rotational) specified in G-code as opposed to grbl’s 3 linear ones. TinyG comes as a motor controller board+code package using an Arduino Mega, but there is also a port to the newer and more advanced 32-bit ARM Arduino Due. This looked like a promising alternative. Because I’m using stepper motors with higher current than the grblshield motor controllers on the TinyG board can handle, I wanted to use separate motor controllers anyway.

Finally, the other thing that made me decide on TinyG over Mach3 is that TinyG (and grbl, too) is open source, while Mach3 is commercial software. I’m really partial to a solution where I can fix things myself if they don’t work.

The only problem with this is that Mach3 also handles the user interface. TinyG and grbl are only motion controllers. You interact with them through G-code, which isn’t very intuitive. While this doesn’t matter much when running an actual job, things like moving the machine around, calibrating the coordinate systems, etc, are much easier to do (and less error prone) with an actual user interface rather than by typing G-code. There is a “web-based” thing called chilipeppr which seems half decent, but I haven’t used it enough to know how it will turn out. That is also, however, open source, so if something I really need is missing I can probably figure out how to add it.

This was meant to just be the introduction to the description of the electronics box, but it’s long enough I’ll end here and leave the box for the next post.