9
\$\begingroup\$

Warning

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.


Introduction

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 it's 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 fizz_num and buzz_num, I kind-of forgot the proper syntax for that.

The simulation is controlled by mouse. Works like a train.

Code

PLC_PRG (PRG)

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

FIZZBUZZ (FB)

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

Project overview

Project overview

Result

To 90:

FizzBuzz visualized HMI to 90

To 255:

FizzBuzz visualized HMI to 255

From left to right, top to bottom, including the variable they're linked with:

  • Index indicator (PLC_PRG.i)
  • Fizz indicator (PLC_PRG.fizz)
  • Buzz indicator (PLC_PRG.buzz)
  • Reset button (PLC_PRG.reset)
  • State switch (PLC_PRG.state)
  • Automatic reset switch (PLC_PRG.toggle_reset)

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.

Footnote

This particular FizzBuzz is written in ST using CODESYS V3.5 SP12.

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.