Skip to content

PLCProject XML Schema Reference - Version 2.0

Document Version: 1.0 Schema Version: 2.0 Last Updated: 2026-01-25 Status: Active

Overview

The PLCProject XML format is the native file format for PiPLC ladder logic projects. Files use the .plcproj extension and contain complete project data including metadata, symbol tables, and ladder logic programs.

File Format Basics

  • Encoding: UTF-8 (with XML declaration)
  • Extension: .plcproj
  • MIME Type: application/x-plcproject+xml
  • XML Version: 1.0

Schema Version History

Version Date Changes
2.0 2026-01-25 Initial documented schema with streaming XML support
1.0 (Legacy) Reserved for future backwards compatibility

Root Element

<?xml version="1.0" encoding="UTF-8"?>
<PLCProject version="2.0">
  <!-- Child elements -->
</PLCProject>

Attributes

Attribute Type Required Description
version string Yes Schema version (e.g., "2.0"). Required for compatibility checking.

Child Elements (in order)

  1. Metadata - Project metadata (required)
  2. SymbolTable - Variable definitions (required, may be empty)
  3. Programs - Ladder logic programs (required)

Metadata Element

Contains project identification and descriptive information.

<Metadata>
  <Name>Motor Control</Name>
  <Description>Optional description of the project</Description>
</Metadata>

Child Elements

Element Type Required Description
Name string No Project name. Empty string if not specified.
Description string No Project description. Omitted if empty.

Notes

  • Special XML characters (<, >, &, ", ') are automatically escaped
  • Unicode content is fully supported

SymbolTable Element

Contains variable/symbol definitions used in the ladder logic.

<SymbolTable>
  <Symbol name="StartButton" type="BOOL" address="I:0/0" description="Main start pushbutton" />
  <Symbol name="MotorRunning" type="BOOL" address="O:0/0" />
  <Symbol name="CycleCount" type="INT" address="N:10" description="Production counter" />
</SymbolTable>

Symbol Element Attributes

Attribute Type Required Description
name string Yes Unique variable name. Must follow naming rules (alphanumeric + underscore, no leading digits).
address string Yes PLC memory address. See Address Formats below.
type string No Data type: BOOL, INT, DINT, REAL, TIMER, COUNTER. Defaults to BOOL.
description string No Human-readable description. Omitted if empty.

Validation Rules

  • Variable names must be unique within the symbol table
  • Duplicate names will cause a load error
  • Address must be valid per the Address Formats specification

Programs Element

Contains one or more ladder logic programs.

<Programs>
  <Program name="MainProgram" type="Main">
    <Rungs>
      <!-- Rung elements -->
    </Rungs>
  </Program>
</Programs>

Program Element Attributes

Attribute Type Required Description
name string No Program name (informational, may differ from Metadata name)
type string No Program type: Main, Subroutine, Interrupt. Default: Main

Notes

  • Currently only single-program projects are supported
  • The authoritative program name comes from Metadata/Name, not the Program element's name attribute

Rungs Element

Contains the ladder rungs within a program.

<Rungs>
  <Rung id="0" comment="Start/stop circuit with seal-in">
    <!-- Instruction elements -->
  </Rung>
  <Rung id="1">
    <!-- Instruction elements -->
  </Rung>
</Rungs>

Rung Element Attributes

Attribute Type Required Description
id integer No Rung identifier (0-based). Used for reference only.
comment string No Rung comment/description. Omitted if empty.

Instruction Element

Represents a single ladder logic instruction.

<Instruction type="XIC" address="I:0/0" column="0" />
<Instruction type="OTE" address="O:0/0" column="10" />

Attributes

Attribute Type Required Description
type string Yes Instruction type. See Instruction Types below.
address string Yes Target memory address. See Address Formats below.
column integer No Visual column position in ladder editor. Default: 0

Instruction Types

Contact Instructions (Input)

Type Name Description
XIC Examine If Closed TRUE when addressed bit is 1
XIO Examine If Open TRUE when addressed bit is 0

Coil Instructions (Output)

Type Name Description
OTE Output Energize Sets bit to match rung continuity
OTL Output Latch Sets bit TRUE on rung TRUE, retains on FALSE
OTU Output Unlatch Sets bit FALSE on rung TRUE, retains on FALSE

Future Instruction Types (Planned for M4)

  • TON, TOF, RTO - Timer instructions
  • CTU, CTD - Counter instructions
  • ADD, SUB, MUL, DIV - Math instructions
  • EQU, NEQ, GRT, LES, GEQ, LEQ - Comparison instructions
  • JMP, JSR, RET - Program control instructions

Address Formats

PiPLC uses Allen-Bradley/Rockwell-style PLC addressing.

Bit Addresses

Format: R:W/B where: - R = Region prefix - W = Word number (0-based) - B = Bit number (0-15)

Region Prefix Description Example
Input I Digital inputs I:0/0, I:1/15
Output O Digital outputs O:0/0, O:0/7
Bit B Internal relays B:3/0, B:10/8

Word Addresses

Format: R:W where: - R = Region prefix - W = Word/element number

Region Prefix Description Example
Integer N 16-bit signed integers N:0, N:100
Timer T Timer structures T:0, T:10
Counter C Counter structures C:0, C:5

Timer/Counter Sub-Elements

Format: R:W.S where S is:

Sub-element Description Type
.DN Done bit BOOL
.TT Timer timing / Counter counting BOOL
.EN Enabled BOOL
.ACC Accumulated value INT
.PRE Preset value INT

Examples: T:0.DN, C:5.ACC, T:2.PRE


Complete Example

<?xml version="1.0" encoding="UTF-8"?>
<PLCProject version="2.0">
  <Metadata>
    <Name>Motor Control Example</Name>
    <Description>Simple motor start/stop circuit with seal-in relay</Description>
  </Metadata>
  <SymbolTable>
    <Symbol name="StartPB" type="BOOL" address="I:0/0" description="Start pushbutton (NO)" />
    <Symbol name="StopPB" type="BOOL" address="I:0/1" description="Stop pushbutton (NC)" />
    <Symbol name="Overload" type="BOOL" address="I:0/2" description="Motor overload contact (NC)" />
    <Symbol name="MotorOut" type="BOOL" address="O:0/0" description="Motor contactor output" />
    <Symbol name="SealIn" type="BOOL" address="B:0/0" description="Motor seal-in relay" />
    <Symbol name="RunIndicator" type="BOOL" address="O:0/1" description="Motor running pilot light" />
  </SymbolTable>
  <Programs>
    <Program name="Motor Control Example" type="Main">
      <Rungs>
        <Rung id="0" comment="Motor start circuit - Start OR Seal-in, AND NOT Stop, AND NOT Overload">
          <Instruction type="XIC" address="I:0/0" column="0" />
          <Instruction type="XIC" address="B:0/0" column="1" />
          <Instruction type="XIO" address="I:0/1" column="2" />
          <Instruction type="XIO" address="I:0/2" column="3" />
          <Instruction type="OTE" address="B:0/0" column="10" />
        </Rung>
        <Rung id="1" comment="Motor output from seal-in">
          <Instruction type="XIC" address="B:0/0" column="0" />
          <Instruction type="OTE" address="O:0/0" column="10" />
        </Rung>
        <Rung id="2" comment="Running indicator">
          <Instruction type="XIC" address="B:0/0" column="0" />
          <Instruction type="OTE" address="O:0/1" column="10" />
        </Rung>
      </Rungs>
    </Program>
  </Programs>
</PLCProject>

Error Handling

Load Errors

The loader reports errors with line and column numbers when possible:

Error Description
No PLCProject element found Root element missing or malformed XML
Missing version attribute Required version attribute not present
Symbol missing name attribute Symbol element lacks required name
Symbol missing address attribute Symbol element lacks required address
Invalid address: X:Y/Z Address format not recognized
Duplicate variable name: Name Symbol table contains duplicate names
Unknown instruction type: TYPE Instruction type not recognized
Instruction missing type attribute Instruction element lacks required type

Forward Compatibility

  • Unknown elements are silently skipped
  • Unknown attributes are ignored
  • This allows newer schema versions to be partially read by older software

Implementation Notes

Writing Projects

Use QXmlStreamWriter for generating XML: - Auto-formatting enabled with 2-space indentation - UTF-8 encoding with XML declaration - Empty elements written as <Element /> (self-closing)

Reading Projects

Use QXmlStreamReader for parsing: - Streaming parser for memory efficiency - Element-by-element processing - Error recovery via skipCurrentElement()

API Reference

// Save to file
bool ProjectSerializer::save(const Program *program, const QString &filePath, QString *error);

// Save to device (for testing)
bool ProjectSerializer::save(const Program *program, QIODevice *device, QString *error);

// Load from file
Program* ProjectSerializer::load(const QString &filePath, QString *error);

// Load from device (for testing)
Program* ProjectSerializer::load(QIODevice *device, QString *error);

See Also