CNC 3018-Pro: HD and CD Fixtures

I actually had this in mind when I laid out the hard drive and CD engraving fixtures:

CNC 3018-Pro - HD and CD fixtures
CNC 3018-Pro – HD and CD fixtures

The fixtures are centered at X±70.0 mm / Y=0.0 from the G54 workspace coordinate origin dead-center in the middle of the platform, with G55 centered on the HD fixture to the left and G56 on the CD fixture to the right.

So the engraving workflow amounts to homing the CNC 3018 when I turn it on, taping a platter in a fixture, selecting the corresponding WCS, loading a suitable G-Code file, and firing it off. It seems bCNC returns to G54 after completing the file, so verifying the WCS selection every time is Very Good Practice.

The friable lacquer coating on some CDs fills my world with glitter whenever I engrave a pattern on their label side. I didn’t plan on a dust shoe for this thing!


, ,

Leave a comment

Chipmunk Fatality

This chipmunk didn’t die in bed, either:

Chipmunk - tail segment - side
Chipmunk – tail segment – side

Similar to the previous example, one of the hawks surely dismantled the tail to get at the good parts, although we haven’t seen any gibbage.

Looking into the end, you can see where the next segment would attach:

Chipmunk - tail segment - end
Chipmunk – tail segment – end

Somewhere nearby, there’s a recently vacated nest with a pantry full of carefully chosen seeds and nuts, just waiting for another critter to move in …

Leave a comment

Vole Fatality

Voles apparently live only a few months, so this one may have run out of gas while crossing the driveway:

Vole - dead on driveway
Vole – dead on driveway

Or it just caught a heart attack?

It definitely wasn’t playing possum; nobody can lie still with ants up their nose.

It had vanished when we returned from our afternoon ride, so somebody further up the food chain also noticed it. As my buddy dBm puts it, “In Nature, nothing goes to waste.”


Makergear M2: Octopi Camera Mount

Octopirint / Octopi works wonderfully well as a controller / G-Code feeder for my Makergear M2. After putting up with an ungainly mass of tape for far too long, I printed Toddman’s Pi Camera Mount:

Pi Camera - M2 Mount - Slic3r
Pi Camera – M2 Mount – Slic3r

Which snapped together exactly like it should:

Makergear M2 - Pi Camera Mount
Makergear M2 – Pi Camera Mount

A strip of double-sided foam tape attaches it to the Pi’s case, which is Velcro-ed to the M2’s frame. The cable may be too long, but avoids sharp bends on the way out of the case.

The whole lashup works fine:

Pi Camera - M2 Mount - Octopi timelapse
Pi Camera – M2 Mount – Octopi timelapse

That’s a second set intended for the CNC 3018-Pro, but it didn’t fit quite as well. The B brackets are slightly too long (or their pivots are slightly too close to their base) to allow the C plates to turn 90° to the mount:

Pi Camera - M2 Mount - Config 2 diagram
Pi Camera – M2 Mount – Config 2 diagram

Nothing one can’t fix with nibbling & filing, but I long for parametric designs …

, ,

Leave a comment

Alead Telecoil Receiver: Magnetic Field Check

I got an Alead / Nolan HearLinks (many adjectives) Telecoil receiver to boost my ability to hear music & presentations at Vassar, because they recently slotted telecoil loops into the floors of their public venues. It took a few concerts to get the appropriate volume setting, after which I wondered how sensitive the receiver was:

Alead T-coil receiver - test setup
Alead T-coil receiver – test setup

The small T in the upper right corner marks the receiving coil location, with the coil oriented parallel to the body’s long axis. It’s the secondary winding of an air-core transformer with a single-turn (perhaps using Litz wire) primary embedded in the floor, with the induced voltage obeying the usual transformer equation:

V = 2π µ₀ µr N A f H cos θ


  • µ₀ – vacuum permeability = 4π×10-7 H/m
  • µr – relative permeability
  • N – number of turns
  • A – receiver loop area, m²
  • f – signal frequency, Hz
  • H – magnetomotive force, A/m
  • θ – angle between windings

For a given installation and receiver position, pretty much everything is fixed, with the voltage depending only on the H field caused by the primary winding current.

The induced voltage is linearly dependent on the frequency, but the transmitter equalization filters apparently flatten the spectrum to get equal receiver amplitude between about 100 Hz and 5 kHz.

The coil in that picture has nine turns, with four passing through the Tek current probe. Applying 10 mVpp to the winding produces a corresponding current:

JDS6600 10mVpp 1 kHz - 4 turns - 1 mA-div
JDS6600 10mVpp 1 kHz – 4 turns – 1 mA-div

The scope sees 14 mVpp = 1.4 div at 1 mA/div = 1.4 mA. Dividing by 4 turns means the coil actually carryes 350 µA. The signal generator has a 50 Ω output impedance, so 10 mV should produce about 200 µA, which seems a bit low. On the other paw, the signal generator sees the coil as a dead short at 1 kHz, so I don’t trust the numbers.

Whatever magnetic flux it may be produces a 1 kHz tone at a somewhat higher volume (for the same receiver setting) than the fancy Vassar loops, so the flux is in the right ballpark. With a bit more attention to detail, perhaps I can tinker up a current-mode loop drive amplifier.

The Alead receiver has an internally generated tick audible at the audio volume I need for the Vassar loops, which is 5 to 7 steps down from the maximum volume at 15 steps. It seems related to the internal Bluetooth hardware, although it’s present even when the receiver is not paired with my Pixel phone and, in fact, is unchanged even when 100 feet from the nearest electronic device.

When I reported the problem, they said:

Yes, you can hear very minor tick sound on telecoil mode. It is caused by some electronic and current to make those tick sound. Sorry for this defective on the design.

It had one job that it doesn’t do well, so it’s on the way back for a refund.

Evidently, I must build an audio loop receiver to get what I want …



GCMC Platter Engraving

Engraving Spirograph / Guilloché patterns on scrap CDs and hard drive platters now works better than ever:

Spirograph - 674203941 - preview
Spirograph – 674203941 – preview

After, that is, I realized:

  • Any Rotor will work, as long as it’s smaller than the Stator
  • You must pick pen offset L so the pattern never crosses the stator center point
  • L ≥ 1 is perfectly fine
  • You must scale the resulting pattern to fit the actual space on the disk

One of my final doodles showing how the variables relate to each other, although the Wikipedia article may be useful for the underlying math and other posts have more pix on various machines:

Spirograph Scaling doodles
Spirograph Scaling doodles

Cheat sheet:

  • Stator has tooth count (∝ radius) R
  • Rotor has tooth count (∝ radius) r
  • K = r/R, so if you normalize R=1, K=r
  • Pen offset L puts it at radius rL in the rotor

Picking a suitable rotor requires iterating with random choices until one fits:

  RotorTeeth = Stators[-1];
  n = 0;
  while (RotorTeeth >= floor(0.95 * StatorTeeth) || RotorTeeth < 5) {
    RotorTeeth = (XORshift() & 0x007f);       // this is why Stator can't have more than 127 teeth
  comment("Rotor: ",RotorTeeth," in ",n," iterations");

The 5% buffer on the high end ensures there will be an L keeping a hole in the middle of the pattern. Requiring at least five teeth on the low end just seems like a Good Idea.

Given the stator & rotor tooth counts, iterate on random L values until one works:

  n = 0;
  do {
    L = (to_float((XORshift() & 0x1f) + 1) / 32.0) * (1.0/K - 1.0);   // allow L > 1.0
  } while (L >= (1.0/K - 1.0) || L < 0.01);
comment("Offset L: ", L," in ",n," iterations");

With L chosen to leave a hole in the middle of the pattern, then the pattern traced by the pen in the rotor is centered at 1.0 – K (the normalized Stator radius minus the normalized Rotor radius) and varies by ±LK (the offset times the normalized Rotor radius) on either side:

RotorMin = 1.0 - 2*K;
comment("Rotor Min: ",RotorMin);

BandCtr = 1.0 - K;                      // band center radius
BandMin = BandCtr - L*K;                //  ... min radius
BandMax = BandCtr + L*K;                //  ... max radius

BandAmpl = BandMax - BandCtr;

comment("Band Min: ",BandMin," Ctr: ",BandCtr," Max: ",BandMax);

Knowing that, rescaling the pattern to fit the disk limits goes like this:

FillPath = {};

foreach (Path; pt) {

  a = atan_xy(pt);                      // recover angle to point
  r = length(pt);                       //  ... radius to point

  br = (r - BandCtr) / BandAmpl;        // remove center bias, rescale to 1.0 amplitude
  dr = br * (OuterRad - MidRad);        // rescale to fill disk
  pr = dr + MidRad;                     // set at disk centerline

  x = pr * cos(a);                      // find new XY coords
  y = pr * sin(a);

  FillPath += {[x,y]};

comment("Path has ",count(FillPath)," points");

The final step prunes coordinates so close together as to produce no useful motion, which I define to be 0.2 mm:

PointList = {FillPath[0]};                // must include first point

lp = FillPath[0];
n = 0;

foreach (FillPath; pt) {
  if (length(pt - lp) <= Snuggly) {       // discard too-snuggly point
  else {
    PointList += {pt};                    // otherwise, add it to output
    lp = pt;

PointList += {FillPath[-1]};                // ensure closure at last point

comment("Pruned ",n," points, ",count(PointList)," remaining");

The top of the resulting G-Code file contains all the various settings for debugging:

(Disk type: CD)
(Outer Diameter: 117.000mm)
(        Radius: 58.500mm)
(Inner Diameter: 38.000mm)
(        Radius: 19.000mm)
(Mid Diameter: 77.500mm)
(      Radius: 38.750mm)
(Legend Diameter: 30.000mm)
(         Radius: 15.000mm)
(PRNG seed: 674203941)
(Stator 8: 71)
(Rotor: 12 in 1 iterations)
(Dia ratio K: 0.169 1/K: 5.917)
(GCD: 1)
(Lobes: 71)
(Turns: 12)
(Offset L: 3.227 in 1 iterations)
(Rotor Min: 0.662)
(Band Min: 0.286 Ctr: 0.831 Max: 1.376)
(Path has 43201 points)
(Pruned 14235 points, 28968 remaining)

The GCMC source code as a GitHub Gist:

, ,

1 Comment

Monthly Science: Concrete Bridge Flexing

Riding south on Rt 376 takes us across the Mighty Wappinger Creek on a four-lane concrete bridge built about 1995. This Dutchess County Aerial Access photo shows it in 2016:

Rt 376 - Wappinger Bridge - 2016 overhead
Rt 376 – Wappinger Bridge – 2016 overhead

A pothole opened up on the south end of the span last year:

Rt 376 bridge deterioration - marker 1102 - 2018-05-07
Rt 376 bridge deterioration – marker 1102 – 2018-05-07

NYS DOT patched it a while ago:

Rt 376 - Wapp Bridge - 2019-09-11 - 0490
Rt 376 – Wapp Bridge – 2019-09-11 – 0490

This year, we’ve been avoiding a new pothole opening on the north end:

Rt 376 - Wapp Bridge - 2019-09-11 - 0295
Rt 376 – Wapp Bridge – 2019-09-11 – 0295

It’s difficult to ride between the right side of the hole and the weeds growing from the curb joint under the guide rail, so we take the lane whenever we can. The extensive vegetation growing in the bridge structure can’t possibly be a good thing.

The bridge deck rests on steel beams across the creek, with plenty of corroded concrete along the edge:

Red Oaks Mill bridge - dangling concrete
Red Oaks Mill bridge – dangling concrete

The concrete seems to be failing by tension overload as the beams flex downward under traffic loading and pull the top surface apart. The surface has irregular transverse cracks across the deck width, not all of which look like control joints.

With potholes and surrounding cracks allowing brine into the deck, we expect much worse deterioration during the next few years.

My Professional Engineer license has long lapsed, not that I ever knew anything about bridge design, so this is mostly observational.