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. EveryJ5_*_TST_TAPPETIbranch is dead code here, andEN_BARRIERA = 0inpargen.prmkills the light-barrier alternative too.IF_BATT_AEI_GIU_X/_YandIF_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:
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:
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.