plcLib (Arduino): Function Block Diagrams

A function block diagram allows an electronic system to be represented as a block diagram, which may then be translated into a text-based Arduino sketch in the usual way.

Function block diagrams are typically made up of a series of boxes (often rectangular in shape), having inputs at the left and outputs at the right. External inputs are normally shown at the left side of the diagram and outputs at the right. Interconnections between these elements allow signals to progress generally from left to right, although in some cases, feedback signals, may also be present, returning signals back to an earlier stage for further processing.

A variety of function types are supported, including logic gates, comparators, latches, time delays and waveform generators.

Constructing Working Systems

Interconnections between blocks may use a variety of signal types, which are represented by the computer as an equivalent data type. For example, a simple logic diagram, consisting of interconnected logic gates, transfers single bit values (0 / 1) between elements. A more complex digital system may require some parameters to be specified as an integers (signed or unsigned), or as floating point numbers (numbers which can take any value).

Clearly, care must be taken not to link incompatible signals when creating interconnections. However, note that the software is designed to be as 'forgiving' as possible. For example, an analogue input may be directly connected to a PWM output, or to a servo, without problems, and the software will automatically scale the values.

A good understanding of how the software actually 'solves the circuit' is required, in order to write an equivalent text-based sketch. The Advanced Concepts section explains how the software uses the scanValue variable to solve each rung of a ladder diagram, progressing from left to right across each rung, and from top to bottom in a repeating sequence called the scan cycle. In effect, the output of each command is temporarily stored in the scanValue variable and then reused as the first input to the next command. This works fine for simple networks, but it may be necessary to store temporary results for later reuse in more complex circuits.

The process of solving a system represented in block diagram form is very similar to that used with a ladder diagram. In summary, work from left to right and from top to bottom. Try to allow the scanValue variable to automatically transfer signals between system blocks, wherever possible. You can use multiple left to right 'passes' – just like the 'rungs' of a ladder diagram – and temporary results may be stored and later retrieved, if necessary. The following two examples demonstrate the application of this design approach with some relatively simple circuits.

Application 1: A Simple Alarm

A simple alarm circuit may be constructed using an OR gate and a Set Reset latch, as shown by the following illustration.

The alarm has three sensors, which are connected to a 3-input OR gate. If one or more of the sensors becomes active, this causes the output of the logic gate to go high, which in turn sets the latch and activates the alarm output (Q). The alarm will remain active due to the latch, even when the original alarm input is removed, but may be manually cancelled by activating the Reset input.

An equivalent sketch is shown below.

#include <plcLib.h>

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Simple Alarm - A 3-input alarm circuit with a latched output and manual Reset input

   Connections:
   Input - Sensor 0 - switch connected to input X0 (Arduino pin A0)
   Input - Sensor 1 - switch connected to input X1 (Arduino pin A1)
   Input - Sensor 3 - switch connected to input X2 (Arduino pin A2)
   Input - Reset Alarm - switch connected to input X3 (Arduino pin A3)
   Output - Alarm Output - LED connected to output Y0 (Arduino pin 3)

   Software and Documentation:
   http://www.electronics-micros.com/software-hardware/plclib-arduino/

*/

void setup() {
  setupPLC();       // Setup inputs and outputs
}

void loop() {
  in(X0);           // Read Sensor 0 (Input 0)
  orBit(X1);        // OR with Sensor 1 (Input 1)
  orBit(X2);        // OR with Sensor 2 (Input 2)

                    // Sensor result is used as Set input to latch
  latch(Y0, X3);    // Latch command, Q = Output 0, Reset = Input 3
}
Source location: File > Examples > plcLib > Applications > SimpleAlarm

Application 2: Alarm with Flashing 'Armed' LED

This example is based on the previous application, but uses a cycle timer to produce a flashing Armed output when the alarm is active, but not triggered. The circuit diagram is shown below.

Operation of the OR gate and Set Reset latch is the same as the basic alarm described previously. The pulse generator (or cycle timer) is enabled when the Reset input is inactive (using the Not gate connected to input X3) and is configured to produce a brief pulse of 0.1 seconds duration every 2 seconds. The Q output of the cycle timer is connected to the Armed output (Y1) via an AND gate, which will disable the Armed output if the main alarm has been triggered. The equivalent software listing is shown below.

#include <plcLib.h>

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Alarm with Armed Status LED - 3 input alarm controller with flashing Armed LED

   Connections:
   Input - Sensor 0 - switch connected to input X0 (Arduino pin A0)
   Input - Sensor 1 - switch connected to input X1 (Arduino pin A1)
   Input - Sensor 3 - switch connected to input X2 (Arduino pin A2)
   Input - Reset Alarm - switch connected to input X3 (Arduino pin A3)
   Output - Alarm Output - LED connected to output Y0 (Arduino pin 3)
   Output - Armed Output - LED connected to output Y1 (Arduino pin 5)

   Software and Documentation:
   http://www.electronics-micros.com/software-hardware/plclib-arduino/

*/

// Timer Variables
unsigned long AUX0 = 0;     // Pulse low timer variable
unsigned long AUX1 = 0;     // Pulse high timer variable

void setup() {
  setupPLC();               // Setup inputs and outputs
}

void loop() {
  
  in(X0);                              // Read Sensor 0
  orBit(X1);                           // OR with Sensor 1
  orBit(X2);                           // OR with Sensor 2

                                       // Set input to latch taken from sensors
  latch(Y0, X3);                       // Latch command, Q = Output 0, Reset = Input 3

  inNot (X3);                          // Enable input (0 = enable)
  timerCycle(AUX0, 1900, AUX1, 100);   // Repeating pulse 1.9 s low, 0.1 s high.
  andNotBit(Y0);                       // Disable armed pulse if alarm is triggered
  out(Y1);                             // Armed pulse on output Y0
}
Source location: File > Examples > plcLib > Applications > AlarmWithArmedStatus

Creating User Defined Function Blocks

You can extend the plcLib software by defining one or more text based functions (or function blocks to use PLC-specific terminology) 'locally' within a sketch, which may be useful if a required feature is not supported by the software, as standard. Any user created functions may then be called from the main program, acting just like built-in commands.

To create your own custom commands you will need to be reasonably confident with C / C++ programming, and have a basic knowledge of Arduino functions. You will also need to be familiar with the Advanced Concepts and Using Variables in Programs sections of the user guide.

The following example calls a user defined function to calculate the average value of two different analogue inputs, using the result to control the brightness of an LED.

#include <plcLib.h>

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Average - Create a custom function to calculate the mean of two analogue inputs

   Connections:
   Input - Potentiometer connected to analogue input X0 (Arduino pin A0)
   Input - Potentiometer connected to analogue input X1 (Arduino pin A1)
   Output - LED connected to output Y0 (Arduino pin 3)

   Software and Documentation:
   http://www.electronics-micros.com/software-hardware/plclib-arduino/

*/

unsigned int reading1;
unsigned int reading2;
extern int scanValue;	// Link to scanValue defined in PLC library file

void setup() {
  setupPLC();                               // Setup inputs and outputs
}

void loop() {
  reading1 = inAnalog(X0);                  // Read analogue Input 0
  reading2 = inAnalog(X1);                  // Read analogue Input 1
  scanValue = average(reading1, reading2);  // Set scanValue to average reading
  outPWM(Y0);                               // Send to Output 0
}

                                            // User defined function to calculate
                                            // the average of two values
											
unsigned int average(unsigned int value1, unsigned int value2) {
  int result;
  result = (value1 + value2) / 2;
  return result;
}
Source location: File > Examples > plcLib > Function Block > Average

The above sketch repeatedly reads the two analogue inputs, storing these values in two user defined variables, reading1 and reading2. These are 'passed' to the average() function, which finds the mean of reading1 and reading2, returning the result to the main program. This returned result is stored in the scanValue variable, which automatically makes the value available as an input to the next command in the scan cycle. The actual function definition is found towards the end of the listing.

The scanCycle variable must be initially defined as an external variable, as it is used internally by the plcLib software.

Related Topics

top