Preview:
-
The PLC cycle scan is a sequential process where we read inputs, execute the user’s program, and then write to the outputs. At no time does the user’s program operate directly on the I/O. This is a key tenet to minimize runtime bugs.
-
Some modern PLCs may be programmed in C. Also, the line between the PLCs and PCs is blurred. Some hybrid PLCs like the Revolutions Pi are very flexible, allowing many different programming languages.
-
Purpose-built IEC 61131-3 languages such as Ladder Logic (LL) and Structured Text (ST) should be used whenever possible. However, there are reasons to use C including programming experience and the ability to leverage increasingly common Industry 4.0 networking with cloud storage and cybersecurity.
Introduction
Let’s start with the iron law of industrial economics. System downtime is horrendously expensive with costs ranging from hundreds to thousands of dollars per minute. Industrial components such as the PLC are designed with ease of maintenance to minimize this downtime. This fact extends to the IEC 61131-3 languages such as Ladder Logic (LL). They were designed to enhance readability with graphical representation of logic including a technician-friendly near-real time display of the logic states.
There are many good reasons to stay with the tried-and-true PLC languages. However, you may be a confident K & R C programmer who still uses sprintf( ). You may wish to leverage the technology where the line between PLC and industrial PC is blurred. You may also want to take advantage of the scale and functionality of networked devices with emphasis on data sharing (cloud), cybersecurity, and ease of updates.
PLC cycle scan from within main
Let’s add structure to make main( ) as simple as possible. For example, would this representation of the classic latch be worth something to you? The idea is shown graphically in Figure 1.
void loop( ) {
readInputs( );
if (SS1 & PB_START & !PB_STOP) {
FAN = ON;
PL_GREEN = ON;
PL_RED = OFF;
}
if (!SS1 | PB_STOP) {
FAN = OFF;
PL_GREEN = OFF;
PL_RED = ON;
}
writeOutputs( );
}
To the greatest extent possible, we have abstracted away the function calls to the I/O and included simple, self-documenting names for the I/O. In many respects we have taken the, at times, clumsy (sorry, perfect) C language and moved it closer to Structured Text (ST). Please refer to this prerequisite article exploring the X macros technique implicit in the code listing. The document explains the abstraction associated with the simplified code. You may also be interested in this article that explores the PLC memory structures from a ladder logic perspective.
Figure 1: This clock analogy represents the actions taken during a PLC’s program scan.
PLC cycle scan pattern
The code assumes a PLC style cycle scan structure where the inputs are locked in at the beginning of the loop and the outputs are asserted at the end of the loop, as shown in Figure 1. Perhaps you already use this style by taking and then operating on a snapshot of the inputs. This is an important structure, as we want to operate on a fixed data set for duration of the loop. For example, suppose we have code operating on PB_START at the beginning of the loop with additional code operating on the same PB_START variable near the end of the loop. Subtle bugs can enter the program if PB_START changes in the middle of the loop.
The PLC cycle scan structure also guards against certain types of bugs. For example, suppose MOTOR_1 was updated near the top of the loop from within a conditional statement. Later, the programmer uses the old value of MOTOR_1. The system would not be predictable, as the output may or may not depend on the inputs depending on the structure of the conditional statement. Good luck troubleshooting these non-deterministic bugs as the conditions are very difficult to identify.
Modularity and encapsulation
The prime take away is that we do not operate directly on the inputs and outputs. Instead, our program operates on internal memory (snapshot) structures. The readInputs( ) and writeOutputs( ) functions/methods consolidate all of the digitalRead( ) and digitalWrite( ) functions that would otherwise clutter the code. The consolidation also ensures deterministic operation.
Tech Tip: It’s true that the PLC cycle scan structure is not the fastest or even the most resource efficient programming method. However, given the programming hazards, there aren’t many reasons to buck this advice.
If high speed is required, the microcontroller Interrupt Service Routine (ISR) should be implemented with volatile variable and atomic data transfers between main( ) and the ISR.
TechTip: Bugs can still enter the program. For more information, please consider the “last rung wins” argument for PLC operation. Multiple lines of code that manipulate an internal variable such as MOTOR_1 can cause unexpected operation. To clarify, while this type of bug may be unexpected to the programmer, it is still deterministic and relatively easy to troubleshoot.
Single location for I/O names
We won’t repeat the lesson of the prerequisite article. However, we can’t stress the importance of program clarity and the use of named variables in coordination with the readInputs( ) and writeOutputs( ) function/methods. The X macros technique, with its consolidated I/O lists is a key ingredient to programming hygiene. To prevent bugs, we want to define variables such as PB_START and MOTOR_1 once, and only once. We then automate the routine tasks of initializing and reading the ports and
Tech Tip: Despite what your programming textbook states, global variables are used in PLC programming. The reduced clutter of the main loop is a good reason to embrace global variables. Don’t worry, they are still used with the “sparingly” stamp of approval, typically in association with I/O.
Next steps
To learn more about the PLC and C programming:
-
Reflect on the life cycle of your code with the understanding that the lifespan of a PLC application is measured in decades. Balance your own understanding with the needs of future technicians who service the PLC and future engineers who will modify your code.
-
Study the IEC 61131-3 languages to identify desirable code structures and techniques. Incorporate best practices into your C programs.
-
Construct and continually refine a style guide for your embedded applications.
-
Add timers to the mix. This article shows a technique adapted from structured text.
Parting thoughts
The cycle scan is a solid feature of PLC programming. The snapshot model of never operating directly on the I/O goes a long way to preventing unexpected bugs. It also cleans up the program, making it easier to read and maintain.
If I may, once again, I would like to point out the power of the IEC61131-3 languages and their inherent troubleshooting tools. They lower the level of programming experience required to troubleshoot a system. This could have serious implications for your bottom line when equipment inevitably fails. On the other hand, C and derivative high-level languages may be easier from a networking perspective – not many conventional PLCs feature Docker.
Best wishes,
APDahlen
Related information
Please follow these links to related and useful information:
About this author
Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET-accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians. Dahlen has returned to his Northern Minnesota home and thoroughly enjoys researching and writing articles such as this.