plcLib (Arduino): Defining Custom IO Allocations

In some cases, the default input output configuration may not be suitable. A custom I/O allocation may be appropriate if additional inputs or outputs are needed, custom hardware is being used, or if a different pin naming convention is preferred.

Preconfigured I/O Allocations

Version 1.2 of the PLC library provides an extended range of custom I/O files to suit a variety of hardware. The following configuration files are available from the File > Examples > CustomIO menu section.

  • Uno and Mega with default pin configurations (Uno, Mega)
  • PLCs (ControllinoMaxiPLC, ControllinoMegaPLC, ControllinoMiniPLC)
  • Ardbox PLCs (ArdboxAnalogPLC, ArdboxPNPPLC, ArdboxRelayPLC, ArdboxTCHPLC)
  • M-Duino PLCs (MDuino19RelayPLC, MDuino21PLC, MDuino38RelayPLC, MDuino42PLC, MDuino57RelayPLC, MDuino58PLC)
  • Grove shields for Uno and Mega (GroveUno, GroveMega)
  • TinkerKit shields for Uno and Mega (TinkerkitUno, TinkerkitMega)
  • I/O Shield (VellemanIOShield)
  • Use of custom pin names and user defined variable names (CustomIO)

If the supplied configurations are unsuitable, then you may need to create your own from scratch, as discussed next.

Case Study: Creating a Custom IO Allocation

This section demonstrates the creation of a custom IO mapping for the Velleman Input/Output Shield for Arduino.

The module provides a total of eighteen IO connections, arranged as six analogue inputs, six digital inputs, and six relay-based digital outputs. Further details of connection and internal wiring details are available in the and .

The first task is to choose a suitable naming convention for inputs and outputs, and identify the associated pin connections.

  • Analogue inputs can continue to use existing names A0A5.
  • Digital inputs will be allocated names D0D5, linked to Arduino pins 2, 3, 4, 5, 6 and 7.
  • Relay outputs will be called R0R5, using pins 8, 9, 10, 11, 12 and 13.

The following sketch begins by disabling the definition of default pin names (X0, X1, ..., Y0, Y1, ...) using the command #define noPinDefs, and then specifies the required pin names as a series of integer constants.

#define noPinDefs       // Disable default pin definitions (X0, X1, ..., Y0, Y1, ...)
#include <plcLib.h>     // Load the PLC library

/* Programmable Logic Controller Library for the Arduino and Compatibles

   Velleman IO Shield Input / Output mapping
   Product information:

   6 digital inputs D0-D5 (Arduino pins 2, 3, 4, 5, 6 and 7)
   6 analogue inputs A0-A5 (connected to the same Arduino pins)
   6 relay outputs R0-R5 (Arduino pins 8, 9, 10,11, 12 and 13)
   Note: outPWM() and outServo() commands should not be used with this
         board due to the use of mechanical switch-based relay outputs.

   Software and Documentation:


  // Define digital input pins
  const int D0 = 2;
  const int D1 = 3;
  const int D2 = 4;
  const int D3 = 5;
  const int D4 = 6;
  const int D5 = 7;
  // Analogue pins will use existing names A0 - A5
  // Define Relay outputs as R0 - R5
  const int R0 = 8;
  const int R1 = 9;
  const int R2 = 10;
  const int R3 = 11;
  const int R4 = 12;
  const int R5 = 13;

void setup() {
  customIO();        // Setup inputs and outputs for Velleman IO Shield
}                    // (See IO tab for details)

void loop() {      // Sample code follows - replace as required
  in(D0);            // Read Digital Input 0
  out(R0);           // Send to Relay Output 0 (Relay 1 of 6)
Source location: File > Examples > plcLib > CustomIO > VellemanIOShield

The customIO() function is used (in place of the standard setupPLC() function) to define data directions for all inputs and outputs as shown below (and available from the IO tab of the sketch).

void customIO (){
  // Input pin directions
  pinMode(D0, INPUT);
  pinMode(D1, INPUT);
  pinMode(D2, INPUT);
  pinMode(D3, INPUT);
  pinMode(D4, INPUT);
  pinMode(D5, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);

  // Relay Output pin directions
  pinMode(R0, OUTPUT);
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  pinMode(R3, OUTPUT);
  pinMode(R4, OUTPUT);
  pinMode(R5, OUTPUT);

The following points should be noted from the above example.

  • Names for the digital inputs and relay outputs must be defined globally, by defining them outside of the setup() { ... } and loop() { ... } sections, hence making them available for use anywhere within the sketch.
  • Pin names and allocations will not change so are defined as constants rather than variables.
  • The plcLib software requires pin names to be defined of signed integer type (i.e. 'int' rather than 'unsigned int'), for reasons discussed in the Using Variables in Programs section

Related Topics