Function blocks that diff: the Nautilus FBD editor
Function Block Diagram (FBD) in VS Code
All posts · Nautilus ·
Companion post for the week-4 video. The five-minute editor tour covers the same ground on screen: watch it here.
Last week was ladder. This week I'm adding a fourth task to the same project, in a third language: TAL-101, a low-temperature alarm, written as a function block diagram.
The project is the heated tank from the earlier videos, plus one file:
program.st the pump latch, the temperature PI loop, and the AH-101 alarm latch
sim.st the plant physics, in Structured Text
interlocks.ld the annunciator — a horn with a grace timer and an acknowledge
alarms.fbd the low-temperature alarm, as a function block diagram
nautilus.yaml every tag, with its type, units and description
There are four programs in three languages, all sharing one set of tags, and every tag has exactly one writer. The Structured Text program owns the high alarm. The ladder program owns the horn. The new FBD program owns TempLowAlm, which the ladder annunciator has been ORing since last week and which nothing was driving until now.
I put the alarm in FBD because a comparison feeding a timer feeding a coil is what function block diagrams are good at, and because it is the language most people mean when they say a graphical change can't be reviewed.
A first draft with two real problems
The file starts as a draft that works, sort of, which is the honest version of how these get written:
VAR_EXTERNAL
TempC : REAL;
HiTempClrSP : REAL;
TempLowAlm : BOOL;
END_VAR
FBD
cold = LT(TempC, HiTempClrSP)
TempLowAlm := cold
END_FBD
That is the whole diagram: a LT compare and a coil. Two problems. The compare borrows HiTempClrSP, the high alarm's clear setpoint, because whoever drafted it copied the high alarm and changed the direction. And the coil rides the compare directly, so one cold reading during a stir trips the alarm.
Open it with nautilus: Open FBD Diagram Preview and you get the diagram beside the text, with live value chips painting from the running controller. The block outputs take variable names, so cold is both the wire's label on the canvas and an identifier in the file.
Declare and rewire in one gesture
Double-click the HiTempClrSP chip and the editor lists the tags that exist. Type a new one with Structured Text's own syntax, TempLowSP : REAL, and two things land in the text beside the diagram: the argument swaps in the compare, and a declaration appears in VAR_EXTERNAL. One gesture makes both edits.
The chip then goes amber: the program reads a declared tag that the running controller doesn't have. Writes create tags; reads don't, and the first read of a tag that isn't there faults the scan. The editor marks it while the change is still a drawing rather than at three in the morning. Hover the chip for the reason.
nautilus check fails on it too:
error: the programs read "TempLowSP", which nautilus.yaml declares no tag for —
an undeclared tag is never seeded and never driver-fed, so the first read faults the scan
Two things clear it. nautilus: Set Live Value… with the cursor on the tag writes 55 to the controller, which creates the tag and paints the chip. Then one line in nautilus.yaml gives it a role, units and a description, and nautilus check comes back clean.
A timer from the palette
The alarm still needs a debounce. The diagram's + add button opens the palette, and an IEC TON goes in with IN := cold and PT := T#5S. The block lands on the canvas, and one statement lands in the netlist:
t1 : TON(IN := cold, PT := T#5S)
Then drag the timer's Q pin onto the TempLowAlm coil. The wire lands on the canvas and, in the text beside it, the coil's line changes:
- TempLowAlm := cold
+ TempLowAlm := t1.Q
Every gesture in the editor is a change to a line you could have typed. There is no export step and no project file between the drawing and what runs.
The whole change, in four lines
That is the part worth the video. The entire change, from a first draft to an alarm with its own setpoint and a five-second debounce, reads as four lines of git diff. One declares the setpoint, one swaps the compare's argument, one adds the timer and one rewires the coil. A colleague can review that in a pull request the way they review anything else.
And for a reviewer who would rather see the diagram, nautilus: Diff FBD Diagram (vs git HEAD) draws the working tree against the last commit as a diagram, deletions in red and additions in green.
Traditional PLC IDEs offer a compare tool at best, against a file you had to remember to keep. This is ordinary version control that happens to render as function blocks.
Proving it on the controller
The program downloads with the same command as the other videos, and the status bar's "program differs" clears. Then the alarm gets checked the way you would check it at a commissioning: nautilus: Set Live Value… moves TempLowSP to 75, above the tank's running temperature, and the compare goes true on the diagram. The timer's elapsed value counts up in its chip. At five seconds, TAL-101 comes in. Put the setpoint back to 55 and it stands down.
What's next
Next week: sequential function charts, the SFC editor, with the active step highlighted as a batch sequence runs.
Nautilus is open source, Apache-2.0. If you'd like help with your own plant, start with a Control System Assessment: a fixed-price review that ends in a written report you keep either way.
Docs: nautilus.joyautomation.com · Repo: github.com/joyautomation/nautilus
Subscribe to the weekly newsletter to keep up to date: joyautomation.com/newsletter