Wall of text, little bit of code. This question is about as much as introducing the language as it is about whether or not I still know how to write the language.
Programmable Logic Controllers (PLCs) are industrial, heavy-duty computers used to control (semi-)automated processes in factories. They can be programmed in a large amount of languages and programmed using a multitude of languages. Up till '93, every brand had its own language. Thanks to the IEC 61131-3, languages are more (but not completely) standardized now.
One of the most used languages of the standard 5 described in the earlier mentioned IEC document is "Structured text" (ST), not to be confused with reStructuredText. ST looks a bit like Pascal and is, usually, quite easy to read.
In ST, there's a main program (traditionally called PLC_PRG) which can be accompanied by multiple Function Blocks (FBs). Every function gets its own FB. Variable declaration is separated from variable usage.
To program a PLC, you need a programmer. Those are usually packed within an IDE. An ever growing amount of PLCs can be programmed with the standard languages using CODESYS.
A typical set-up for a PLC is having a Human Machine Interface (HMI), a PLC, sensors and actuators. Most of those can be simulated and visualized so no actual hardware is required.
Problem and approach
How FizzBuzz works doesn't need much explanation. Except mine doesn't work quite like that. You see, I had a little trouble getting the text-box to work and by the time I figured it out it already looked just fine. So unlike an ordinary FizzBuzz, mine will always show the number. There will be extra output when the number is divisible by 3, 5 or both (15). All working as intended.
To keep it more interesting, I added a couple of extras. A switch to turn the program off, for example. After all, it's a PLC. It might be driving a chainsaw instead of a couple of indicators next. Everything you build in hardware needs a switch to turn it off.
The number indicator is limited to 90 or 255. Why? Because they're divisible by 15 and 100 isn't. It just looks better. There's also a reset button (self-explanatory) and an automated reset at 90. The automated reset can be toggled. If the reset isn't used, the count will go till 255 and overflow to 0. If the indicator is set to a scale end of 90, 91-255 will be indicated as 90.
The FizzBuzzer has its own FB. I've considered putting the
IF statements within it in their own FB as well, passing 3 and 5 as arguments from the FizzBuzzer, but that got surprisingly messy. Must've done something wrong. I'm also unable to make
CONST variables out of
buzz_num, I kind-of forgot the proper syntax for that.
The simulation is controlled by mouse. Works like a train.
PROGRAM PLC_PRG VAR state : BOOL := FALSE; reset : BOOL := FALSE; toggle_reset: BOOL := FALSE; i: USINT; reset_above : USINT := 90; fizzbuzz: FIZZBUZZ; fizz: BOOL; buzz: BOOL; END_VAR
IF state THEN i := i+1; fizzbuzz(in:=i, fizz=>fizz, buzz=>buzz); END_IF; IF reset THEN i := 0; END_IF IF toggle_reset AND i >= reset_above THEN i := 0; END_IF
FUNCTION_BLOCK FIZZBUZZ VAR_INPUT in : USINT; END_VAR VAR_OUTPUT fizz : BOOL := FALSE; buzz : BOOL := FALSE; END_VAR VAR fizz_num : USINT := 3; buzz_num : USINT := 5; END_VAR
IF in MOD fizz_num = 0 THEN fizz := TRUE; ELSE fizz := FALSE; END_IF; IF in MOD buzz_num = 0 THEN buzz := TRUE; ELSE buzz := FALSE; END_IF
From left to right, top to bottom, including the variable they're linked with:
- Index indicator (
- Fizz indicator (
- Buzz indicator (
- Reset button (
- State switch (
- Automatic reset switch (
Whether or not that naming is logical depends on how you look at it and what you're used to, I guess. The State switch probably needs a better name.
Both animations use a MainTask interval of 250 ms and a VISU_TASK interval of 100 ms.
This particular FizzBuzz is written in ST using CODESYS V3.5 SP12.