mcplc edits the HAL of a machine like a PLC program, after the pattern
of SINUMERIK/TIA Portal: program blocks of networks, each a function
block diagram (FUP) of instruction boxes (&, >=1, =1, SR, TON,
comparators, arithmetic …) and HAL components wired by signals, with
pins of the machine’s base components (motion., halui., joint.N.)
and named signals as operands. The project (.hpj, JSON) is the source:
the HAL file is generated from it, and existing HAL files are imported
into networks. With LinuxCNC (or halrun) running, the live view colours
true bits green and shows the values at the pins. Start with
mcplc [project.hpj | file.hal]; mcplc file.hal --generate out.hal
regenerates without the window (man page mcplc(1)).
Window
-
Projektnavigation (left): the project with its Baugruppen (the base HAL lines:
loadrtof motion, kinematics, drivers, theiraddf), the Programmbausteine with their networks, Geraete & Netze (the configured cards with their daughter cards), the IO-Variablen, the SCL blocks (stage 2) and the Variablentabelle (all signals of the project). -
Editor (centre, tab Programmbausteine): the networks of the selected block stacked, each with its title and comment; a toolbar with the frequent instructions (
&,>=1,=1,NOT,SR,TON), the operands (pin, signal, constant) and the FUP/KOP switch. The Info pane shows the pins of the selected box, messages and the HAL preview. -
Geraete & Netze (centre, second tab): the hardware view, see Devices and networks (hardware).
-
Anweisungen (right): the instruction palette by groups (Bitverknuepfungen, Zeiten, Flanken, Vergleicher, Mathematik, Verschieben, Filter, Sicherheit), all HAL-Komponenten of the library with their pins, and the operands; a double click inserts into the selected network. The search field above filters by symbol, name, component or description (several words narrow down; Return inserts the first hit).
-
Testen (right): the live view switch, setting a pin/signal value (
setp/sets), the list of the running HAL’s pins. -
Hardware-Katalog (right): the Mesa cards and daughter cards of the catalogue with their firmware variants; a double click adds a card to Geraete & Netze.
Editing
Boxes show the names of their inputs and outputs inside, as TIA Portal
does (IN1, IN2, OUT; S, R1, Q; IN, PT, Q, ET; the pin
names of a HAL component), and are dragged on a grid. A wire is pulled
like in TIA: press on an output port, drag to the input port (the target
is ringed while dragging) and release - releasing on a box picks its
nearest free input, releasing on an operand connects the operand. A
click on a port followed by a click on another port wires them as well.
Resting the mouse on a port shows an info box with its name, data type
(Bool/Real/DInt/UDInt with the HAL name bit/float/s32/u32), direction
and HAL pin; the type of an operand comes from the library, the running
HAL or the configured hardware. While pulling, the target is ringed when
the types fit and crossed with a red X when they do not (a float
output onto a bit input, say) - such a wire is refused, as is wiring
two inputs together; a constant fits every type it can be written as.
An output may feed several inputs. A click selects a box or operand
(bold blue frame) or a wire (bold line); Entf deletes the selection -
a wire’s target leaves the signal, the other endpoints stay connected, a
box goes with all its wires. Inputs and in/out pins sit on the left of a
box, pure outputs on the right. Operands are edited by a double click (pin names come
from the running HAL or from the library’s patterns). The context menu
of a box adds or removes inputs of &/>=1/=1, negates an input
(drawn as a circle, generated as a not instance), renames the HAL
instance and edits the parameters written with setp; the context menu
of a wire names its signal or removes it; the context menu of the
background inserts, edits, disables or deletes networks and runs the
automatic layout. Ctrl+Z/Y undo and redo.
Instructions and HAL
| Box | HAL component | Note |
|---|---|---|
|
|
personality = function + number of inputs (2..16) |
|
|
|
|
|
S = set, R1 = reset (dominant), Q, QN |
|
|
|
|
|
PT in seconds on the |
|
|
pulse of PT seconds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
any library component |
the component with all its pins |
The generated file holds the device lines (Devices and networks (hardware)) and the
base lines first, then one loadrt … names=… per component with all
instances of the networks, addf in block and network order on the
block’s thread (the read functions of the cards before, their write
functions after everything else), the net lines of the IO variables,
and per network the setp of constants and parameters and the net
lines: a connected group of wires is one signal, named by the user, by a
signal operand, or after its driving pin. Instances without a name get
<box>-<block>-<network>-<k>; a negated input becomes a not instance
in the generated file only, the project keeps the circle.
Threads: fast for the drives, slow for the PLC
Time-critical functions - the trajectory planner (motion-controller,
always in motmod’s servo thread), the PID loops, the read/write
functions of the cards and the probe input - run in the fast thread;
the PLC logic (interlocks, emergency stop chain, operator panel, spindle
enables, tool change sequences) runs in a slow one. The project keeps
a thread table (Bearbeiten > Threads (Zykluszeiten), also the node
Threads of the navigation): name and period. A new project has
servo-thread 1 ms (created by motmod from [EMCMOT]SERVO_PERIOD) and
plc-thread 10 ms; more can be added (a 0.25 ms fast-thread for an
encoder filter, say). HAL wants the fastest thread first and the others
as integer multiples; the generator writes
loadrt threads name1=plc-thread period1=10000000
for the threads no base component creates, fastest first, after the base
loadrt lines (a project without motmod gets all its threads from this
line). Each block has a thread (Bearbeiten > Thread des Bausteins;
new PLC blocks take the slowest), and a network may override it
(context menu Netzwerk-Thread, shown as a clock mark and the thread
name at the right of the network header) - the probe network in a PLC
block goes to the servo thread this way. Per thread the generated order
is: card read functions, motion, the instances of the networks in
block and network order, card write functions. Signals between
threads are plain HAL signals. The CNC assistant (The CNC assistant)
puts the axis, spindle and probe networks in the fast thread and the
emergency stop chain in the PLC thread, and writes [EMCMOT]SERVO_PERIOD
and PLC_PERIOD into the INI.
HAL files as units (OB) and folders
A project is made of units, one per HAL file, the way a Siemens
program is made of organisation blocks: Bearbeiten > HAL-Dateien
(Einheiten) lists them with their kind - hal (loaded by the run
script, [HAL]HALFILE), postgui (loaded after the GUI,
[HAL]POSTGUI_HALFILE, the place for panel pins) or external (a
Tcl/LIB: file that stays untouched in the INI). Every block belongs to
a unit (HAL-Datei des Bausteins) and may sit in a folder path
(Ordner des Bausteins, Zylinder/Vorschub), both shown in the
navigation. The generator writes one file per unit: the first carries
the devices, the base lines, the threads and every loadrt (a module
loads only once), each file the addf/net/setp of its blocks, and
the card write functions close the last pre-GUI file. HAL-Datei(en)
generieren asks for a directory when there is more than one unit;
mcplc project.hpj --generate DIR does the same without the window. The
CNC assistant writes the matching HALFILE/POSTGUI_HALFILE lines.
Ladder view (KOP)
The FUP/KOP switch of the toolbar changes how a block’s networks are
drawn; the graph behind them is the same, and the generated HAL does not
change. In KOP a network is drawn between the power rails: bit operands
that feed & boxes become contacts in series (--| |--), those
feeding >=1 boxes parallel branches, a negated input an open
contact (--|/|--), NOT boxes vanish into the contacts, a written
bit operand becomes a coil (--( )--) at the right rail. Other boxes
(=1, SR, TON, counters, components, FB instances) stand in the rung
with their bit inputs fed by contact logic, their other inputs by
operands and their outputs feeding coils. A network without that form -
arithmetic and float signals only - keeps its FUP drawing inside the KOP
block with a note, as TIA Portal refuses such a switch.
Editing in KOP works on the graph: --| |-- inserts a contact in series
with the selected one (an & appears in FUP), --|/|-- an open one,
--( ) a coil driven by the selected contact or box output, Zweig a
parallel branch to the selected contact (a >=1); the context menu of a
contact swaps closed and open (the negation of the input it feeds, or a
NOT before its coil). With the live view on, contacts, rung lines and
coils are green when their signal is true.
Function blocks (FB) and data blocks (DB)
The context menu of Programmbausteine (and of a HAL file, a folder or a block in it) offers Neuer Programmbaustein, Neuer Funktionsbaustein (FB), Neuer Datenbaustein (DB) and Neuer Ordner, as the TIA Portal project tree does.
A function block is a block with an interface (context menu
Schnittstelle…): parameters with a name, a direction - in, out,
inout or static (a memory of the instance) -, a data type
(Bool/Int/DInt/UInt/UDInt/Real/Time, mapped to bit/s32/u32/float), a
start value and a comment. Inside the FB the parameters are operands
#name (toolbar #Param): an input is a source on the right, an output
a target on the left, inout and static both. The FB appears in the
palette under Eigene Bausteine (FB); a double click puts an instance
into the current network, named like an instance DB (zyl1), drawn as a
box with the interface parameters as ports and typed like any other
box. A cylinder control with five inputs and two outputs is written
once and used as often as needed; FBs may use other FBs (recursion is
refused). There is no separate FC: an FB without static parameters is
one.
The generator expands every instance: the networks of the FB are
copied behind the calling network (titled zyl1: Ventil), their HAL
instances get the instance name as prefix (zyl1-ton-2), the
parameters become signals zyl1-start, zyl1-ventil … and the ports
of the instance box are replaced by signal operands of the same names,
so a wire group stays one signal; a user-named signal on an instance
port keeps its name. A constant on an instance parameter becomes
newsig/sets in the first HAL file. Instanz oeffnen is not needed:
the generated file shows the expanded networks.
A data block is a table like in TIA (double click on the DB): Name,
Datentyp, Startwert, Remanenz, Kommentar, with Struct elements that
hold children and Array[lo..hi] elements. Every leaf is one typed HAL
signal - dbDaten.zaehler, dbDaten.pos.x, dbDaten.flags.3 - created
in the first HAL file with newsig (HAL’s current type names bool,
sint, uint, real) and, with a start value, sets.
Networks read a DB element through a signal operand of that name (the
signal browser lists all DB elements with their types, so the type
check applies) and write it with a wire from an output onto the
operand; HAL allows one writer per signal. String, Char and Date do not
exist in HAL and are refused. The Remanenz column is stored; saving
and restoring retentive values comes with a later step. With the live
view on, the DB table shows the actual values.
PLC variable tables
PLC-Variablen (navigation node and centre tab) lists every variable
of the project with its table, data type, address and comment: the
signals of the networks, the IO variables with their terminal pin as
address, and the DB elements. The Standard-Variablentabelle holds all
variables by default; Neue Variablentabelle adds tables to structure
them (Sicherheit, Hydraulik …), and a double click on the
Variablentabelle cell of a row opens the dropdown that assigns the
variable, like in TIA; a double click on the comment edits it. The
navigation shows every table with its count, Alle Variablen anzeigen
the whole list.
Import of HAL and INI files
Projekt > INI importieren reads a machine’s INI: every HALFILE and
POSTGUI_HALFILE becomes a unit with one block ([HAL]HALCMD lines a
unit halcmd.hal, Tcl/LIB: files external units), [EMCMOT]
SERVO_PERIOD/BASE_PERIOD the thread periods, [DISPLAY]PYVCP /
GLADEVCP and loadusr pyvcp/gladevcp lines the panels whose pins
(pyvcp.spindle-at-speed, gladevcp.x_plus) are read from the panel
files and known to the pin browser. The components of the base lines -
loadrt of motion/kinematics/drivers and loadusr programs such as
halui, hal_manualtoolchange, pyvcp - are listed under
Baugruppen > Komponenten with their pin names (from the library or the
running HAL). mcplc machine.ini opens the import directly; the project
is saved next to the INI.
Projekt > HAL-Datei importieren reads loadrt/addf/net/setp:
instances of catalogue components become boxes (a logic with
personality 0x103 is a three-input &, a timedelay with off-delay
set a TOF …), other library components generic boxes, pins of base
components operands, setp on an instance pin a constant. Networks are
the connected groups of instances over the nets; a net without
instances is a network of its own. The comment above a net becomes the
network title. The round trip import - generate keeps every net with its
pins (tests/mcplc).
The library
Pins, parameters and functions come from the .comp sources of
src/hal/components, from the man pages of the C components and, when
connected, from the running HAL (hal.get_info_pins); the result is
cached in ~/.config/mcplc/components.json (Online > Bibliothek neu
einlesen).
Devices and networks (hardware)
The tab Geraete & Netze assembles the hardware like the device view of TIA Portal: the PC with its servo thread, the Mesa FPGA cards on their bus (PCI or Ethernet) and the daughter cards hanging on the sserial channels (RJ45/DB25) of a card. A double click on a card in the Hardware-Katalog adds it; a click selects it and shows its properties:
-
Firmware / Konfiguration: the firmware variant decides what the connectors carry. A 5i25 with
7i76x2has ten step generators and two encoders for two 7i76 stepper cards; with7i77x2six encoders for two 7i77 servo cards with analogue outputs;7i77_7i76one of each,G540x2,prob_rfx2… Changing the firmware changes the pins of the card and the sserial channels on which daughter cards fit. -
the number of used step generators, encoders and PWM generators (
num_stepgens=,num_encoders=,num_pwmgens=); the pins of the unused channels are plain GPIO. -
IP-Adresse (Ethernet cards,
board_ip=) and the watchdog timeout. -
one combo box per sserial channel with the daughter card and its mode (
7i76mode 0/2,7i77mode 0/3,7i73mode 1,7i84,7i70,7i71,7i69,7i64,8i20); a 7i77 occupies its channel and the next one (analogue part). Changing the firmware puts the cards it was made for on the channels. The result is thesserial_port_0=string with one digit (the mode) per channel of the firmware,xfor an unused channel.
The config string is shown at the bottom of the properties and goes into the generated HAL as
loadrt hostmot2 loadrt hm2_pci config="num_encoders=6 num_pwmgens=0 num_stepgens=5 sserial_port_0=00x0x" loadrt hm2_eth board_ip="10.10.10.10" config="num_encoders=2 num_pwmgens=0 num_stepgens=10 sserial_port_0=0x0x" setp hm2_5i25.0.watchdog.timeout_ns 5000000 addf hm2_5i25.0.read servo-thread # first in the thread ... addf hm2_5i25.0.write servo-thread # last
(a 5i25 with 7i77_7i76: the 7i77 on P3 takes channels 0 and 1, the
7i76 on P2 channel 3; firmware= is written for boards that load their
firmware over the bus, not for the 5i25/6i25/7i90 with it in flash or
for Ethernet boards). All HAL pins of the configured hardware
(hm2_5i25.0.stepgen.00., hm2_5i25.0.encoder.00.,
hm2_5i25.0.gpio.014.in, hm2_5i25.0.7i77.0.0.input-05,
hm2_5i25.0.7i77.0.1.analogout0, hm2_5i25.0.7i76.0.3.spinout …) are
known to the pin browser with their direction and their location
(connector pin or terminal).
Finding cards
Karten suchen… finds the cards of the computer: PCI through lspci
(Mesa’s vendor id 0x2718 and the older boards behind a PLX bridge with
their subsystem ids, as hm2_pci knows them) and Ethernet through an
LBP16 board-info read on UDP port 27181 - the same packet hm2_eth
probes with - sent to every host of the given /24 subnets in parallel
(the host’s own networks plus Mesa’s defaults 10.10.10.0/24 and
192.168.1.0/24 are preset). Firmware der Karte lesen runs mesaflash
--readhmid on the selected card and matches its pin table (StepGen,
QCount, PWM, SSerial per I/O index) against the catalogue’s firmware
variants; a known variant is set, an unknown one is written as a user
catalogue file to ~/.config/mcplc/hardware/mesa-<board>-<name>.xml
with the pins read from the card, and the card appears with that
variant. Einfuegen puts the card into Geraete & Netze with its IP.
Flashing (mesaflash)
Firmware… on a selected card opens the mesaflash dialog: the bitfile
(preset from the variant’s file in /lib/firmware/hm2/<board>/, or
any .bit), Info (--info), Pinbelegung lesen (--readhmid, offers
to switch the project to the variant found), Schreiben (--write,
verified by mesaflash; Fallback-Bereich adds --fallback), Pruefen
(--verify), Neu laden (--reload), Reset, Backup
(--backup-flash), sserial-Karten (--sserial) and, for Ethernet
cards, IP setzen (--set ip=). PCI cards need root: mcplc runs
mesaflash through sudo -n (or pkexec); without the right it prints
the command to run by hand, and without mesaflash installed it prints
the command as well. After a successful write the card’s variant in the
project is switched to the one the file belongs to, so the pins follow.
IO variables
The table IO-Variablen gives terminals symbolic names, like the PLC
tag table: a name (the HAL signal), the terminal pin, type and comment.
Alle Klemmen anlegen creates one per input/output terminal of the
selected card (i525_input00 = hm2_5i25.0.7i77.0.0.input-00,
q525_output03, i525_gpio014 …), the names are edited by a double
click. The names are operands in the networks (signal operand) and are
generated as net <name> <pin>, so the networks never carry the
terminal pins themselves and rewiring a machine changes one table.
Hardware catalogue
The cards are described in XML under configs/common/mcplc_hardware/
(installed to share/linuxcnc/mcplc_hardware): one file per board
(<board name title driver bus> with <firmware name file encoders
pwmgens stepgens sserial_channels watchdog gpio>, its <connector>
elements and their <pin io type chan hal dir sserial_channel
default_card>), and mesa-daughters.xml with the daughter cards
(<daughter name mode title channels>, <terminal name>, <pin n hal
htype dir channel>). The shipped files are generated from the tables of
pncconf by src/emc/usr_intf/mcplc/gen_mesa_catalog.py; a card or a
custom firmware is added by writing another XML file.
EtherCAT: drives and terminals
EtherCAT devices are described by ESI files (EtherCAT Slave
Information, ETG.2000, XML <EtherCATInfo>) - the counterpart of the
Profinet GSD file, shipped by every vendor (Beckhoff as one ZIP of all
terminals; Omron, Delta, Leadshine, RTelligent, Inovance … per
product). Hardware-Katalog > ESI-Dateien importieren reads XML files
or ZIP archives into the user catalogue ~/.config/mcplc/esi/; a small
set (EK1100, EL1008, EL2008, EL3064, EL4034, EL5101 and a generic CiA
402 drive) ships with mcplc. The catalogue knows per device the vendor
and product ids, revision, name, group, profile, the sync managers, the
RxPdo/TxPdo definitions with their entries (index, subindex, bit
length, name, data type) and the distributed-clock modes.
In Geraete & Netze the EtherCAT-Master hangs on the PC with its
slaves as a chain in bus order; a double click on a device of the
catalogue appends a slave, EtherCAT-Bus scannen reads the real bus
through the IgH tool (ethercat slaves -v, ethercat pdos; the output
can also be pasted) and matches it against the catalogue - unknown
slaves become generic ones with the PDOs the bus reports. Per slave:
the name (HAL prefix lcec.0.<name>.), the lcec driver - the
dedicated driver of linuxcnc-ethercat when it has one for the type
(EL1008, EL2008, EL3064, AX5xxx, ECT60 …), basic_cia402 for CiA 402
drives (profile 402 or the 0x6040/0x6041 objects), generic for the
rest -, the distributed-clock mode from the ESI, CiA 402 modParam
settings (homeMethod, homeOffset, profileMaxVelocity …), SDO
start parameters and, for generic slaves, the PDOs taken into the
configuration. The HAL pins of every slave are known to the pin
browser: lcec.0.din1.din-3, lcec.0.ain1.value-0,
lcec.0.xaxis.srv-cia-statusword …
The generator writes ethercat-conf.xml for lcec_conf next to the
HAL files - <masters><master idx appTimePeriod refClockSyncCycles>
<slave idx type name [vid pid configPdos]> with dcConf, sdoConfig,
modParam and, for generic slaves, syncManager/pdo/pdoEntry with
halPin/halType from the ESI entries - and the HAL lines loadusr -W
lcec_conf ethercat-conf.xml, loadrt lcec, addf lcec.read-all first
and addf lcec.write-all last in the fast thread. The CNC assistant
knows the axis type ethercat: a cia402 box (the hal-cia402
component, pins pos-cmd, pos-fb, enable, statusword,
controlword, opmode, drv-target-position …) sits between the
joint and the srv-* pins of the drive, with the position scale and
the INI entries for drive-internal homing. linuxcnc-ethercat and the
IgH EtherCAT master are installed separately
(https://github.com/linuxcnc-ethercat/linuxcnc-ethercat, etherlab.org).
The CNC assistant
CNC-Assistent… in Geraete & Netze builds the base program of a
machine from a table: for each axis the letter, joint, type (stepper or
servo), the card and its channel, the scale (steps or counts per mm),
Vmax, Amax and the limits; the spindle (none, PWM channel or
analogue output such as hm2_5i25.0.7i76.0.0.spinout) with its maximum
speed; the emergency stop input; the probe input; the periods of the
servo and PLC threads. It creates the block CNC (first block, servo
thread) with one network per axis - stepper: joint.N.motor-pos-cmd to
stepgen.NN.position-cmd, feedback, enable, the stepgen parameters
(scale, maxvel/maxaccel with 25 % headroom, step timing) - servo: a
pid box with encoder.NN.position as feedback and the output on
pwmgen.NN.value or, with a 7i77 and no PWM in the firmware, on
7i77.0.N.analogoutN -, the spindle network (spindle.0.speed-out-abs,
spindle.0.on, direction, scale), the probe network (input, optionally
inverted, to motion.probe-input, in the fast thread), and the
emergency stop chain (iocontrol.0.user-enable-out and the input
through an ESTOP latch to iocontrol.0.emc-enable-in, in the PLC
thread). The networks are then edited like any
other. The matching INI ([KINS] trivkins with the coordinates,
[TRAJ], [AXIS_x], [JOINT_n] with scale, limits, stepgen headroom,
[SPINDLE_0], [HOSTMOT2] with the config strings, [HAL] with the
generated HAL file) is saved with Projekt > INI der CNC speichern.
SCL blocks: structured text compiled to HAL components
Eigene Bausteine (SCL) (navigation, context menu Neuer SCL-Baustein)
hold blocks written in the structured-text subset below; each becomes
one HAL component through halcompile, used in networks like any
component - a box with the parameters as ports, in the palette under
Eigene Bausteine (SCL):
FUNCTION_BLOCK "Zylinder"
VAR_INPUT start : Bool; zeit : Real := 2.5; END_VAR
VAR_OUTPUT aktiv : Bool; rest : Real; END_VAR
VAR t : TON; flanke : R_TRIG; zaehler : DInt; END_VAR
BEGIN
t(IN := start, PT := zeit);
flanke(CLK := start);
IF flanke.Q THEN zaehler := zaehler + 1; END_IF;
aktiv := t.Q;
rest := MAX(zeit - t.ET, 0.0);
END_FUNCTION_BLOCK
VAR_INPUT parameters become pin in, VAR_OUTPUT pin out,
VAR_IN_OUT pin io (types Bool, Int, DInt, SInt, UInt, UDInt, USInt,
Byte, Word, DWord, Real, LReal, Time - bit, s32, u32, float), VAR
static variables that keep their value between cycles; the body runs
once per thread cycle as the component’s function. Statements: :=,
IF/ELSIF/ELSE/END_IF, CASE … OF with single values, lists and
ranges, FOR … TO … BY … DO, WHILE … DO, REPEAT … UNTIL,
RETURN, EXIT. Expressions: + - * / MOD **, AND OR XOR NOT,
= <> < ⇐ > >=, numbers, TRUE/FALSE, time literals T#1s500ms
(seconds), PERIOD (the cycle time in seconds), functions ABS MIN MAX
LIMIT SEL SQRT SIN COS TAN ATAN EXP LN TRUNC ROUND and the conversions
REAL_TO_INT etc. Built-in instances declared under VAR: TON, TOF,
TP (IN, PT → Q, ET), R_TRIG, F_TRIG (CLK → Q), CTU,
CTD (CU/CD, R/LD, PV → Q, CV), SR, RS (Q1); they
are called as t(IN := x, PT := 2.0) and read as t.Q.
The editor shows the translated .comp (Uebersetzen), Compilieren &
installieren runs halcompile --install on it (with sudo when the
RT library directory is not writable) and puts the component into the
library; .comp speichern writes the file for a build by hand. A box
of a block that is not installed yet is a reminder in the log: the
generated HAL loads it with loadrt <name> names=… like every
component, so the machine needs the installed component.
Simulation, retentive values, cross references
Testen > Simulation starten writes the HAL files of the project in a
simulation form into sim/ next to the project and runs them in
halrun: the base components (motion, kinematics), the cards, the
EtherCAT slaves and the panels are left out and their pins leave the
nets - the signals stay, listed in the log, and are set by hand with
Wert setzen (sets) -, the threads are created by the file, the
networks, data blocks and constants are loaded as they are. The live
view switches on by itself, so the logic can be watched and driven
without a machine; Simulation stoppen (or closing mcplc) ends
halrun.
A DB element with Remanenz keeps its value across restarts: the
generated HAL loads the userspace component mcplc_retain right after
the DB signals (loadusr -W mcplc_retain <machine>.retain.json
dbDaten.zaehler …), which restores the saved values with sets
before the networks give the signals writers, watches them, writes the
JSON file whenever one changes (at most once per second) and once more
when HAL shuts down. The file lives in the configuration directory.
Online > Querverweise (and Querverweise… in the context menu of an operand or box) lists every signal, pin, parameter, instance and IO variable of the project with the blocks and networks that use it, read or written; a double click jumps to the network and selects the element.
Traces
Traces in the navigation (context menu Neuer Trace) record HAL
signals over time like the trace function of TIA Portal. The Trace
page shows on the left the signals of the trace - chosen from the
dropdown of the project’s variables and the running HAL’s signals, or
any pin of a component through Pin… (a pin already on a signal is
recorded through that signal, a free pin gets a trace signal of its
own) - and the recording conditions: the resolution (sample interval
in ms), the duration, the trigger (none, rising or falling edge of a
bit, a level above or below for numbers) with the pre-trigger time
kept before it, and the mode. In mode sampler the recording is done
in real time: mcplc loads the sampler component into the fast thread,
links the signals to its pins and reads halsampler, one sample per
thread cycle decimated to the resolution; mode poll reads
hal.get_value from the GUI (10 ms and slower) when realtime sampling
is not possible. Aufzeichnung starten arms the trigger and the chart
follows the recording live (Automatisch); stoppen ends it early.
The chart draws one track per signal (bits as 0/1 steps, numbers scaled
to their range) over the time axis; the mouse wheel zooms, the
scrollbar pans, Alles shows the whole recording. Two measuring
cursors work like on an oscilloscope: a left click sets t1, a right
click (or Shift+click) t2, both are dragged with the mouse; the
header shows t1, t2 and dt, the signal table Y(t1), Y(t2) and dY per
signal. Speichern writes the recording as CSV (t_s and one column
per signal) together with a .trace.json of the configuration,
Laden brings a saved recording back into the chart.
Ansicht switches the chart: Zeit is the time diagram, FFT the amplitude spectrum of every signal (Welch estimate, dB over a logarithmic frequency axis up to half the sample rate), Bode the transfer function of an output signal over an input signal (magnitude, phase and coherence) - the "Transfer" of TIA’s maths function, e.g. the frequency response of the mechanics from the motor and the load encoder of a trace. The two cursors read level, phase and their differences in the frequency views; polled recordings are put on a uniform time grid first.
Axis tuning (position loops)
| Every measurement and the automatic tuning move the axis. The operator keeps the responsibility: working area free, parts fixed, the axis enabled, a small amplitude first. mcplc asks before every start. |
Achsoptimierung in the navigation (context menu Neue Achse) and the
page of the same name tune the position loops of the pid instances
the way the measuring functions of TIA Portal / Startdrive do, on the
components LinuxCNC has:
-
Achse: the pid instance (from the running HAL or the pid boxes of the project), its thread; Erkennen reads the command, feedback and output signals and the cycle time from the running HAL.
-
Regler (pid): Pgain, Igain, Dgain, FF0-FF2, bias, deadband, maxerror, maxoutput read from and written to the HAL (
setp). -
Filter im Reglerausgang:
biquadinstances between the pid output and the drive - Bandsperre (type 2, f0 and Q = f0 / bandwidth; the bandwidth not narrower than half the frequency, so the notch stays robust when the resonance shifts; the component accepts Q from 0.5 to 2 only) and Tiefpass (type 1); Auf Resonanz makes a notch from a resonance of the findings list, In HAL laden puts the chain into the running HAL (a module loads only once: when the configuration already usesbiquad, the filters take effect in the generated HAL), Ins Projekt uebernehmen writes the gains into the pid box and inserts the biquad boxes behind its output. -
Messfunktion:
-
Regelstrecke - a PRBS noise signal (maximum length sequence, one sample per thread cycle) is added to the pid output after the filters through a summing component inserted into the running HAL (
offset,sum2orscale, whichever is free), fed bystreamer/halstreamer; the feedback is recorded withsampler/halsampler. The frequency response feedback/excitation (Welch estimate, Hann windows, coherence) is measured inside the closed loop; the controller active at that moment is taken out again (G = Gm/(1-C Gm) with C = P + I/s + D s), so the curve shows the mechanics: Resonanz (Pol) and Tilger (Nullstelle) with frequency, level, Q and bandwidth in the findings list. -
Fuehrungsfrequenzgang - the noise is added to the command (the feedforward is switched off for the measurement and restored). The closed loop Fg gives the bandwidth f(-3 dB) and the resonance peak (at most 3 dB), the open loop Fo = Fg/(1-Fg) the gain margin (6-10 dB at the -180 degree crossing) and the phase margin (about 40 degrees and more at the crossover).
-
Sollwertsprung - a step with a short ramp on the command; rise time 10-90 %, overshoot (4 % for the amount optimum, 43 % for the symmetric optimum), settling time (2 %) and the steady error.
-
Verfahrprofil - a smooth move there and back on the command with the feedforward on (the "Symmetrierung" check: the controller should have nothing left to do during a move); the following error is fitted against the command velocity and acceleration, which gives the FF1 and FF2 the error asks for. FF1/FF2 aus Verfahrprofil applies them and measures once more.
The Bode plot draws magnitude and phase over a logarithmic frequency axis with the filter chain and the open loop overlaid and the resonances marked; two cursors (left click f1, right click f2) read level and phase and their differences, as on an oscilloscope. The HAL is restored after every measurement (the summing component and the streamer are unloaded, the signals re-linked).
-
-
Automatisch:
-
Relay (pid-intern) - the auto tune built into the pid component: the output switches between +-effort around the bias, the amplitude and period of the limit cycle give the ultimate gain Ku and period Tu and the component writes Ziegler-Nichols gains (PID, or PI with FF1 = 1 for a velocity drive); Ku and Tu are shown (the pid exports them as pins with
debug=1, otherwise they are taken back from the gains). Fully automatic, no HAL changes, but a coarse rule. -
Frequenzgang (loop shaping) - the plant is measured, notches are put on the resonances above the expected crossover, P is placed where the plant phase leaves the chosen margin (konservativ 60 degrees / 10 dB, standard 50 / 8, dynamisch 40 / 6) and lowered until the gain margin and every resonance peak keep their reserve, I follows Tn = 4/wc of the real crossover (symmetric optimum), FF1 comes from the velocity gain of the plant, and a step of the feedback loop alone (feedforward off) verifies the result: Tn is doubled while the overshoot exceeds 25 %. The report lists every step.
-
Semi-automatic tuning is the same loop by hand: measure the plant, set a notch on a resonance, raise P (a factor 1.4 is 3 dB), measure the closed loop and read the margins, add I, check with a step.