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.

Zones, loading and the pedal protocol

3 September 2026. Mined from Mw310\Sv\MW310.PLC (JOB 5 supervisor, BLK_PZ_NORMALE, JOB 9 HOLD), Mw310\Sv\MW310.EQU and Param\pargen.prm. Nothing here required touching the machine.

This is the block plc-sequences.md listed as "still to mine". It turns out to answer, on its own, two of the open questions on that document's list.


1. The table is two zones, and that is the whole shape of the machine

Parameter Raw Meaning
Q.PARK X Z.1 (VP.981) 280000 X park for zone 1 = 2800.00 mm
Q.PARK X Z.2 (VP.982) 0 X park for zone 2 = 0.00 mm
X MAX Z. 1 (QMAX_Z1, VP.985) 182830 Zone 1 ends at 1828.30 mm
X MIN Z. 2 (QMIN_Z2, VP.986) 183910 Zone 2 starts at 1839.10 mm

The two zones split the 2800 mm bed at roughly its middle. Each parks the gantry at the far end of the machine from itself, which is what clears the operator's half.

The midline is computed, not configured

The obvious reading is that QMAX_Z1 is the boundary. It is not, and the PLC says so in a version note:

;*** 3.82 (FAX) : NON TESTO PIU'IL PARAMETRO MACCHINA QMAZ_Z1, MA LA MEDIA
;*** TRA QMIN_Z2 E QMAZ_Z1

"From version 3.82 I no longer test the machine parameter QMAX_Z1, but the mean of QMIN_Z2 and QMAX_Z1." The arithmetic is explicit:

COPY   0,VAPP_RDQ
ADD    QMIN_Z2,VAPP_RDQ
ADD    QMAX_Z1,VAPP_RDQ
SFRX   1,VAPP_RDQ                 ;shift right 1 = divide by 2

So the working midline is (1828.30 + 1839.10) / 2 = 1833.70 mm, held in VAPP_RDQ. QMAX_Z1 and QMIN_Z2 survive as the soft limits of each zone; the midline is the single crossing point.

โš ๏ธ Do not carry the 1828.30 / 1839.10 pair into LinuxCNC as a boundary pair. One number, 1833.70 mm, is what the machine actually used.


2. Two zones, but only two fields

The software supports up to twelve fields (A-L). MW310.EQU shows which exist here โ€” everything else is mapped to the OF.254 / OF.255 not-present sentinel:

Output Address Function
OF_RIF_X_CAMPO_AEI OF.29 X datum stop, zone 1
OF_RIF_X_CAMPO_DHL OF.30 X datum stop, zone 2
OF_RIF_Y_CAMPO_A OF.6 Y datum stop, zone 1
OF_RIF_Y_CAMPO_E OF.6 same solenoid - E is an alias for A
OF_RIF_Y_CAMPO_D OF.7 Y datum stop, zone 2
OF_RIF_Y_CAMPO_H OF.7 same solenoid - H is an alias for D
OF_SBLOCCO_CAMPO_AEI OF.2 workpiece release, zone 1
OF_SBLOCCO_CAMPO_DHL OF.3 workpiece release, zone 2
OF_LAMPADA_AEI OF.8 zone 1 lamp
OF_LAMPADA_DHL OF.37 zone 2 lamp

B, C, F, G, I, J, K, L have no output assigned at all. So the wiring gives one X stop and one Y stop per zone, four solenoids in total โ€” and A/E share one Y solenoid, D/H share the other.

This does not agree with BATTUTE.PRM, and the wiring wins

Param/BATTUTE.PRM carries datum coordinates for six fields โ€” A, B, C, D, E and H (plc-sequences.md has the grid). Two of those, B and C, have coordinates but no solenoid. The PLC cannot raise a stop it has no output for, so those rows are configuration for hardware that was never fitted โ€” a factory default left in place rather than a description of this machine.

โš ๏ธ Where the two disagree, MW310.EQU is the harder evidence. It is what the PLC actually drives, and it was saved in 2017; BATTUTE.PRM is a coordinate table the interpreter reads.

The X column does line up cleanly with the zones, which is a good cross-check on the whole model:

Field Datum X Zone (split at 1833.70 mm)
A, B, E 120.00 mm zone 1
C, D, H 2910.90 mm zone 2

โš ๏ธ The fourth column (A=2, B=3, C=2, D=3, E=0, H=1) is still unidentified. It is not a Y index โ€” A and B share a Y coordinate but differ in it. Left open.

So for practical purposes TuChop is field A in zone 1 and field D in zone 2: one datum corner per zone, one clamp zone per zone, one lamp per zone.

That kills a whole class of PLC code as irrelevant: MDUE_CAMPI_ZONA1, MEM_AB_CORTI, MPRIMO_CAMPO_ZONA1, the four-pedal MPEDALE_AB / _ABC / _ABCD memories, and every #if 2CAMPI ... #else alternative branch. Do not port any of it.

The one composite that does apply is (AD) โ€” a single panel long enough to span both zones. MCAMPO_AD selects it, both zones' stops rise together, and both pedals are enabled at once.


3. Sensors and interlocks that exist, and the ones that do not

Signal Address Notes
IF_START_ZONA1 IF.1 green start button, zone 1
IF_START_ZONA2 IF.2 green start button, zone 2
IF_BLOCCO_AEI IF.3 clamp pedal, zone 1 (N.O.)
IF_BLOCCO_DHL IF.4 clamp pedal, zone 2 (N.O.)
IF_FOTOC_Z1 IF.33 zone 1 photocell (N.C.)
IF_FOTOC_Z2 IF.34 zone 2 photocell (N.C.)
IF_CONTR_VUOTO IF.9 vacuum healthy (N.C.)

Not fitted (all OF.254):

  • IF_TAPPETO_A / _INT / _D โ€” pressure-sensitive safety mats. TuChop has none; the photocells do that job. Every J5_*_TST_TAPPETI branch is dead code here, and EN_BARRIERA = 0 in pargen.prm kills the light-barrier alternative too.
  • IF_BATT_AEI_GIU_X / _Y and IF_BATT_DHL_GIU_X / _Y โ€” stops-down confirmation switches.

๐Ÿ”ด That second one is the important negative. The machine has no sensor telling it the stops have retracted. machine-timings.md inferred this from the fact that TM11 had to be a dwell rather than a timeout; MW310.EQU now says it outright. The PLC sets TWTT_IF_BATT_A to "wait for the stop inputs", and on this machine that wait resolves against nothing โ€” the TM11 = 1500 ms delay is the only thing standing between "stops commanded down" and "axes may move".

Keep that number honest in LinuxCNC. It is not a guess and it is not padding; it is the entire stop interlock.


4. The pedal protocol

BLK_PZ_NORMALE is the branch that applies (the GESTIONE_ISO_BR branch is the B&R sub-platen option โ€” see corrections). The pedal is gated, not free-running:

MBLOCCO_A = IF_BLOCCO_AEI AND NOT MCONTR_BLOCCO_A

MCONTR_BLOCCO_A is the PLC's inhibit; the supervisor clears it (RES MCONTR_BLOCCO_A ;abilito press. pedale A) only when a load is actually expected. Pressing the pedal at any other time does nothing at all.

Once enabled, the cycle is driven by edges of the pedal, with the current stop position choosing which of two things happens. MBATTUTAX_AEI is the machine's memory of "stops are up".

Stops DOWN

Edge Action
press nothing (falls straight through)
release raise X stop, raise Y stop, release the vacuum, raise the panel lifters

The table is now floating and the datum corner is standing proud. The operator slides the panel in and pushes it into the corner.

Stops UP

Edge Action
press mark the zone occupied, release the vacuum, drop the panel lifters
release apply the vacuum, set MBLOCCO_PEZZO (START now permitted), light the zone lamp, arm the wait-for-stops-down flag

So it is a genuine two-press cycle: press-and-release once to open the zone up for loading, press-and-release again to set the panel down and clamp it. The lamp coming on is the machine's "you may press START".

Output polarity is fail-safe, and inverted from its name

OF.2 is named SBLOCCO_CAMPO_AEI โ€” unblock field A. The PLC SETs it to free the panel and RESets it to hold:

SET  TOF_SBLOCCO_CAMPO_AEI      ;setto il vuoto A/E/I   (panel free)
RES  TOF_SBLOCCO_CAMPO_AEI      ;resetto il vuoto A/E/I (panel held)

โš ๏ธ Energised = released. Lose the 24 V and the panel stays clamped. Preserve that sense in LinuxCNC โ€” inverting it to the more natural-reading "energised = clamped" would make a power failure drop the workpiece.

One special case worth knowing about

For a rotary block (BLK_ROTATIVO_A, bit 4 of VTIPO_BLK_AB) that is not the first part of a run, TBLK_ROT_A is set โ€” "blk. pz con una sola pedalata", clamp with a single pedal press. The two-press cycle collapses to one because the stops were already raised at the end of the previous program. TuChop's normal-block path does not use this, but if a rotary fixture ever appears the shortcut is there in the original.


5. Who raises the stops: it is configurable, and both answers are right

This settles the open question plc-sequences.md recorded as "which stop branch applies โ€” pedal or program". Both do. It is a per-field setting.

;*** SE VBATT_Y_SU_END SETTATA (AUTO), LE BATTUTE SONO ALZATE A FINE PRG.
;*** (CIOE'AL CARICO DEL SUCCESSIVO) E NON ALLA PRESSIONE DEL PEDALE

The PLC's own bit table says the same thing in as many words:

;*** TABELLA BATTUTE Y (VBATT_Y_SU_END) : SE BIT A 1 LA BATTUTA DEL CAMPO
;*** INDICATO DEVE SALIRE A FINE PROGRAMMA (AUTO)
;*** SE BIT A 0 (PEDALE) LA BATTUTA DEL CAMPO INDICATO DEVE SALIRE DOPO IL
;*** RILASCIO (PEDALE)

VBATT_Y_SU_END is VV.34, one bit per field:

Mask Field Bit set Bit clear
BATT_Y_A_SU = 01H A AUTO โ€” stop rises at the end of the previous program PEDAL โ€” stop rises on pedal release, per ยง4
BATT_Y_B_SU = 02H B (not fitted)
BATT_Y_C_SU = 04H C (not fitted)
BATT_Y_D_SU = 08H D AUTO PEDAL

โœ… And the operator screen has the same two words on it. English/messaggi.txt and Italiano/messaggi.txt carry PEDAL / PEDALE and AUTO adjacent in the clamping-setup block (ยง10 below). Three independent sources agree.

AUTO saves a pedal press per part; PEDAL leaves the table flat until the operator asks for it. The setting comes down with the part program, not from pargen.prm.

On the very first part of a run โ€” no previous program to have raised anything โ€” the macro BATT_SU_PRIMA_VOLTA_Z1 raises them unconditionally, in both modes.

For LinuxCNC: implement PEDAL as the base behaviour and treat AUTO as an option, because PEDAL is the mode where the operator's hands and the stops are interlocked by a single deliberate act. M101 P<zone> already gives the program the AUTO path if it is wanted.

Grant's pedal test still settles which mode this machine was last configured for, and is still worth doing โ€” but whichever way it goes, neither branch is wrong.


6. Pendulum working

MMEM_PENDOLO distinguishes the two ways of running:

  • SEQUENZA โ€” one zone at a time. At the end of a program the axes park and both zones are released.
  • PENDOLO โ€” the operator loads one zone while the machine cuts the other.

The handshake is a position, not an event

In pendulum mode the supervisor sits in J5_PARK_Z1_WTT_QUOTA (or _Z2) reading the U axis every PLC scan and comparing it against the midline:

RDQ    ASSE_U,VPOS_ASSE_U
CMP    VAPP_RDQ,VPOS_ASSE_U
JPGT   J5_MEZZERIA_Z1             ;jump if U has crossed

The moment the gantry crosses 1833.70 mm, the zone it has left is released โ€” vacuum dumped, lamp lit, pedal enabled โ€” while the program carries on cutting in the other zone. No parking move, no dwell, no operator action. That single comparison is the whole of pendulum working.

Occupancy lives in V_STATO_GEN (VV.87), the word shared with the interpreter side:

Bit Name
0 END_PRG
1 ABILITA_END_CYCLE
2 MSG_START
3 MSG_MANUALE
4 zone 1 occupied
5 zone 2 occupied
6 loader: start of loading
7 loader: start of program
8 MSG_PIANETTI
9 manual tool-change message
10 SMON_CU_MAN
11 zone 1 selector high
12 zone 2 selector high
13 carousel reset
14 mats error

Crossing the midline clears bit 4 or bit 5. Pressing the pedal in a zone sets it again (ORX SET_Z1_OCCUPATA,V_STATO_GEN).

If the gantry never crosses, that is an error

;*** 2.01 SE DURANTE L'ESECUZIONE DEL PROGRAMMA IN ZONA 1 L'ASSE U NON VA
;*** MAI AL DI SOTTO DELLA MEZZERIA, A PROGRAMMA TERMINATO ... SETTO L'ERRORE 2.1.1076

Faults 1075 and 1076 ("impossible to release area 1 / area 2") are exactly this: a pendulum program whose toolpath stayed entirely on one side of 1833.70 mm, so the release never fired. plc-fault-codes.md had the English text; this is the cause.

โš ๏ธ A LinuxCNC implementation needs the same guard. A short program that never crosses the midline will silently leave the other zone locked, and the operator will be standing at a dead pedal with no message.

Booking the next zone

MPREN_START โ€” prenotazione โ€” lets the operator press START on a zone they have just loaded while the other zone is still cutting. The supervisor remembers it and starts that zone the instant the current program ends, with no second press.

The ABILITA_PREN macro is what opens a zone up after a release: enable that zone's pedal, enable its START, enable booking, light its lamp, extinguish the other zone's lamp, and start the lamp flasher (JOB 7). The lamp is the interface. Steady = clamped and ready; flashing = this zone is yours; dark = keep out.

Tool changes respect the zones

;*** TIPO_MOV = 2 MOV U A QMAX_Z1-50 mm  (FINE C.U.)
;*** TIPO_MOV = 3 MOV U A QMIN_Z2+50 mm  (FINE C.U.)

If a tool change happens during pendulum work and the spindle ends up outside its own zone, the U axis is pulled back to 50 mm inside the zone boundary before cutting resumes. Worth reproducing โ€” it stops the gantry idling over the operator's half after a tool change.


7. The photocells are maskable, per zone

JOB 9's HOLD chain, in full:

MFOTOC_Z1 = IF_FOTOC_Z1 OR NOT MCONTR_FOTOC_Z1
MFOTOC_Z2 = IF_FOTOC_Z2 OR NOT MCONTR_FOTOC_Z2
MHOLD     = MFOTOC_Z1 AND MFOTOC_Z2 AND IF_HOLD

All three inputs are N.C., so MHOLD high means healthy.

The MCONTR_FOTOC_Zn bits arm each beam independently. With MCONTR_FOTOC_Z1 clear, the OR pins MFOTOC_Z1 high and zone 1's beam is ignored entirely.

That masking is not a nicety โ€” it is what makes pendulum working possible at all. The operator loading zone 1 is standing in zone 1's beam for the whole load. Without the mask, every load would hold the program running in zone 2.

A previous version of the sim's HOLD chain was missing this. It ANDed both beams unconditionally, which is correct for sequence working and would have made pendulum working unusable. Fixed โ€” see the sim's section 7.

The same inputs mean different things in different modes

Machine state Beam broken or HOLD pressed
running a program feed hold
jogging or stepping THOLD
during a manual reset TEMERG โ€” full emergency

The third row is deliberate. During a reset the machine may move without a program's knowledge, so the beams are promoted from hold to emergency.


8. What this changes in the simulation

File Change
tuchop-io.hal photocells given per-zone arming, matching MCONTR_FOTOC_Zn
tuchop-io.hal zone-occupancy bits added, set by pedal and cleared at the midline
tuchop-io.hal midline crossing detector at 1833.70 mm

9. Still open

Question How it gets settled
Which stop mode (AUTO / PEDAL) this machine was last set to Grant's pedal press, still worth doing
EN_BARCODE = 2 with no barcode reader visible โœ… Downgraded โ€” the PLC never reads it (ยง11). Vestigial unless a reader turns up
Third column of BATTUTE.PRM Unidentified
EN_CAMPO_INT = 1 (intermediate field) โœ… Closed โ€” the string appears nowhere in the PLC (ยง11). Interpreter-side only

Closed by this document: the stop branch question, MAX.P.Z1.N.P (below), and the source of faults 1075/1076.

MAX.P.Z1.N.P โ€” resolved as "not the PLC's business"

machine-parameters.md listed MAX.P.Z1.N.P = 90000 (900.00 mm) as purpose-unknown. It has no VP. symbol anywhere in MW310.PLC โ€” the parameter block runs VP.981-VP.999 with VP.995 and VP.1000-VP.1012 unassigned, and neither panel-length limit appears. Nor does L.MAX.PAN.Z1.

So both are read by the interpreter / HMI side only, not the PLC. They are program-acceptance limits โ€” the size of panel the software will let you declare in a zone โ€” not anything the real-time logic enforces. Nothing to port into HAL or ClassicLadder; if the limits matter they belong in the CAM post or a G-code preamble check.


10. The clamping setup screen, recovered

English/messaggi.txt and Italiano/messaggi.txt are the HMI string tables. One contiguous run of them is the clamping configuration page, and it lines up one-for-one with the PLC's bit tables. Together they give the complete specification of what an operator could configure per field โ€” which is exactly what a LinuxCNC replacement has to expose.

Clamping type โ€” VTIPO_BLK_AB (VV.32) and VTIPO_BLK_CD

One byte per field, one bit per type. Zone 1 is byte 0 of VTIPO_BLK_AB; zone 2 is byte 1 of VTIPO_BLK_CD.

Bit Mask (field A) Italian English (from the HMI) PLC branch
0 01H NORMALE STANDARD BLK_PZ_NORMALE โ† this machine
1 02H PIATTELLO PLATE BLK_PZ_PIATTELLO
2 04H INTERNO INTERNAL BLK_PZ_INTERNO
3 08H MECCANICO MECHANIC BLK_PZ_MECCANICO
4 10H BATTUTA ROTATIVA ROTARY STOP the TBLK_ROT_A one-press shortcut in ยง4
5 20H PEZZI STRETTI NARROW PIECES BLK_PZ_STRETTO โ€” raises only the X stop, not Y
6 40H BLOCCAGGIO DIME TEMPLATE CLAMPING BLK_PZ_DIME
7 80H STAFFE BRACKETS BLK_PZ_STAFFE โ€” the fall-through default

Fields B and C occupy bits 8-15 of the same words and are not fitted here.

The four per-field toggles

Each is a four-bit word, bit 0 = field A through bit 3 = field D.

Word Address HMI label What it gates
VTIPO_VUOTO VV.33 Vuoto / Vacuum whether this field uses vacuum at all (MFLAG_VUOTO_A)
VBATT_Y_SU_END VV.34 Battute XY / XY Stops, with PEDALE / AUTO ยง5
VALZAPANNELLI VV.35 Alza pannelli / Workpiece lift the panel lifters (TFLAG_ALZAP_A)
VANUBA โ€” Piano anuba / Anuba table hinge-boring table. EN_PIANO_AN = 0 โ€” not fitted

โœ… "Workpiece lift" independently confirms the pedal protocol in ยง4. The lifters are a real, separately-configurable function, and the two-press cycle raises them for loading and drops them before clamping. That was inferred from M_ALZAPANNELLI_AEI; the HMI names it.

What to carry into LinuxCNC

TuChop runs STANDARD clamping, so seven of the eight branches are dead code. But the four toggles are live and worth keeping as a per-zone configuration, because they are what a job actually varies:

Keep Because
Vacuum on/off per zone A jig or template job may not use it
Stops AUTO/PEDAL per zone Genuinely changes the operator's hand sequence
Workpiece lift on/off per zone A heavy panel needs it; a small one does not
Anuba table โŒ Drop. Not fitted

The natural home for all four is a G-code preamble or an INI section, not HAL โ€” they are per-job settings, not real-time logic.


11. Three more parameters that the PLC never reads

MAX.P.Z1.N.P turned out to be interpreter-side only (ยง9). Checking the rest of the unknowns the same way:

Parameter pargen.prm Appears in MW310.PLC?
MAX.P.Z1.N.P / Z2 90000 โŒ no VP. symbol
L.MAX.PAN.Z1 / Z2 120000 โŒ no VP. symbol
EN_CAMPO_INT 1 โŒ the string appears nowhere in the PLC
EN_BARCODE 2 โŒ only in a comment saying VEN_BARCODE is no longer used

All four are read by the interpreter / HMI, never by the real-time logic. None of them needs porting into HAL or ClassicLadder. If the panel-size limits matter operationally they belong in the CAM post or a G-code preamble check; EN_BARCODE = 2 on a machine with no visible reader is best treated as vestigial until one turns up.