Once we added a crude but functioning third axis to our primordial CNC machine, we started testing it by running longer and longer G-code programs. Once we got to a test program that took roughly 25 minutes to complete, we encountered our first system failure: our computer running UGS (Universal G-code Sender) would lose its serial communication connection at unpredictable times.
As we intend to eventually run programs much longer than 25 minutes, this was unacceptable and UGS was removed from contention. We returned to the list of G-code senders in Grbl documentation and chose bCNC as our next candidate.
We are definitely giving up some nice features by moving from UGS to bCNC. We lose the ability to customize the arrangement of our control elements, and we lose the ability to preview our tool path from arbitrary directions. (We’re restricted to a few fixed projections.) But reliability is more important than eye candy, so we’re happy to give them up if it means a system that we can rely upon to run for hours.
To test bCNC, we take advantage of the fact this is an open loop system: the control board will run exactly the same whether it is attached to the salvaged industrial XY stage or not. This allowed me to run long duration tests using just the laptop and the prototype control board, away from the workshop where the machine hardware resides.
To establish our baseline: UGS is brought up to run this 25 minute test program again in the test configuration without hardware. Two attempts both failed with serial connection dropping offline at different times.
Then, using the same desktop test configuration, bCNC is brought up to run the same 25 minute test program. Five attempts ran to successful completion without losing serial connection.
Then we moved on to the challenge level: a G-code program that takes over 7 hours to execute. I would leave the laptop and prototype board running over most of a week. Every time I noticed the program had succeeded, I press “Cycle Start” again. This netted roughly ten attempts, and they were all successful. No serial connections were lost.
It looks like bCNC is the way to go. And with the new candidate software in place, attention returns to machine hardware.
We now have a three-axis machine: aged but still robust industrial motion control linear drives for our X and Y axis, and a new but not at all robust servo holding a Sharpie marker as our Z-axis. It was enough to let us feed three-axis G-code programs and watch them in action.
We started with short programs that would take less than a minute to run, then gradually increased the complexity and duration of jobs. If we wanted to turn this into a CNC mill, it will need to be reliable and dependable for long jobs. We didn’t have enough experience to have a list of potential points of failure, we just ran ever longer jobs and watched to see what goes wrong. We knew it was going to be a process of finding a problem, fixing it, finding the next thing to fail, fix that too, and repeat.
Our first problem: the G-code sender UGS running on the control console laptop. In the middle of running a job of approximately 15 minutes, UGS would drop serial connection. The machine stops moving and UI shows “OFF-LINE”. This is not just annoying, it is plainly unacceptable in a machine that might be expected to run for hours.
And there’s another possibly related problem with UGS serial communication: it was not able to connect to Grbl ESP32 if the dev board was connected at boot. We could work around this by unplugging the USB cable to ESP32 and reconnect, but this is rather inconvenient.
We could put up with the startup connection issue if that was the only problem, but randomly halting in the middle of a long job is unacceptable. So UGS is out of contention, and we return to the Grbl G-code sender list to find a replacement.
The next candidate: bCNC.
Soldering up components for a test run at the workshop, I ran out of time to implement something to actually attach to the end of the Z-axis servo. While I was setting up all the components with copious amounts of tape, I asked Emily for help. She has repeatedly demonstrated skill at creatively building a solution in very short time using whatever parts were on hand. The most important episode of this skill saving our bacon was when she fabricated a steering servo bracket for SGVHAK rover.
As I was focused on routing wires and taping them in place, I didn’t watch the magic happen first hand. But I was amazed when Emily walked up less than 15 minutes later with a bracket with parts clearly made of 3D printed plastic. There was not enough time to print such a thing… “How did you do that so fast?”
As it turned out, she drew from a box of rejected & failed 3D prints that was sitting in the back of the shop. The parts were not printed for this project, but their residence in the fail pile made them candidate raw material for today’s quick fabrication. Once Emily installed the Sharpie marker holder to our servo Z-axis, our plotter can lift its pen!
But as we found out very quickly, the lift is not clean. This cheap micro servo has a lot of slop which made it difficult to position it at a height that will make good contact with the paper when down and stay clear of the paper when lifting. Instead of ending a line cleanly, the pen would make a short diagonal mark as it lifted.
No matter, it was enough for us to continue testing this system. We started feeding it increasingly longer programs to see what breaks down first. Our answer: UGS, the G-code sender program running on our control console laptop, was the first to fail.
Completion of soldering circuits for hardware control switches seemed like a good place to take a break and test. It’s fun to keep the momentum going, but it’s also important to stop and verify the work done so far. Off to the shop we go to set things up!
The jury-rigged nature of this prototype test is evident. While I had put a bit of time into building a nice shelf for the computer, none of the other pieces received such attention. Eventually there’ll be an enclosure for the ESP32 running Grbl. A circuit board of the dev module plus all of its associated circuitry, much like the official Grbl ESP32 board. But that board has room for Pololu stepper drivers like those on a 3D printer, and we don’t need that for our Parker motors. That will happen later. For this test, I found a piece of scrap acrylic and taped it to the top extrusion beam to serve as table for the perforated circuit board.
In fact, tape is the dominant element in this test. In addition to the ESP32 platform, tape is held the battery pack for Z-axis servo. Plus all the wires, as it’s not yet clear how we’d want to run wiring for this system. The Parker ZETA4 drivers are still sitting loosely on the bottom shelf of the table, they need to be properly mounted eventually. Once these drivers and the ESP32 are mounted, we will need to consider how to best run wiring to minimize chances of wires getting in the way of our work piece.
In the meantime, everything is held out of the way with tape. Tape tape tape.
Aside from the computer, about the only thing not held by tape was the servo I intended to use to test Z-axis, which received a small 3D printed bracket. However, I ran out of time at home before I could devise something to attach to that servo output shaft.
For that I had to call for help, and Emily answered.
MatterHackers is a local supplier for 3D printing. They also carry other products catering to the same hobbyist-grade audience for small scale fabrication, such as laser cutters and CNC engravers. I’ve bought much of my supplies — including the PETG filament used to print the current iteration of Sawppy — from MatterHackers.
I’ve met some of the people of MatterHackers at Yuri’s Night, and been extended an invitation to visit their headquarters where there’s a showroom area. But I have yet to take them up on that invitations because, while MatterHackers is within driving distance, it is a nontrivial drive accounting for LA traffic. Going to that area is basically a day trip, and it kept not happening.
But when Sawppy was invited to be at their Modern Creators Night event, that was enough motivation for me to pack up and take that trip. At the event, I learned it is a scaled-up version of an occasional meetup MatterHackers used to hold at their main office, but there was no longer enough space there. Their business has grown, as has the size of the crowds. Hence – a new event at a venue with a new format.
Sawppy arrived and started roaming the exhibit area as rovers tend to do. But when it came time for the speakers to present, Sawppy was presented with a table for static exhibit. I made some signage I could tape to the table, to explain Sawppy when I’m not present to tell the story.
There were a lot of 3D prints on exhibit by other makers, and one of them decided to loan their little printed model of Curiosity to keep Sawppy company during speaker presentations. I was happily surprised when I saw this little guy, and didn’t meet its owner until later. I regret to say I’ve already forgotten her name, but her generous and appropriate loan is very much appreciated!
After wiring up for Z-axis servo control, I turned my attention to the remaining empty quadrant of the prototype board.
At the moment I have a small laptop running a G-code sender acting as the CNC control console, from which I can access all functionality of Grbl. The ESP32 port of Grbl also offers a built-in web interface, which is a great choice for compact machines that don’t want the overhead of a full computer. Both of these control options have a communication delay, so some things are better handled by hardware switches for immediate feedback.
By default Grbl ESP32 supports four physical switches, in the order of their pin assignment they are:
- Feed Hold: On many CNC, this completes execution of the current G-code command but holds off running the next one. Some machines can pause mid-command but this is not guaranteed. Axis motion stops, but spindle does not. This is a good way to have a machine pause, useful for example when the operator wants to visually check to make sure position and upcoming commands look reasonable.
- Cycle Start: Begins executing the loaded G-code program. Also used to resume execution after Feed Hold.
- Reset: This commands an immediate stop, of everything. Unlike Feed Hold, it will not wait for the current command to complete. It will also turn off spindle in addition to axis motion. Since it is an immediate cutoff of execution, the controller ends up in an unpredictable state. There’s no resuming after a reset. The machine has to be re-homed and all coordinate offsets recalculated.
- Door: Designed to be wired up to a door open detection switch so the machine can take actions to ensure operator safety. On some machines this is effectively a Feed Hold, others treat it as an emergency Reset, most machines treat it as somewhere in between. I don’t know yet how Grbl reacts.
All four are designed for normally-open switches that activate upon closing the circuit to ground. For reasons I don’t understand, these switches don’t use the ESP32 internal pull-ups and require external pull-up resistors. Normally-open switches don’t necessarily make sense for a situation. For example, reset is usually wired up with a series of normally closed switches and, if any of them should open, the machine halts. But this is easy to address in the physical circuit.
Another concern for these switches is that they tend to have long runs of wire. (Such as the aforementioned reset switch.) Long wires have a nasty tendency to act as an antenna picking up stray signals. So a real board would require opto-isolation to avoid triggering from line noise. But again, this is a prototype board missing the full set of protective features.
After I wired up jumpers for playing with these four switches, I made a small piece of label to remind me which pin is which. Then it’s time to bring the results of this prototype soldering session to the shop and run a few tests.
I plan to take advantage of a feature in Grbl ESP32, where a RC hobby servo can take the place of a stepper motor for any supported axis. It won’t be nearly as precise, or have the same range of motion, but it’s a good option for specific situations including tests.
The first part of this task was, obviously, to find it in the code repository and know how to compile with this option active. The second is to wire up my ESP32 dev board to emit the 1-2 ms RC control signal at its 3.3V output and convert that to a 5V signal courtesy of the USB port. Then it’s time to connect a servo.
But not directly, because USB doesn’t supply very much current and would not be a good source for servo motor power. Tasks with high stress or moving quickly will draw more than what USB can supply and cause voltage level to sag. Possibly causing the ESP32 to brown out and restart which would ruin everything.
What I needed for a servo test was a separate power supply. I started digging through my collection of salvaged AC to DC power transformer bricks looking for one in an appropriate voltage range before I decided I was overthinking things. This isn’t going to be the long term solution, it’s just for a short test. I don’t need a long term power source.
RC hobby servos are originally designed to run off 4.8-6V of a four-cell pack of batteries, tracing its lineage back to the age of NiCad radio receiver packs. This is roughly the same voltage as a commodity AA battery cell, so I pulled from my stock of 4xAA battery holders for this test. They even have an integrated on/off switch for convenience.
The ground wire was connected to the servo ground wire as well as ESP32 ground. Servo power wire is supplied by this 4xAA tray, and servo control signal from the 3-pin servo header of the prototype controller board. And finally, the servo gets a 3D printed bracket to clip on to the gantry structure’s 40mm extrusion beams.
The Z-axis test arrangement is now complete. But before I wrap up this session of perf board soldering, I wired up provisions for hardware control switches.
Strictly speaking, it was not critical to add a shelf for the little laptop used to control everything, but it is very nice to resolve the constant irritation of pausing what I wanted to do just to find a place to set it down. It should speed up future tinkiering of this machine, and the next step in that process is to wire up Z-axis capability.
In hindsight I should have packed the X (lower left) and Y axis (lower right) components a little closer together, but learning these lessons this is why we build prototypes. There isn’t quite enough room to duplicate the same pin layout for Z in the upper right, but then again, I don’t really need to. I’m not interfacing with an existing Parker Motion Control product, the Z-axis will be different.
As a result, the JST-XH connectors have been simplified from a 4+3 arrangement to a single 6-pin arrangement. 4 of the pins are the same: a pair of open-drain signals for step and direction. The remaining two pins are for a normally-open switch to home the Z axis stepper control.
But there’s another twist to the Z-axis: a feature of Grbl ESP32 is the ability to use a RC hobby servo for any axis. It requires changing a few
#define in the source code and recompiling, something I could do on the little laptop who now has a shelf. I thought a servo-actuated Z-axis would work well as a first test of system functionality, before I go through the effort of building a more functional stepper-controlled Z axis.
But I couldn’t use the same pin for both, because an open-drain circuit is the wrong way to send a control signal to a servo. Instead, a separate transistor was rigged up so the ESP32 control signal (3.3V) can emit a 5V servo signal. The signal pin and ground are exposed via a separate 3-pin header.
The 5V source for the control signal came from the USB port connected to the little laptop. Ideally there’ll be some opto-isolation for the control signal, but this will suffice for a prototype. However, it will not be enough to power the servo motor, which will require its own power source.
The first thing I wanted to address after a wobbly (but successful!) first run was placement of the control console computer. I didn’t have a good place to set the tiny laptop down. The machine may not look like it would take up the entire table, but once machine’s range of motion is accounted for, there’s not a whole lot of space left. During the test run, the laptop was literally on the ground next to the table. It would be useful to have a dedicated computer shelf.
The shelf was designed in two parts. The right side could be bolted to the end of an extrusion beam, but the left side didn’t have that luxury. I thought I would design it to clip on to the extrusion beam, but the first draft hooks were far too aggressive. I had to trim them back with a saw before I could fit the piece around the beam.
Both hooks installed and ready to host the computer. The right hand hook was printed with the final filament from one spool and start of another spool of PLA. Even though I ordered from the same vendor (Monoprice) they have apparently changed vendors or specification and the new spool filament is visibly different.
At first glance this design may appear to be heavily cantilevered, with most of the weight on the front of the hook placing great stress on the mounting points. This is only true when the laptop lid is closed. When the lid is open, where this shelf mounts on the beams is actually very close to the center of gravity of the laptop.
It still needs to be able to accept some weight, though, since there’ll be physical forces as I type on the keyboard and use the trackpad. But PLA is plenty strong for this application, with very little flex even when I rest my wrists on the computer.
This shelf is probably not permanent, but it is nice to have a convenient shelf to hold the laptop while I figure out how to work the rest of this machine.
Jet Propulsion Laboratory’s Open Source Rover uses six wheels adapted from Traxxas remote control trucks. Traxxas suspension has a hex shaped mounting point for these wheels, but the ServoCity motor hubs used by OSR does not fit. To bolt these wheels onto those hubs, rover builders need to drill two holes aligned with two diagonally opposite holes on the ServoCity hub. Precisely locating these holes may prove challenging, and some rover builders have offered their solution to the problem. This post outlines my approach.
The heart of my approach is a 3D printed jig that is clamped in a drill press vise. It is tall enough to accomodate one of these wheels, with a cylindrical tip that locates the center hole for the wheel. There are two holes on either side of this tip, corresponding to the locations where we want to drill. For setup, the vise and jig are positioned such that one of the holes are aligned with the location of our drill bit.
Once aligned, a wheel is mounted on the jig and we drill our first hole. Once that is done we turn the wheel 180 degrees. We can visually align the newly drilled hole to the printed hole in the jig, or we can use another drill bit as a locating pin. Drop this drill bit through the just-drilled hole into the 3D printed hole in order to locate the wheel.
This setup has room for improvement in terms of precision. The holes aren’t precisely the correct size so the location pin/drill bit has room to move. But it is sufficiently precise for the task at hand so I didn’t put in the time to revise the jig for additional precision.
The 3D printed jig is shared on Thingiverse, and a video demonstration has been posted to YouTube:
We had a few final bits of goofing off without a Z-axis before starting to build a real one. Two beams available for construction were found to be exactly the same length as the width of our table, so they were natural candidates as the main horizontal gantry structure. Now we could use arbitrary lengths for the vertical support beams bolted to either side, because they could drape past the edge and below the table surface. Not only does it give us complete flexibility on what height to mount our main horizontal beam, we also gain the option to reinforce the beam with brackets bolted to the bottom of the table.
Once the drilling and bolting started, however we found a few unexpected problems.
A small problem was that while our horizontal beam is exactly the width of the table, we also had a black plastic moulding surrounding the edge of the table. Actually dropping the beam below the table surface meant cutting interfering pieces of plastic away. Which we could do, but we don’t need to do so just yet so that’s been deferred.
A more significant problem was that one of the two holes of a bracket overlapped with the existing metal structure of this printer table. If it lined up exactly with the horizontal parts of the metal, we could drill a hole through it just as we did the wooden parts. Unfortunately it partially overlapped with some vertical members of the support structure, which would severely weaken the table if we drilled into it. We chose not to drill, but it also meant there were only two bolts instead of four fastening our gantry to the table.
This meant we ended with a less rigid gantry than we had originally hoped. It is pretty good left-right (parallel to machine X axis) but front-back (machine Y axis) is weak. We’ll have to add more reinforcements before we get serious about cutting material, but in the meantime it is the best Z-axis yet for pen plotting.
So Emily created a program that draws a gift for our enthusiastic supportive online cheerleader. This was the machine’s first run with nontrivial G-code, and its success cleared the way to further refinement of this machine.
After some debugging and re-awakening, I brought the laptop running UGS back to the workshop and this time it mostly worked. There were still a few unexplained system freeze-ups early in the work session but it was stable afterwards. Was there something weird with Java runtime settling down? I’m not sure, but I’ll have to keep an eye out to see if this recurs upon every system bootup.
Having a computer running UGS proved useful because we now have a 3D visualization of G-code tool path. It allowed us to see where a particular program declared its origin, so we could set work coordinate zero accordingly. It also allowed us to debug a few problems with the G-code we’ve randomly found online. The smiley face, for example, issued a G54 command early in the program but Grbl didn’t like that upon rerun and demanded a G0 before it.
Running G-code programs repeatedly to debug UGS settings meant we had ample opportunity to goof around with more drawings.
While fun, this “let’s act like a crappy Z-axis” game is not the point of the project. We know we need some sort of structure to fasten a Z-axis mechanism to. We hunted around the workshop for items collecting dust and found a set of 40mm x 40mm aluminum extrusion beams along with associated hardware. Formerly some sort of display for trade shows, it has been retired and available for use.
For the first draft we just want something better than holding the pen by hand, so we weren’t picky. Not really understanding what we wanted also meant we were reluctant to cut into these beams destructively until we know better. This meant using the lengths as-is and playing with various arrangements. C-clamps were very useful to temporarily hold pieces in place! Eventually we had enough of a plan and the clamps were replaced with bolts.
One thing that didn’t go quite according to plan during our first system test was how we sent our G-code file to the controller. I had planned to dedicate my Dell Inspiron 11 (3180) to the task of CNC control console, but it didn’t turn on at the workshop.
This was a problem, because I had hoped the G-code sender program I had installed on that laptop would help us understand what’s going on as we drive the machine. While CNC G-code is officially standardized, the standards still left a lot to the individual machine makers to define. Grbl (mostly) follows example set by LinuxCNC, so for the most part I can use LinuxCNC reference guide. I doubt I could memorize everything immediately, so a little software help might have been nice.
Grbl ESP32 is capable of operating completely independently using web interface. This is a basic interface which is extremely streamlined and missing some of the luxury features of other control interfaces. Furthermore, there is not enough onboard storage for CNC programs. To address the latter, there’s provision for attaching a SD card for storage via four pins on the ESP32. This is great for building small self-contained (maybe even portable!) machines.
But since our project is not very easily portable, I thought it’d be better to have a more full featured control console for this CNC. Grbl project wiki included a list of popular G-code senders, after reading that list I decided to try UGS and installed it on the little Dell. Since it was written for Grbl, it understands the Grbl-specific subset of G-code and also has a visualization module so we know what to expect when we run a program. All of these would have been useful in an initial system run.
At the workshop I pulled the Dell out of my backpack, pushed the power button, and nothing happened. After a few failed efforts to wake the machine, I resorted to using
simple_stream.py from the Grbl site, a flat Python script with absolutely no user friendly features whatsoever.
I brought the little Dell home in order to debug the problem. Once I got home, I determined the machine is running but stuck. I held the power button for longer than 4 seconds, which per ACPI spec will power down the machine regardless of state. I thought I had tried that at the workshop but I guess I didn’t quite hold it long enough? In any case the computer is ready for another attempt.
[Update: UGS didn’t pan out, more details here.]
While we’ve proven our nascent CNC could home and respond to individual hand-typed G-Code commands, we have yet to run more than a single line at a time. We’ve just bolted it down to a table but before we put too much effort into more hardware, it seemed like a good idea to make sure the software side is capable of a multi-line program.
Emily found a short snippet of G-Code that purports to draw a smiley face with a pen plotter. It is a great introduction to G-Code, showing us a basic way to start and stop the machine. Curiously, there is no Z-axis motion at all. It uses spindle motor commands to communicate “drawing” (M3 = spindle on) and “not drawing” (M5 = spindle off.)
G54 X0 Y0
G00 X0 Y0
G00 X-25 Y20
G02 X10 Y-10 I10 J0 F200 M3
G02 X-10 Y10 I0 J10;
G90 G00 M5 X0 Y0;
G00 X25 Y20
G02 X10 Y-10 I10 J0 F200M3
G02 X-10 Y10 I0 J10;
G90 G00 M5 X0 Y0;
G00 X40 Y0
G02 X-40 Y0 I-40 J0 F200 M3
G90 G00 M5 X-55 Y0;
G02 X0 Y-55 I55 J0 F200 M3
G02 X-55 Y0 I0 J55
Reading through this, I could see the XY coordinates are all around (0,0) so the center of this smiley face should be at the origin. Other than that, I have no idea. And since we haven’t built our Z-axis yet, Emily volunteered to be a human Z-axis. We sent this snippet of G-Code (some hiccups along the way) and our reward at the end of this work session was an artistic collaboration between human and machine.
Once we can successfully perform XY axis homing in Grbl ESP32 and see that it responds to some simple G-Code commands, it was time to get a little more rigorous about our hardware configuration. Up until this point this machine was mere placed on a dusty table, itself a salvaged piece of equipment.
Based on the appearance of a slot in the middle and a metal shelf underneath, it appears to have been designed for old dot matrix (or maybe even daisy-wheel) printers that use continuous fanfold paper fed through that slot. Given that such printers have a carriage that moves left-right (now our X axis) it was unexpectedly wobbly along that axis. Our X-axis movement now sets the table oscillating.
We may need to reinforce that sometime down the line, but the first task is to bolt our XY stage to the table. Since it is quite powerful and heavy, there’s a lot of momentum involved in its motion and we could not depend on friction to hold it in place: it slides around on the surface. Six holes were drilled in the table for 1/4″-20 threaded rods, each held in place by a nylon insert locking nut above and below. Now XY stage will no longer slide around on the table.
The chosen location is aligned with the front edge of the table, slightly right of center, due to the Y-axis lead screw to the left of the table. This placement left equal amount of space to the left and right for us to plan out how we want to build a Z-axis gantry. The first candidate approach is to use some aluminum extrusion beams that are sitting around gathering dust in the shop. But in the spirit of “build a little, test a little” we want to run a short G-Code file for fun.
Deciding on the machine axis was a useful piece of information for configuring Grbl ESP32 settings, but it was also an important decision for which wire connects to which pins. All of these could potentially be changed later if we change our mind, but hopefully spending a few minutes thinking now would save us that effort later.
The wires for both axis were put into JST-XH connectors for connection with perforated PCB. We could use other form of wire terminals but these polarized plugs seems like a good way to keep things orderly.
The Parker ZETA4 motor drivers offer a wide range options in microstepping. While it is tempting to go up to insane number of microsteps just because we can, for the immediate future we’ll go with “merely” 10 microsteps for a total of 2000 pulses per revolution. This lead screw is cut for 5 turns per inch, which made things a little tricky as Grbl uses metric values. Using 25.4mm to represent an inch, a setting of 2000 pulses per revolution works out to 393.7 steps per mm. It is not perfect but should be close enough for our purposes. If this causes a problem down the line, these ZETA4 drives do have a metric-friendly option of 25,400 steps per revolution. This will divide evenly but we may be trading off torque or run into problems with generating pulses fast enough.
For now, using 393.7 steps/mm is enough for reasonable precision in movement, and this machine homes on both X and Y axis according to newly decided axis alignment. Our dreams of a mini CNC is a little bit closer, and we can start thinking about how we want to approach building the Z axis. Part of that process will be deciding how everything will be bolted down to a table.
With a new control board built, there remained a few firmware configuration settings to pin down. Several of these parameters will dictate movement direction of the machine. We should decide on the direction our two machine axis will point, in a way that would make the most sense for the machine operator.
When exploring and working with a machine to bring it up and running, the most obviously convenient place to work is a place where it is easy to access various components of the machine. For me, this meant I had been spending most of my time staring at the side of XY stage where I could most easily access the motors and lead screws.
But aligning operational axis with this perspective would be a mistake. Assuming we get this machine up and running, the priorities will change. We would want machine components to be out of the way when actually using the machine. This translates to a desire to have the front of the machine be the least cluttered side of the machine, away from components. The cleanest side of this XY table mechanism is the far side from where its motors are.
If we designate that side as “front”, the motors would be out of the way of normal operation and so will one of the lead screws. The other lead screw will still reach close to the front, but at least it would be the simpler side away from where the motor (and associated cables) would have to be routed.
Based on this designated front side, it was then easy to decide on the location of machine zero, and the direction of X and Y axis, Once Grbl ESP32 was configured accordingly, we could test if the machine responds as expected.
Grbl ESP32 packed a lot of functionality in software, so it was relatively simple to put it to work controlling the salvaged industrial XY table. An ESP32 development board already included voltage and USB serial converter on board, all I really had to provide for the project are a few simple components to stand between the delicate 3.3V pins of a ESP32 and the physical world. If the goal was maximum simplicity, I would have used an ATmega based Arduino board with its robust 5V IO pins that could have been used directly. But I was enticed by the feature set of Grbl ESP32 and willing to put in a little more effort.
These components were first proven out on a temporary breadboard, and a successful single axis home gave me the confidence to move that circuit to a perforated circuit board with soldered instead of jumper wires, and also duplicate the circuit so we could control both X and Y axis.
I first laid out the ESP32 development module in the center, with roughly equal space for circuitry all around. As I started planning on component layout, though, I quickly realized this was silly. Even spacing was not a feature, it was actually very constrictive. Thankfully I had not yet soldered everything down so I could rotate the layout 90 degrees giving more space to the left and right of my ESP32 dev board for components. It didn’t matter this reduced the free space top and bottom – they weren’t convenient to use in this layout anyway.
For the step and direction lines on both axis, there’s a simple 2N2222 transistor allowing delicate ESP32 output pins (via a 1 kΩ resistor) to control the ground line of a much larger 5V circuit going into the Parker ZETA4 stepper motor driver. In parallel with the output ground pin going to the ZETA4, there’s also a LED (with a 470 Ω current limiting resistor) to indicate activity on that line. Following the footstep of my Pixelblaze axis test, I used two red LEDs for X and two green ones for Y.
I had originally intended to install an optoisolator for each of the two homing switch input pins, but I ran short on time for the work session. I was too squeamish to connect the pins directly so I put in another 1 kΩ resistor between the ESP32 pin and the input that would be shorted to ground. It’s not a very robust level of protection, but it is better than nothing. A future iteration will have to revisit the topic of ESP32 protection measures, potentially after one is damaged from insufficient protection…
But that’s a problem for later. For the purposes of this work session, we have to decide how we want our machine axis to be configured.
Once the intermittent wiring problem had been tracked down and fixed, we could resume where we left off on the previous work session with this salvaged Parker XY stage: trying to command an axis to find its homing position. The previous attempt failed because the stage sailed right past the homing switch due to the homing switch.
We did get the homing operation to work, but we had to adjust a few settings from Grbl defaults before everything started moving as planned. Those defaults made sense for a relatively lightweight motion control table using physical micro switches for home and limit switches. This salvaged industrial stage is quite sturdy with significant momentum once it starts moving, and it uses magnetic reed switches for its home and limit switches.
- To compensate for greater momentum, homing seek speed (Grbl parameter
$25) was halved from 2000 mm/min to 1000 mm/min.
- Reed switches have greater hysteresis than micro switches, so the homing pull-off distance (Grbl parameter
$27) was increased from 1 mm to 6 mm.
We haven’t yet decided which direction will actually be positive or negative nor which motor will move which axis. This will affect direction port invert mask (Grbl parameter $3) once the decision is made. For now, it only matters that we wire up the correct reed switch to function as a homing switch.
Seeing the large Parker Motion Control linear actuator move and find home position was quite satisfying, and with this much confidence in functionality, I can transfer the control circuit from a temporary breadboard with jumpers to a perforated prototype board with more reliable soldered wires.
Following plan for the switch test board, I crimped 3-pin JST-XH connectors on loose wires at the end of XY stage’s limit and home switches. The colors matched the wiring diagram I found in documentation, which also matched what we determined via probing with a meter. But there was a problem hiding somewhere in this system, and that’s what the test board is here to determine.
The first discovery is that one of the limit switches is no longer closing before the carriage runs into a hard mechanical stop. In my eagerness to move the switches as far out to their limits as I could, I’ve managed to move one of the limit switches too far out of detection range. This will have to be fixed eventually but it isn’t the top problem right now.
Moving the axis back and forth and watching LEDs on the test board, we eventually figured out the problem: there is a loose connection somewhere in the system. There are six LEDs on the test board, a pair of complementary LEDs for each of three switches. In normal operation we expect one of the two LEDs to illuminate. But for the homing switch, it occasionally goes dark and neither LEDs are illuminated.
Hunting for loose connections, we eliminated the more likely suspects first (such as my JST-XH crimps) and worked our way down the list. We did not expect the strong industrial standard AMP circular connectors to be the problem, but that’s where it was: pin for the black wire, which is the common wire of the homing switch, had backed out from its proper location and unable to make a strong and reliable connection. We pushed it back into position and it seemed to stay in position. At least, for now.
With this intermittent connection, homing the machine would have been an unreliable process. It is conceivable this was the very problem that caused the original machine to be retired, but that is just speculation. With the homing switch repaired, it’s time to get back to work.