plcLib (Arduino): Using Variables in Programs

This section considers some applications of variables in user sketches, beginning with the built-in scanValue variable, which keeps track of the current calculation result as the scan cycle is executed. Creation of user defined variables is then discussed, leading finally to the application of user variables to solve complex, multiple branch logic circuits.

Using the scanValue Variable

It was seen previously that the scanValue is used internally by the plcLib software as the PLC scan cycle is repeatedly executed. However, this variable is not directly available in user programs, as it is only defined inside the plcLib header file (it is said to be 'out of scope' inside your sketch). You can optionally make scanValue available by defining it as an external variable, as shown in the following example.

#include <Servo.h>
#include <plcLib.h>

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Single Servo - Controlling the position of a servo using a potentiometer 

   Connections:
   Input - potentiometer connected to input X0 (Arduino pin A0)
   Output - servo connected to output Y0 (Arduino pin 3)

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

*/

Servo servo1;           // Create a servo object to control a single servo

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

void setup() {
  setupPLC();           // Setup inputs and outputs
  servo1.attach(Y0);    // Attaches Servo 1 to Output 0
}

void loop() {
  inAnalog(X0);         // Read potentiometer connected to input 0
  outServo(servo1);     // Output to Servo 1 (connected to Output 0)
}

// The outServo function is defined locally
int outServo(Servo &ServoObj) {
  ServoObj.write(map(scanValue, 0, 1023, 0, 179));
  return(scanValue);
}
Source location: File > Examples > plcLib > InputOutput > ServoSingle

As an alternative to the above approach, plcLib instructions may optionally return the current scanValue value to a previously defined user variable (which is only accurate at that specific point in the scan cycle). The content of a user defined variable may also be used as an 'input' to a plcLib command, in place of direct input or output from a named pin. The following example illustrates some of the posibilities.

#include <plcLib.h>

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Latch Command with Variables - Latch command using variables to hold temporary values

   Connections:
   Input - Set - switch connected to input X0 (Arduino pin A0)
   Input - Reset - Switch connected to input X1 (Arduino pin A1)
   Output - Q Output - LED connected to output Y0 (Arduino pin 3)

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

*/

// Temporary Variables:
unsigned int AUX0;        // Latch output variable
unsigned int AUX1;        // Latch reset variable

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

void loop() {
  AUX1 = in(X1);          // AUX1 (Reset) controlled by input X1

  in(X0);                 // Read switch connected to Input 0 (Set input - Input 0)
  latch(AUX0, AUX1);	  // Latch command, Output = AUX0, Reset = AUX1 (Input 1)

  in(AUX0);               // Send Q output to output Y0
  out(Y0);
}
Source location: File > Examples > plcLib > Variables > LachCommandVariables

Things to notice above are the saving of the scanValue variable in a user defined variable (AUX1 = in(X1);), and also the use of variable names in place of pin names in other plcLib commands.

Working with Custom Variables

When referring to names such as X0, X1, Y0, AUX0, AUX1, in the previous listing. you might wonder how does the software 'know' whether you are referring to a pin name or the content of a user defined variable? The answer is that all pin names (X0, X1 and Y0) are defined internally by the plcLib software as signed integer variables, while the user defined variables in the above program (AUX0 and AUX1) are of an unsigned variable type. The plcLib software actually has at least two versions of each command, and the compiler picks the appropriate version based on the supplied variable type (this is called function overloading).

Just remember to specify your user defined integer-type variables as either unsigned integer (16-bit) or unsigned long (32-bit) to avoid confusion between user variables and pin names.

Using Variables with Complex Logic Circuits

A possible application of user variables is in solving complex Boolean logic circuits, as shown in the following example sketch.

#include <plcLib.h>

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Complex Logic - Solving multiple branch Boolean Logic circuits by using
                   variable(s) to hold temporary calculation results

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

   Equivalent Ladder Logic Circuit:
   |                                |
   |         X0    X1               |
   |     |---| |---|/|---|          |
   |     |               |    Y0    |
   |-----|               |---(  )---|
   |     |   X2    X3    |          |
   |     |---| |---| |---|          |
   |                                |
   |                                |

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

*/

unsigned int AUX0;  // AUX0 variable holds top rung temporary result

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

void loop() {
                    // Solve first branch
  in(X0);           // Read Input 0
  andNotBit(X1);    // AND with inverted Input 1
  out(AUX0);        // Use auxiliary variable AUX0 to store first branch result
  
                    // Solve second branch
  in(X2);           // Read Input 2
  andBit(X3);       // AND with Input 3
  orBit(AUX0);      // OR with result from first branch (AUX0)
  out(Y0);          // Send result to Output 0
}
Source location: File > Examples > plcLib > Variables > ComplexLogic

The above example first solves the upper branch of the logic circuit and then 'outputs' this as a temporary result to a user defined variable – out(AUX0);. (This line could have been omitted completely by rewriting the preceding line as AUX0 = andNotBit(X1);.) The second branch is then solved and the result from the first branch ORed with the previous temporary result – orBit(AUX0);.

An alternative to the 'user variable' approach discussed above is the application of block logic commands, which is discussed in the next section.

Related Topics

top