Skip to content

Working documentation

This page is generated from the project's working notes. It records a real retrofit in progress, corrections included. Anything marked 🔴 or ⚠️ is unresolved or carries a caveat - read those before acting.

Bringing the machine up on Mesa

11 September 2026. Grant: "How are we going to test the machine once we have the Mesa cards in place?"


The principle the whole plan runs on

⭐ Each stage may only be able to break what the previous stage already proved.

That is the entire design. It is why air comes on late and drives come on later, and why the interlocks get tested deliberately rather than discovered.

🔴 The corollary, and it is the one people skip: never let the first test of a subsystem be a test with energy in it. A drill valve proven with the air off tells you the wiring is right. The same test with air on tells you the wiring is right and costs you a drill if it is not.


Stage 0 — before a single wire is connected

The simulation must actually run. It never has.

python3 hal-lint.py && python3 ngc_lint.py nc_files/*.ngc && python3 test_gcode_tools.py
linuxcnc ~/linuxcnc/configs/tuchop-sim/tuchop-sim.ini

⚠️ Expect small errors on the first start. They are loud and cheap — LinuxCNC prints the offending line and refuses to start. Fix, rerun.

🔴 This is also the rehearsal for everything below. Every halcmd used in Stages 1-4 works identically in the sim, against LEDs instead of valves. Learn the tools where nothing can move.

Gate: the sim loads, the panel responds, halcmd sets moves a signal. ✅ Only then touch hardware.


Stage 1 — Mesa alive, nothing connected to the machine

Cards on the bench or in the Housing. Ethernet to the PC. No field connections. Drives unpowered. Air off.

mesaflash --device 7i76e --addr 10.10.10.10 --readhmid     # card and firmware
halrun -I                                                   # then:
  loadrt hostmot2
  loadrt hm2_eth board_ip="10.10.10.10" config="..."
  show pin hm2_7i76e.0.
Prove
The card answers, and the firmware is 7i76eu_7i76x1_7i77x1d.bin The one Mesa confirmed for this three-card chain
All three cards enumerate 7I76EU, 7I77U on P1, 7I84U on SSerial
Every expected pin exists A missing pin here is a firmware or cabling problem, not a config one
🔴 Servo thread jitter under 100,000 ns latency-test for at least an hour, ideally while something loads the PC

⚠️ Jitter is a go/no-go on the PC, not a tuning knob. If the rp5800 will not hold it under a Preempt-RT kernel, that is a hardware problem to solve now, not after everything is wired.

Gate: three cards enumerate and jitter is in spec. Nothing is connected to the machine yet.


Stage 2 — Inputs only. Air OFF, drives OFF, machine powered

Connect the input ribbons. Nothing else.

🔴 With no output ribbons connected, LinuxCNC physically cannot actuate anything. That is what makes this stage free.

Walk every one of the 44 inputs by hand — press each button, trip each sensor, block each photocell — and watch it in halshow or:

watch -n0.2 'halcmd show sig | grep in-'
Prove
⭐ Every input reaches the right pin This is the IF.n → Mesa channel map under test
⭐ Polarity is right on every N.C. input IF.7 HOLD, IF.9 vacuum, IF.33/IF.34 photocells are all normally closed — healthy reads TRUE
Input voltage and sourcing/sinking suit the card Already on the survey list; settle it before trusting a reading

⚠️ An input wired to the wrong channel is invisible until something depends on it. This is the cheapest hour in the whole project.

Gate: all 44 inputs identified and correct. Write the result into io-map.md against the Mesa channel.


Stage 3 — Outputs, electrically. Air STILL OFF, drives OFF

Connect the output ribbons.

halcmd sets drill-vert-1 1      # listen for the module relay
halcmd sets drill-vert-1 0

🔴 Air off means an energised valve does nothing physical. You are proving the electrical path only — Mesa to module relay to solenoid coil — one output at a time.

Prove
The correct module relay clicks for each output
⚠️ No output energises two things A crossed ribbon shows up here and only here
⚠️ Nothing is energised at power-on Watch the relays as LinuxCNC starts. An output that comes up hot is a config error you want to find now

Gate: all 41 outputs switch the right relay, and nothing is live at startup.


Stage 4 — Air ON, drives STILL OFF

Now the rams move. The gantry still cannot.

🔴 Do not run the drill block motor yet. Valves only.

Prove Settles
Each valve moves the ram you expect ⭐ Which output fires which physical spindle — the last open piece of the drilling geometry
IF.10 goes low when any unit drops, true when all are up The guard's whole foundation
IF.11 goes low as the blade leaves the top The saw's descent confirm
IF.26/27/28 follow the horizontal heads
The router ram plunges down and retracts And that Y201 holds position with both coils off
⚠️ The counter-pressure beam It is a retract hold-down, not a cut clamp — see drills-and-saw-on-linuxcnc.md

⭐ Time the strokes with halscope while you are here. That closes the dwell-tightening item and it costs nothing extra.

Gate: every actuator identified, every feedback input confirmed against it.


Stage 5 — 🔴 The drives. One axis at a time

This is the stage that can hurt the machine. Everything above was reversible.

5a. Prove the encoder BEFORE the motor can turn

🔴 Drive disabled. Move the axis by hand (or with the brake released and the drive off) and watch the count.

halcmd show pin hm2_7i77.0.encoder.00.position

⭐ This proves feedback polarity with no power to the motor at all. ⚠️ An inverted encoder is a runaway the instant you close the loop — the drive sees the error growing and drives harder. Catching it here costs nothing; catching it later costs a gantry.

5b. First enable, with the smallest possible authority

Before enabling, set up to fail safely:

MAX_VELOCITY A tenth of the intended value
FERROR / MIN_FERROR Tight. A runaway must trip on following error in millimetres, not metres
Analog output Confirm it sits at zero with the drive enabled and no command
⚠️ Hand on the E-stop Not a figure of speech. First enable of a servo is the one moment this matters

Then command 1 mm. Verify it moves 1 mm, in the direction the label says, and stops.

🔴 If it runs away, the following error catches it. That is what the tight setting is for.

5c. Then, per axis

  1. Direction sign — does + go the way the (newly relabelled) plate says?
  2. Scaling — set an arbitrary scale, command a long move, measure, correct. Cross-check against Pn201.
  3. Homing — ⚠️ the Y and Z search directions are suspect after the axis reversal. Re-derive, do not assume.
  4. Tuning — ⚠️ check the Z counterbalance pressure first. The original gains assumed a balanced carriage.

Gate: all three axes move accurately, home repeatably, and hold position.


Stage 6 — Spindle

No tool. Guard on. Run it up slowly.

Prove
The analog scale — commanded rpm against measured Laser tacho on reflective tape, VFD output frequency as the cross-check
IF.25 at-speed behaves
🔴 The 104 Hz floor n034 = 26% is a hard minimum. Commanding below it does not do what you expect
Stop, and the brake-resistor interlock

Stage 7 — ⭐ Test the interlocks deliberately. Do not skip this

🔴 A guard that has never been tested is a guard you do not have. Every one of these should be provoked and seen to work.

Provoke Expect
Jog with a drill commanded down 🔴 The jog is refused (motion.jog-inhibit)
Program motion with a drill down Motion held, releases when it comes up
Force motion with a unit down (override off) Guard trips, machine off, latched
Y move with the blade down Guard trips
Break a photocell mid-program Feed holds, resumes when cleared
Turn the override key Guard suspends, and the indicator shows it
Let go of the override key ⚠️ It clears itself — this is why it must be spring-return

⚠️ Log what each one actually did. If any behaves differently from the table, the config is wrong and the table is the specification.


Stage 8 — First cut

⭐ The first cut is also a measurement. Cut a test piece that yields, in one go:

The drill block ram stroke
The router ram stroke Separate number
The 35 mm and 10 mm spindle offsets Drill with each, measure where the hole landed, the difference is the offset
Squareness and scaling under load

🔴 Four deferred unknowns close on one piece of board. That is why they were deferred rather than guessed.


What to build before any of this

⭐ A bring-up config that loads Mesa but NOT motion Outputs can be exercised with zero possibility of axis movement. Stages 2-4 run on it. This is the single most useful thing to build next
A written I/O walk sheet 44 inputs and 41 outputs, printed, ticked off at the machine. Not a screen
The real machine config tuchop-sim with the sim loopbacks swapped for hm2_eth. The I/O logic transfers unchanged — that was the point of writing it first
  • retrofit-boundary.md — what is being touched, and what is not
  • mesa-wiring-schedule.md — the landing list this stage proves
  • io-map.md — the 44 in / 41 out being walked
  • linuxcnc-motion-pins.md — why the guards are built the way they are
  • servo-drive-interface.md — 🔴 read the counterbalance and brake note before Stage 5