Archive for category Software

HP 7475A Plotter Data Sniffing: socat Serial Port Tee

Some hints and examples provided the socat incantation required to sniff serial data between my Superformula demo program (on the Raspberry Pi) and my HP 7475A plotter:

socat /dev/ttyUSB0,raw,echo=0 SYSTEM:'tee /tmp/in.txt | socat - "PTY,link=/tmp/ttyv0,raw,echo=0,wait-slave" | tee /tmp/out.txt'

The out.txt file collects data from the program to the plotter, the in.txt file holds data from the plotter to the program, and both files contain exactly and only the serial data, so some interpretation will be required.

With that in hand, tweak the .chiplotle/ file to aim Chiplotle at the virtual serial port:

serial_port_to_plotter_map = {'/tmp/ttyv0' : 'HP7475A'}

This is dramatically easier than wiring a pair of additional hardware serial ports onto the RS-232 connection between the two:

HP 7475A - serial port adapters - hardcore
HP 7475A – serial port adapters – hardcore

The adapter stack instantly become a custom cable, although I miss Der Blinkenlights.

The HPGL output to the plotter (out.txt) comes from the Chiplotle driver with no embedded linefeed / carriage return characters, as HPGL uses semicolon command terminators, making it one humongous line impervious to the usual text utilities. In addition, several plotter configuration commands have prefix ESC (0x1b) characters without semicolon separators. Each LB (label) command within the stream ends with a 0x03 ETX character.

While one could fix all those gotchas with a sufficiently complex sed script, I manually separated the few lines I needed after each semicolon, then converted the raw ASCII control characters to displayable Unicode glyphs (␛ and ␃), making it legible for a presentation:

head -c 1000 out.txt
LBStarted 2020-01-09 18:03:57.494617␃;
LBPen 1: ␃;
LBm=1.9 n1=0.71 n2=n3=0.26␃;
<<< snippage >>>

The corresponding responses from the plotter to the program (in.txt) are separated by carriage return characters (␍) with no linefeeds (␊), so the entire file piles up at the terminal’s left margin when displayed with the usual text tools. Again, manually splitting the output at the end of each line produces something useful:

<<< snippage >>>

The first number gives the size of the serial FIFO buffer. An inexplicable ten OW; commands from deep in the Chiplotle driver code return the Output Window size in plotter units. No other commands produce any output until the plot finishes, whereupon my code waits for a digitized point from the plotter, with the (decimal) 18 indicating a point isn’t ready.

All that at 9600 bits per second …

Leave a comment

CNC 3018XL: Adding Run-Hold Switches

Although the bCNC GUI has conspicuous Run / Hold buttons, it’s easier to poke a physical switch when you really really need a pause in the action or have finished a (manual) tool change. Rather than the separate button box I built for the frameless MPCNC, I designed a chunky switch holder for the CNC 3018XL’s gantry plate:

CNC 3018-Pro - Run Hold Switches - installed
CNC 3018-Pro – Run Hold Switches – installed

The original 15 mm screws were just slightly too short, so those are 20 mm stainless SHCS with washers.

The switches come from a long-ago surplus deal and have internal green and red LEDs. Their transparent cap shows what might be white plastic underneath:

CNC 3018-Pro - Run Hold Switches - top unlit
CNC 3018-Pro – Run Hold Switches – top unlit

I think you could pry the cap off and tuck a printed legend inside, but appropriate coloration should suffice:

CNC 3018-Pro - Run Hold Switches - lit
CNC 3018-Pro – Run Hold Switches – lit

Making yellow from red and green LEDs always seems like magic; in these buttons, red + green produces a creamy white. Separately, the light looks like what you get from red & green LEDs.

The solid model shows off the recesses around the LED caps, making their tops flush with the surface to prevent inadvertent pokery:

Run Hold Switch Mount - Slic3r
Run Hold Switch Mount – Slic3r

The smaller square holes through the block may require a bit of filing, particularly in the slightly rounded corners common to 3D printing, to get a firm press fit on the switch body. The model now has slightly larger holes which may require a dab of epoxy.

A multi-pack of RepRap-style printer wiring produced the cable, intended for a stepper motor and complete with a 4-pin Dupont socket housing installed on one end. I chopped the housing down to three pins, tucked the fourth wire into a single-pin housing, and plugged them into the CAMtool V3.3 board:

CNC 3018-Pro - Run Hold Switches - CAMtool V3.3 header
CNC 3018-Pro – Run Hold Switches – CAMtool V3.3 header

The CAMtool schematic matches the default GRBL pinout, which comes as no surprise:

CAMtool schematic - Start Hold pinout
CAMtool schematic – Start Hold pinout

The color code, such as it is:

  • Black = common
  • Red = +5 V
  • Green = Run / Start (to match the LED)
  • Blue = Hold (because it’s the only color left)

The cable goes into 4 mm spiral wrap for protection & neatness, with the end hot-melt glued into the block:

CNC 3018-Pro - Run Hold Switches - bottom
CNC 3018-Pro – Run Hold Switches – bottom

The model now includes the wiring channel between the two switches, which is so obviously necessary I can’t imagine why I didn’t include it. The recess on the top edge clears the leadscrew sticking slightly out of the gantry plate.

The LEDs require ballast resistors: 120 Ω for red and 100 Ω for green, producing about 15 mA in each LED. Those are 1/8 W film resistors; I briefly considered SMD resistors, but came to my senses just in time.

A layer of black duct tape finishes the bottom sufficiently for my simple needs.

Note: the CAMtool board doesn’t have enough +5 V pins, so add a row of +5 V pins just below the standard header. If you’ve been following along, you needed them when you installed the home switches:

3018 CNC CAMTool - Endstop power mod
3018 CNC CAMTool – Endstop power mod

A doodle giving relevant dimensions and layouts:

Run Hold Switch Mount - Layout Doodles
Run Hold Switch Mount – Layout Doodles

I originally planned to mount the switches on the other gantry plate and sketched them accordingly, but (fortunately) realized the stepper motor was in the way before actually printing anything.

The OpenSCAD source code as a GitHub Gist:

It seems bCNC doesn’t update its “Restart Spindle” message after a tool change when you poke the green button (instead of the GUI button), but that’s definitely in the nature of fine tuning.

, ,

1 Comment

CNC 3018XL: Rotating the Axes

After extending the CNC 3018-Pro platform to 340 mm along the Y axis, I tweaked the Spirograph demo to work with 8-1/2×11 paper:

Spirograph - 3018XL Platform - Portrait Mode
Spirograph – 3018XL Platform – Portrait Mode

Yeah, a Portrait mode plot kinda squinches the annotations into the corners.

Rotating the coordinates to put the X axis along the length of the new platform is, of course, a simple matter of mathematics, but it’s just a whole lot easier to rearrange the hardware to make the answer come out right without fancy reprogramming.

The first step is to affix an MBI-style endstop switch to the left end of the gantry upright:

3018XL - endstop - left gantry
3018XL – endstop – left gantry

The gantry carriage sits at the 1 mm pulloff position, with the switch lever just kissing the (fixed) lower carriage plate. As before, good double-sticky foam tape holds everything in place.

The probe camera hovers just over the switch and the Pilot V5RT pen holder is ready for action.

Shut down the Raspberry Pi and turn off the power!

At the CAMtool V3.3 board:

  • Swap the X and Y motor cables
  • Move the former Y endstop switch to the X axis input
  • Plug the new endstop switch into the Y axis input, routing its cable across the top of the gantry
  • Abandon the former X axis switch and its cable in place

Modify the GRBL configuration:

  • $3=4 – +Y home @ gantry left, +X home @ frame front
  • $130=338 – X axis travel along new frame
  • $131=299 – Y axis travel across gantry

Tweak the bCNC config similarly, if that’s what you’re into.

Verify the new home position!

I reset the G54 coordinate system to put XY = 0 at the (new!) center of the platform, redefined G28 as the “park” position at the (new!) home pulloff position, and set G30 as the “tool change” position at the -X -Y (front right) corner of the platform, with bCNC icons to simplify moving to those points.

And then It Just Worked™:

3018XL - rotated axes
3018XL – rotated axes

The Spirograph patterns definitely look better in landscape mode:

Spirograph - 3018XL Platform - Landscape Mode
Spirograph – 3018XL Platform – Landscape Mode

I eventually turned the whole machine 90° clockwise to align the axes with the monitor, because I couldn’t handle having the X axis move front-to-back on the table and left-to-right on the screen.


Leave a comment

Raspberry Pi: Adding a PIXEL Desktop Launcher

The Raspberry Pi’s Raspbian PIXEL Desktop UI (not to be confused with the Google Pixel phone) descends from LXDE, with all the advantages & disadvantages that entails. One nuisance seems to be the inability to create a launcher for a non-standard program.

The stock task bar (or whatever it’s called) has a few useful launchers and you can add a launcher for a program installed through the usual Add/Remove Software function, as shown by the VLC icon:

LXDE launcher icons
LXDE launcher icons

Adding a bCNC launcher requires a bit of legerdemain, because it’s not found in the RPi repositories. Instead, install bCNC according to its directions:

… install various pre-requisites as needed …
pip2 install --upgrade git+ 

Which is also how you upgrade to the latest & greatest version, as needed.

You then launch bCNC from inside a terminal:

python2 -m bCNC

The installation includes all the bits & pieces required to create a launcher; they’re just not in the right places.

So put them there:

sudo cp ./.local/lib/python2.7/site-packages/bCNC/bCNC.png /usr/share/icons/
sudo cp .local/lib/python2.7/site-packages/bCNC/bCNC.desktop /usr/share/applications/bCNC.desktop

The bCNC.desktop file looks like this:

[Desktop Entry]
Comment=bCNC Controller

Set Terminal=false if you don’t want a separate terminal window and don’t care about any of the messages bCNC writes to the console during its execution. However, those messages may provide the only hint about happened as bCNC falls off the rails.

With all that in place, it turns out LXDE creates a user-specific panel configuration file only when you change the default system panel configuration. Add a VLC launcher to create the local ~/.config/lxpanel/LXDE-pi/panels/panel file.

With that ball rolled, then add the bCNC launcher:

nano .config/lxpanel/LXDE-pi/panels/panel
… add this stanza …
Plugin {
  Config {
    Button {

Log out, log back in again, and the bCNC icon should appear:

LXDE launcher icons - additions
LXDE launcher icons – additions

Click it and away you go:

bCNC - Running from LXDE Launcher
bCNC – Running from LXDE Launcher

At least you (and I) will start closer to the goal when something else changes …

, , ,


Drag Knife Cuttery: Entry & Exit Moves

The first pass at cutting laminated decks for the Homage Tektronix Circuit Computer left little uncut snippets at the starting point of the cut. The point of the drag knife blade trundles along behind the cutting edge and, when the ending point equals the starting point, leaves an un-cut sliver as it’s retracted vertically:

Drag Knife - LM12UU - knife blade detail
Drag Knife – LM12UU – knife blade detail

The knife blade isn’t aligned in any particular direction, so it can leave a nick on either side as it enters the deck vertically at the start of the cut.

Gradually entering the deck along the cut line gives the blade enough time to swivel around to the proper alignment before it gets down to serious cutting. Continuing the final cut past the starting point then allows the blade to recut anything remaining from the entry move.

The middle and top decks have windows exposing the scales:

Tek CC - radial text example
Tek CC – radial text example

The paths are basically two arcs connected by semicircular cuts, but with ramps on each end recutting the entry and exit paths:

Top Deck - Window Cut Path
Top Deck – Window Cut Path

The entry path in the upper left slants downward from the TravelZ level of 1.5 (-ish) mm to Z=0, with the nose of the blade holder flush against the surface and the blade sunk to its full length. The vertical path to Z=-2 (-ish) increases the cutting pressure from roughly the preload value to preload + 2*(spring rate), so the blade won’t ride up under the cutting forces.

The path then goes completely around the window at Z=-2, then ramps up to the TravelZ level again.

All of which produces a neat cutout that sticks to the Cricut mat when I peel the rest of the deck off:

Tek CC - MPCNC drag knife
Tek CC – MPCNC drag knife

That’s a middle deck before I started laminating them, but you get the general idea.

The GCMC code (extracted from the complete lump) looks like this:

  local WindowArc = 54deg;

  local ac = -17 * ScaleArc + ScaleRT/2;   // center of window arc
  local r0 = DeckRad - ScaleHeight;        // outer
  local r1 = DeckRad - 2 * ScaleHeight;    // inner

  local aw = WindowArc - to_deg(atan(ScaleHeight,(r0 + r1)/2));    // window arc minus endcaps

  p0 = r0 * [cos(ac + aw/2),sin(ac + aw/2),-];
  p1 = r0 * [cos(ac - aw/2),sin(ac - aw/2),-];
  local p2 = r1 * [cos(ac - aw/2),sin(ac - aw/2),-];
  local p3 = r1 * [cos(ac + aw/2),sin(ac + aw/2),-];

  arc_cw(p0 +| [-,-,0],ScaleHeight/2);    // blade enters surface
  move([-,-,KnifeZ]);                     // apply pressure

  arc_cw(p1,r0);                          // smallest arc
  arc_cw(p2,ScaleHeight/2);               // half a circle

  arc_cw(p1 +| [-,-,TravelZ],r0);         // exit from cut


Having measured the angular position of the window and its size on the original Tek CC, I compute the coordinates of the four points where the semicircular “end caps” meet the longer arcs, then connect the dots with arc_xx() functions to generate the G-Code commands. As always, using the proper radius signs requires trial & error.

While I was at it, I added entry & exit moves for the deck’s central pivot hole and outer perimeter.

I’m pretty sure the right CAM package would take care of that, but GCMC operates well below the CAM level.

, , ,

Leave a comment

Google Pixel 3a Microscope Adapter

Hand-holding my Google Pixel 3a phone over the microscope eyepiece worked well enough to justify building Yet Another Camera Adapter:

Pixel 3a Microscope Adapter - in action
Pixel 3a Microscope Adapter – in action

The solid model looks about like you’d expect:

Google Pixel 3a Zoom Microscope Mount - solid model - top
Google Pixel 3a Zoom Microscope Mount – solid model – top

The “camera” actually has the outside dimensions of a Spigen case, rather than the bare phone, because dropping a bare phone is never a good idea.

The base plate pretty much fills the M2’s platform:

Pixel 3a Microscope Adapter - M2 platform
Pixel 3a Microscope Adapter – M2 platform

I originally arranged the four corners around the plate to print everything in one go, but an estimated six hours of print time suggested doing the corners separately would maximize local happiness. Which it did, whew, even if the plate ran for a bit over 4-1/2 hours.

The snout is a loose fit around the 5× widefield microscope eyepiece, with the difference made up in a wrap of black tape; it’s much easier to adjust the fit upward than to bore out the snout. An overwrap of tape secures the snout to the eyepiece, which I’ve dedicated to the cause; the scope normally rocks 10× widefield glass.

The tapered hole exposes the phone’s fingerprint reader to simplify unlocking, should it shut down while I’m fiddling with something else.

The microscope doesn’t fully illuminate the camera’s entrance pupil at minimum zoom, with 4.5× filling the screen and (mostly) eliminating the vignette. The corner blocks have oversize holes to allow aligning the camera lens axis over the microscope optical axis. The solid model incorporates Lessons Learned from the version you see here, because you (well, I) can’t measure the camera axis with respect to the outside dimensions accurately enough:

Pixel 3a Microscope Adapter - installed - front
Pixel 3a Microscope Adapter – installed – front

Although it’s less unsteady than it looks, microscopy requires a gentle touch at the best of times. The adapter doesn’t add much wobble to the outcome:

Pixel 3a Microscope Adapter - installed - side
Pixel 3a Microscope Adapter – installed – side

The field is about 14×19 mm with the camera at 4.5× and the microscope at minimum zoom:

Pixel 3a Microscope Adapter - test image - min mag
Pixel 3a Microscope Adapter – test image – min mag

You can see a little darkening on the upper and lower right corners, so the phone’s still minutely leftward.

The field is about 1.5×2 mm at full throttle:

Pixel 3a Microscope Adapter - test image - max mag
Pixel 3a Microscope Adapter – test image – max mag

Color balance with the cold white LED ring isn’t the best, but it’s survivable. Mad props to OpenCamera for exposing All. The. Controls. you might possibly need.

The OpenSCAD source code as a GitHub Gist:

, ,


Homage Tektronix Circuit Computer: Pen Plotter Version

A reproduction circular slide rule from the mid-1960s may not be the cutting edge of consumer demand, but the pen version of a Tektronix Circuit Computer came out pretty well:

Homage Tektronix Circuit Computer - green on white laminated
Homage Tektronix Circuit Computer – green on white laminated

A Bash script compiles the GCMC code with eight different parameter combinations to produce pairs of G-Code files to draw (“engrave” being aspirational) and cut (“mill”, likewise) the three decks and the cursor.

The CNC 3018XL with a Pilot V5RT pen draws the deck scales on white paper:

Pilot V5RT holder - installed
Pilot V5RT holder – installed

Better paper definitely produces better results, so I must rummage through the Big Box o’ Paper to see what lies within. Laminating the decks improves their durability and matches the original Tek surface finish.

The MPCNC with a drag knife blade cuts through a laminated deck like butter:

Tek CC - MPCNC drag knife
Tek CC – MPCNC drag knife

Setting the XY origin to dead center on each deck requires carefully calibrating the USB video camera, with the end result accurate to maybe ±0.1 mm around the entire perimeter. Both machines move equal linear distances along both axes, which was definitely comforting.

Having made half a dozen cursors from various bits of acrylic, none of which look particularly good, demonstrates my engraving hand is too weak for a complete slide rule:

Tek Circuit Computer - cursor hairline
Tek Circuit Computer – cursor hairline

With logarithmic scales in hand, however, adapting the GCMC source code to produce general-purpose circular slide rules with only two decks and smaller diameters may be the way to improve my engraving-fu, as a full-scale Tektronix Circuit Computer would chew up three square-foot plastic sheets.

A general-purpose slide rule would need multi-color (well, at least bi-color) labels and digits for red “inverse” scales to remind you (well, me) they read backwards. Some slipsticks use left-slanting italics, left-pointing markers (“<2”), or other weirdness, but they’re all different.

An early small-scale version engraved on ABS came out OK, modulo poor ink fill:

Tek CC bottom - ABS 160g 2400mm-min
Tek CC bottom – ABS 160g 2400mm-min

Engraving the decks on hard drive platters doesn’t count:

Tek CC - bottom deck - scaled to HD platter
Tek CC – bottom deck – scaled to HD platter

All in all, it’s been an interesting exercise and, as you may have guessed, will become a Digital Machinist column.

The GCMC and Bash source code as a GitHub Gist:

, , , ,