为什么我们需要 LadderScript

在 PLC 编程中,管理梯形图(Ladder Logic)文件可能很棘手。不同的 PLC 厂商以各种格式存储其文件,通常使用二进制文件,这使得 Git 等版本控制工具难以使用。有些厂商提供 XML 导出,但这些格式仍然难以阅读和处理。LadderScript 旨在通过为梯形图提供一种标准、易读的文本格式来解决这个问题。

1、不同 PLC 厂商如何存储梯形图

1.1 二进制格式

大多数 PLC 厂商使用二进制格式存储其项目文件。这使得版本控制工具难以使用,因为二进制文件不易比较或合并。这与传统软件开发中基于文本的代码为常态的做法截然不同。

1.2 XML 格式

有些厂商允许以 XML 格式导出项目,这更好一些,但仍不理想。每家厂商使用不同的 XML 格式,而且这些文件通常难以阅读。下面是一些不同 PLC 厂商如何以 XML 存储项目文件的示例。

1.3 PLCopenXML

PLCopen XML 试图为以 XML 存储梯形图制定标准。虽然它比二进制更好,但仍然复杂且难以阅读。

<FunctionBlock name="LD_FB">
  <Parameters>
    <OutputVars>
      <Variable name="Output" orderWithinParamSet="1">
        <Type>
          <TypeName>BOOL</TypeName>
        </Type>
      </Variable>
    </OutputVars>
  </Parameters>
  <Vars accessSpecifier="private">
    <Variable name="S1">
      <Type>
        <TypeName>BOOL</TypeName>
      </Type>
      <InitialValue>
        <SimpleValue value="TRUE" />
      </InitialValue>
    </Variable>
    <Variable name="S2">
      <Type>
        <TypeName>BOOL</TypeName>
      </Type>
    </Variable>
    <Variable name="S1TON">
      <Type>
        <TypeName>TON</TypeName>
      </Type>
    </Variable>
    <Variable name="S2TON">
      <Type>
        <TypeName>TON</TypeName>
      </Type>
    </Variable>
  </Vars>
  <MainBody>
    <BodyContent xsi:type="LD">
      <Rung evaluationOrder="1">
        <RelPosition x="1" y="1" />
        <CommonObject xsi:type="Comment">
          <RelPosition x="1" y="0" />
          <Content xsi:type="SimpleText">S1 -> S2</Content>
        </CommonObject>
        <LdObject xsi:type="LeftPowerRail">
          <RelPosition x="1" y="0" />
          <ConnectionPointOut connectionPointOutId="1">
            <RelPosition x="0" y="7" />
          </ConnectionPointOut>
          <ConnectionPointOut connectionPointOutId="2">
            <RelPosition x="0" y="15" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" operand="S1">
          <RelPosition x="4" y="4" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="1" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="3">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <FbdObject xsi:type="DataSource" identifier="T#1s">
          <RelPosition x="8" y="9" />
          <ConnectionPointOut connectionPointOutId="4">
            <RelPosition x="4.2" y="1" />
          </ConnectionPointOut>
        </FbdObject>
        <FbdObject xsi:type="Block" typeName="TON" instanceName="S1TON">
          <RelPosition x="13" y="4" />
          <InputVariables>
            <InputVariable parameterName="IN">
              <ConnectionPointIn>
                <RelPosition x="0" y="3" />
                <Connection refConnectionPointOutId="3" />
              </ConnectionPointIn>
            </InputVariable>
            <InputVariable parameterName="PT">
              <ConnectionPointIn>
                <RelPosition x="0" y="6" />
                <Connection refConnectionPointOutId="4" />
              </ConnectionPointIn>
            </InputVariable>
          </InputVariables>
          <OutputVariables>
            <OutputVariable parameterName="Q">
              <ConnectionPointOut connectionPointOutId="5">
                <RelPosition x="5" y="3" />
              </ConnectionPointOut>
            </OutputVariable>
            <OutputVariable parameterName="ET">
              <ConnectionPointOut connectionPointOutId="6">
                <RelPosition x="5" y="6" />
              </ConnectionPointOut>
            </OutputVariable>
          </OutputVariables>
        </FbdObject>
        <LdObject xsi:type="Contact" operand="S2">
          <RelPosition x="4" y="12" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="2"></Connection>
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="7">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Coil" operand="S2">
          <RelPosition x="32" y="4" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="5" />
            <Connection refConnectionPointOutId="7">
              <RelPosition x="-10" y="0" />
              <RelPosition x="-10" y="8" />
            </Connection>
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="8">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="RightPowerRail">
          <RelPosition x="40" y="0" />
          <ConnectionPointIn>
            <RelPosition x="0" y="7" />
            <Connection refConnectionPointOutId="8" />
          </ConnectionPointIn>
        </LdObject>
      </Rung>
      <Rung evaluationOrder="2">
        <RelPosition x="1" y="18" />
        <LdObject xsi:type="LeftPowerRail">
          <RelPosition x="1" y="0" />
          <ConnectionPointOut connectionPointOutId="1">
            <RelPosition x="0" y="5" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" negated="true" operand="S1TON.Q">
          <RelPosition x="4" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="1" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="2">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" operand="S1">
          <RelPosition x="11" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="2" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="3">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Coil" operand="S1">
          <RelPosition x="32" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="3" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="4">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="RightPowerRail">
          <RelPosition x="40" y="0" />
          <ConnectionPointIn>
            <RelPosition x="0" y="5" />
            <Connection refConnectionPointOutId="4" />
          </ConnectionPointIn>
        </LdObject>
      </Rung>
      <Rung evaluationOrder="3">
        <RelPosition x="1" y="26" />
        <CommonObject xsi:type="Comment">
          <RelPosition x="1" y="0" />
          <Content xsi:type="SimpleText">S2 -> S1</Content>
        </CommonObject>
        <LdObject xsi:type="LeftPowerRail">
          <RelPosition x="1" y="0" />
          <ConnectionPointOut connectionPointOutId="1">
            <RelPosition x="0" y="7" />
          </ConnectionPointOut>
          <ConnectionPointOut connectionPointOutId="2">
            <RelPosition x="0" y="15" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" operand="S2">
          <RelPosition x="4" y="4" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="1" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="3">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <FbdObject xsi:type="DataSource" identifier="T#1s">
          <RelPosition x="8" y="9" />
          <ConnectionPointOut connectionPointOutId="4">
            <RelPosition x="4.2" y="1" />
          </ConnectionPointOut>
        </FbdObject>
        <FbdObject xsi:type="Block" typeName="TON" instanceName="S2TON">
          <RelPosition x="13" y="4" />
          <InputVariables>
            <InputVariable parameterName="IN">
              <ConnectionPointIn>
                <RelPosition x="0" y="3" />
                <Connection refConnectionPointOutId="3" />
              </ConnectionPointIn>
            </InputVariable>
            <InputVariable parameterName="PT">
              <ConnectionPointIn>
                <RelPosition x="0" y="6" />
                <Connection refConnectionPointOutId="4" />
              </ConnectionPointIn>
            </InputVariable>
          </InputVariables>
          <OutputVariables>
            <OutputVariable parameterName="Q">
              <ConnectionPointOut connectionPointOutId="5">
                <RelPosition x="5" y="3" />
              </ConnectionPointOut>
            </OutputVariable>
            <OutputVariable parameterName="ET">
              <ConnectionPointOut connectionPointOutId="6">
                <RelPosition x="5" y="6" />
              </ConnectionPointOut>
            </OutputVariable>
          </OutputVariables>
        </FbdObject>
        <LdObject xsi:type="Contact" operand="S1">
          <RelPosition x="4" y="12" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="2"></Connection>
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="7">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Coil" operand="S1">
          <RelPosition x="32" y="4" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="5" />
            <Connection refConnectionPointOutId="7">
              <RelPosition x="-10" y="0" />
              <RelPosition x="-10" y="8" />
            </Connection>
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="8">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="RightPowerRail">
          <RelPosition x="40" y="0" />
          <ConnectionPointIn>
            <RelPosition x="0" y="7" />
            <Connection refConnectionPointOutId="8" />
          </ConnectionPointIn>
        </LdObject>
      </Rung>
      <Rung evaluationOrder="4">
        <RelPosition x="1" y="43" />
        <LdObject xsi:type="LeftPowerRail">
          <RelPosition x="1" y="0" />
          <ConnectionPointOut connectionPointOutId="1">
            <RelPosition x="0" y="5" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" negated="true" operand="S2TON.Q">
          <RelPosition x="4" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="1" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="2">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" operand="S2">
          <RelPosition x="11" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="2" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="3">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Coil" operand="S2">
          <RelPosition x="32" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="3" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="4">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="RightPowerRail">
          <RelPosition x="40" y="0" />
          <ConnectionPointIn>
            <RelPosition x="0" y="5" />
            <Connection refConnectionPointOutId="4" />
          </ConnectionPointIn>
        </LdObject>
      </Rung>
      <Rung evaluationOrder="5">
        <RelPosition x="1" y="51" />
        <CommonObject xsi:type="Comment">
          <RelPosition x="1" y="0" />
          <Content xsi:type="SimpleText">Output</Content>
        </CommonObject>
        <LdObject xsi:type="LeftPowerRail">
          <RelPosition x="1" y="0" />
          <ConnectionPointOut connectionPointOutId="1">
            <RelPosition x="0" y="5" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Contact" operand="S1">
          <RelPosition x="4" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="1" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="2">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="Coil" operand="Output">
          <RelPosition x="32" y="2" />
          <ConnectionPointIn>
            <RelPosition x="2" y="3" />
            <Connection refConnectionPointOutId="2" />
          </ConnectionPointIn>
          <ConnectionPointOut connectionPointOutId="3">
            <RelPosition x="4" y="3" />
          </ConnectionPointOut>
        </LdObject>
        <LdObject xsi:type="RightPowerRail">
          <RelPosition x="40" y="0" />
          <ConnectionPointIn>
            <RelPosition x="0" y="5" />
            <Connection refConnectionPointOutId="3" />
          </ConnectionPointIn>
        </LdObject>
      </Rung>
    </BodyContent>
  </MainBody>
</FunctionBlock>

2、Codesys

Codesys 使用 PLCopenXML 进行导出,但结构有所不同。例如,元素位置值始终为 0,这意味着它们可能被编辑器忽略。

      <pou name="PLC_PRG" pouType="program">
        <interface>
          <localVars>
            <variable name="S1">
              <type>
                <BOOL />
              </type>
            </variable>
            <variable name="S2">
              <type>
                <BOOL />
              </type>
            </variable>
            <variable name="S1TON">
              <type>
                <derived name="TON" />
              </type>
            </variable>
            <variable name="S2TON">
              <type>
                <derived name="TON" />
              </type>
            </variable>
          </localVars>
          <outputVars>
            <variable name="Output">
              <type>
                <BOOL />
              </type>
            </variable>
          </outputVars>
        </interface>
        <body>
          <LD>
            <leftPowerRail localId="0">
              <position x="0" y="0" />
              <connectionPointOut formalParameter="none" />
            </leftPowerRail>
            <comment localId="1" height="0" width="0">
              <position x="0" y="0" />
              <content>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </content>
            </comment>
            <vendorElement localId="2">
              <position x="0" y="0" />
              <alternativeText>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </alternativeText>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdelementtype" handleUnknown="implementation">
                  <ElementType xmlns="">networktitle</ElementType>
                </data>
              </addData>
            </vendorElement>
            <contact localId="5" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1</variable>
            </contact>
            <inVariable localId="6">
              <position x="0" y="0" />
              <connectionPointOut />
              <expression>T#1S</expression>
            </inVariable>
            <block localId="4" typeName="TON" instanceName="S1TON">
              <position x="0" y="0" />
              <inputVariables>
                <variable formalParameter="IN">
                  <connectionPointIn>
                    <connection refLocalId="5" />
                  </connectionPointIn>
                </variable>
                <variable formalParameter="PT">
                  <connectionPointIn>
                    <connection refLocalId="6" />
                  </connectionPointIn>
                </variable>
              </inputVariables>
              <inOutVariables />
              <outputVariables>
                <variable formalParameter="Q">
                  <connectionPointOut />
                </variable>
                <variable formalParameter="ET">
                  <connectionPointOut>
                    <expression />
                  </connectionPointOut>
                </variable>
              </outputVariables>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdcalltype" handleUnknown="implementation">
                  <CallType xmlns="">functionblock</CallType>
                </data>
              </addData>
            </block>
            <contact localId="7" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S2</variable>
            </contact>
            <vendorElement localId="3">
              <position x="0" y="0" />
              <alternativeText>
                <xhtml xmlns="http://www.w3.org/1999/xhtml">ParallelBranch</xhtml>
              </alternativeText>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/ldparallelbranch" handleUnknown="implementation">
                  <ParallelBranch mode="seq" xmlns="">
                    <BranchInput>
                      <connectionPointIn>
                        <connection refLocalId="0" />
                      </connectionPointIn>
                    </BranchInput>
                    <BranchTrees>
                      <Tree>
                        <connectionPointIn>
                          <connection refLocalId="4" formalParameter="Q" />
                        </connectionPointIn>
                      </Tree>
                      <Tree>
                        <connectionPointIn>
                          <connection refLocalId="7" />
                        </connectionPointIn>
                      </Tree>
                    </BranchTrees>
                  </ParallelBranch>
                </data>
              </addData>
            </vendorElement>
            <coil localId="8" negated="false" storage="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="4" />
                <connection refLocalId="7" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S2</variable>
            </coil>
            <comment localId="9" height="0" width="0">
              <position x="0" y="0" />
              <content>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </content>
            </comment>
            <vendorElement localId="10">
              <position x="0" y="0" />
              <alternativeText>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </alternativeText>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdelementtype" handleUnknown="implementation">
                  <ElementType xmlns="">networktitle</ElementType>
                </data>
              </addData>
            </vendorElement>
            <contact localId="11" negated="true" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1TON.Q</variable>
            </contact>
            <contact localId="12" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="11" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1</variable>
            </contact>
            <coil localId="13" negated="false" storage="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="12" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1</variable>
            </coil>
            <comment localId="14" height="0" width="0">
              <position x="0" y="0" />
              <content>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </content>
            </comment>
            <vendorElement localId="15">
              <position x="0" y="0" />
              <alternativeText>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </alternativeText>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdelementtype" handleUnknown="implementation">
                  <ElementType xmlns="">networktitle</ElementType>
                </data>
              </addData>
            </vendorElement>
            <contact localId="17" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S2</variable>
            </contact>
            <inVariable localId="18">
              <position x="0" y="0" />
              <connectionPointOut />
              <expression>T#1S</expression>
            </inVariable>
            <block localId="16" typeName="TON" instanceName="S2TON">
              <position x="0" y="0" />
              <inputVariables>
                <variable formalParameter="IN">
                  <connectionPointIn>
                    <connection refLocalId="17" />
                  </connectionPointIn>
                </variable>
                <variable formalParameter="PT">
                  <connectionPointIn>
                    <connection refLocalId="18" />
                  </connectionPointIn>
                </variable>
              </inputVariables>
              <inOutVariables />
              <outputVariables>
                <variable formalParameter="Q">
                  <connectionPointOut />
                </variable>
                <variable formalParameter="ET">
                  <connectionPointOut>
                    <expression />
                  </connectionPointOut>
                </variable>
              </outputVariables>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdcalltype" handleUnknown="implementation">
                  <CallType xmlns="">functionblock</CallType>
                </data>
              </addData>
            </block>
            <contact localId="19" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1</variable>
            </contact>
            <coil localId="20" negated="false" storage="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="16" />
                <connection refLocalId="19" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1</variable>
            </coil>
            <comment localId="21" height="0" width="0">
              <position x="0" y="0" />
              <content>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </content>
            </comment>
            <vendorElement localId="22">
              <position x="0" y="0" />
              <alternativeText>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </alternativeText>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdelementtype" handleUnknown="implementation">
                  <ElementType xmlns="">networktitle</ElementType>
                </data>
              </addData>
            </vendorElement>
            <contact localId="23" negated="true" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S2TON.Q</variable>
            </contact>
            <contact localId="24" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="23" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S2</variable>
            </contact>
            <coil localId="25" negated="false" storage="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="24" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S2</variable>
            </coil>
            <comment localId="26" height="0" width="0">
              <position x="0" y="0" />
              <content>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </content>
            </comment>
            <vendorElement localId="27">
              <position x="0" y="0" />
              <alternativeText>
                <xhtml xmlns="http://www.w3.org/1999/xhtml" />
              </alternativeText>
              <addData>
                <data name="http://www.3s-software.com/plcopenxml/fbdelementtype" handleUnknown="implementation">
                  <ElementType xmlns="">networktitle</ElementType>
                </data>
              </addData>
            </vendorElement>
            <contact localId="28" negated="false" storage="none" edge="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="0" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>S1</variable>
            </contact>
            <coil localId="29" negated="false" storage="none">
              <position x="0" y="0" />
              <connectionPointIn>
                <connection refLocalId="28" />
              </connectionPointIn>
              <connectionPointOut />
              <variable>Output</variable>
            </coil>
            <rightPowerRail localId="2147483646">
              <position x="0" y="0" />
              <connectionPointIn />
            </rightPowerRail>
          </LD>
        </body>
        <addData>
          <data name="http://www.3s-software.com/plcopenxml/objectid" handleUnknown="discard">
            <ObjectId>6b7e38b6-d20c-49d8-8996-c2bab4f21546</ObjectId>
          </data>
        </addData>
      </pou>

3、Siemens TIA Portal

西门子 TIA Portal 有一个版本控制工作区,程序文件以 XML 存储,提供了一种结构化但复杂的格式。

<?xml version="1.0" encoding="utf-8"?>
<Document>
  <Engineering version="V17" />
  <DocumentInfo>
    <Created>2024-06-24T19:29:50.1427684Z</Created>
    <ExportSetting>WithDefaults</ExportSetting>
    <InstalledProducts>
      <Product>
        <DisplayName>Totally Integrated Automation Portal</DisplayName>
        <DisplayVersion>V17 Update 6</DisplayVersion>
      </Product>
      <OptionPackage>
        <DisplayName>TIA Portal Openness</DisplayName>
        <DisplayVersion>V17 Update 6</DisplayVersion>
      </OptionPackage>
      <OptionPackage>
        <DisplayName>TIA Portal Teamcenter Gateway</DisplayName>
        <DisplayVersion>V17 Update 6</DisplayVersion>
      </OptionPackage>
      <OptionPackage>
        <DisplayName>TIA Portal Version Control Interface</DisplayName>
        <DisplayVersion>V17</DisplayVersion>
      </OptionPackage>
      <Product>
        <DisplayName>STEP 7 Professional</DisplayName>
        <DisplayVersion>V17 Update 6</DisplayVersion>
      </Product>
      <OptionPackage>
        <DisplayName>STEP 7 Safety</DisplayName>
        <DisplayVersion>V17 Update 6</DisplayVersion>
      </OptionPackage>
      <Product>
        <DisplayName>WinCC Advanced / Unified PC</DisplayName>
        <DisplayVersion>V17 Update 6</DisplayVersion>
      </Product>
    </InstalledProducts>
  </DocumentInfo>
  <SW.Blocks.FB ID="0">
    <AttributeList>
      <AutoNumber>true</AutoNumber>
      <HeaderAuthor />
      <HeaderFamily />
      <HeaderName />
      <HeaderVersion>0.1</HeaderVersion>
      <Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
  <Section Name="Input" />
  <Section Name="Output">
    <Member Name="Output" Datatype="Bool" Remanence="NonRetain" Accessibility="Public"><AttributeList><BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute></AttributeList></Member>
  </Section>
  <Section Name="InOut" />
  <Section Name="Static">
    <Member Name="S1TON" Datatype="TON_TIME" Version="1.0" Remanence="NonRetain" Accessibility="Public"><AttributeList><BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute></AttributeList><Sections><Section Name="None"><Member Name="PT" Datatype="Time" /><Member Name="ET" Datatype="Time" /><Member Name="IN" Datatype="Bool" /><Member Name="Q" Datatype="Bool" /></Section></Sections></Member>
    <Member Name="S2TON" Datatype="TON_TIME" Version="1.0" Remanence="NonRetain" Accessibility="Public"><AttributeList><BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute><BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute></AttributeList><Sections><Section Name="None"><Member Name="PT" Datatype="Time" /><Member Name="ET" Datatype="Time" /><Member Name="IN" Datatype="Bool" /><Member Name="Q" Datatype="Bool" /></Section></Sections></Member>
    <Member Name="S1" Datatype="Bool" Remanence="NonRetain" Accessibility="Public"><AttributeList><BooleanAttribute Name="ExternalAccessible" SystemDefined="true">false</BooleanAttribute><BooleanAttribute Name="ExternalVisible" SystemDefined="true">false</BooleanAttribute><BooleanAttribute Name="ExternalWritable" SystemDefined="true">false</BooleanAttribute><BooleanAttribute Name="SetPoint" SystemDefined="true">false</BooleanAttribute></AttributeList></Member>
    <Member Name="S2" Datatype="Bool" Remanence="NonRetain" Accessibility="Public"><AttributeList><BooleanAttribute Name="ExternalAccessible" SystemDefined="true">false</BooleanAttribute><BooleanAttribute Name="ExternalVisible" SystemDefined="true">false</BooleanAttribute><BooleanAttribute Name="ExternalWritable" SystemDefined="true">false</BooleanAttribute><BooleanAttribute Name="SetPoint" SystemDefined="true">false</BooleanAttribute></AttributeList></Member>
  </Section>
  <Section Name="Temp" />
  <Section Name="Constant" />
</Sections></Interface>
      <IsIECCheckEnabled>false</IsIECCheckEnabled>
      <IsRetainMemResEnabled>false</IsRetainMemResEnabled>
      <MemoryLayout>Optimized</MemoryLayout>
      <MemoryReserve>100</MemoryReserve>
      <Name>PLC_PRG</Name>
      <Number>3</Number>
      <ProgrammingLanguage>LAD</ProgrammingLanguage>
      <SetENOAutomatically>false</SetENOAutomatically>
      <UDABlockProperties />
      <UDAEnableTagReadback>false</UDAEnableTagReadback>
    </AttributeList>
    <ObjectList>
      <MultilingualText ID="1" CompositionName="Comment">
        <ObjectList>
          <MultilingualTextItem ID="2" CompositionName="Items">
            <AttributeList>
              <Culture>en-US</Culture>
              <Text />
            </AttributeList>
          </MultilingualTextItem>
        </ObjectList>
      </MultilingualText>
      <SW.Blocks.CompileUnit ID="3" CompositionName="CompileUnits">
        <AttributeList>
          <NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
  <Parts>
    <Access Scope="LocalVariable" UId="21">
      <Symbol>
        <Component Name="S1" />
      </Symbol>
    </Access>
    <Access Scope="TypedConstant" UId="22">
      <Constant>
        <ConstantValue>T#1s</ConstantValue>
      </Constant>
    </Access>
    <Access Scope="LocalVariable" UId="23">
      <Symbol>
        <Component Name="S2" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="24">
      <Symbol>
        <Component Name="S2" />
      </Symbol>
    </Access>
    <Part Name="Contact" UId="25" />
    <Part Name="TON" Version="1.0" UId="26">
      <Instance Scope="LocalVariable" UId="27">
        <Component Name="S1TON" />
      </Instance>
      <TemplateValue Name="time_type" Type="Type">Time</TemplateValue>
    </Part>
    <Part Name="Contact" UId="28" />
    <Part Name="O" UId="29">
      <TemplateValue Name="Card" Type="Cardinality">2</TemplateValue>
    </Part>
    <Part Name="Coil" UId="30" />
  </Parts>
  <Wires>
    <Wire UId="32">
      <Powerrail />
      <NameCon UId="25" Name="in" />
      <NameCon UId="28" Name="in" />
    </Wire>
    <Wire UId="33">
      <IdentCon UId="21" />
      <NameCon UId="25" Name="operand" />
    </Wire>
    <Wire UId="34">
      <NameCon UId="25" Name="out" />
      <NameCon UId="26" Name="IN" />
    </Wire>
    <Wire UId="35">
      <IdentCon UId="22" />
      <NameCon UId="26" Name="PT" />
    </Wire>
    <Wire UId="36">
      <NameCon UId="26" Name="Q" />
      <NameCon UId="29" Name="in1" />
    </Wire>
    <Wire UId="37">
      <NameCon UId="26" Name="ET" />
      <OpenCon UId="31" />
    </Wire>
    <Wire UId="38">
      <IdentCon UId="23" />
      <NameCon UId="28" Name="operand" />
    </Wire>
    <Wire UId="39">
      <NameCon UId="28" Name="out" />
      <NameCon UId="29" Name="in2" />
    </Wire>
    <Wire UId="40">
      <NameCon UId="29" Name="out" />
      <NameCon UId="30" Name="in" />
    </Wire>
    <Wire UId="41">
      <IdentCon UId="24" />
      <NameCon UId="30" Name="operand" />
    </Wire>
  </Wires>
</FlgNet></NetworkSource>
          <ProgrammingLanguage>LAD</ProgrammingLanguage>
        </AttributeList>
        <ObjectList>
          <MultilingualText ID="4" CompositionName="Comment">
            <ObjectList>
              <MultilingualTextItem ID="5" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
          <MultilingualText ID="6" CompositionName="Title">
            <ObjectList>
              <MultilingualTextItem ID="7" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
        </ObjectList>
      </SW.Blocks.CompileUnit>
      <SW.Blocks.CompileUnit ID="8" CompositionName="CompileUnits">
        <AttributeList>
          <NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
  <Parts>
    <Access Scope="LocalVariable" UId="21">
      <Symbol>
        <Component Name="S1TON" />
        <Component Name="Q" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="22">
      <Symbol>
        <Component Name="S1" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="23">
      <Symbol>
        <Component Name="S1" />
      </Symbol>
    </Access>
    <Part Name="Contact" UId="24">
      <Negated Name="operand" />
    </Part>
    <Part Name="Contact" UId="25" />
    <Part Name="Coil" UId="26" />
  </Parts>
  <Wires>
    <Wire UId="27">
      <Powerrail />
      <NameCon UId="24" Name="in" />
    </Wire>
    <Wire UId="28">
      <IdentCon UId="21" />
      <NameCon UId="24" Name="operand" />
    </Wire>
    <Wire UId="29">
      <NameCon UId="24" Name="out" />
      <NameCon UId="25" Name="in" />
    </Wire>
    <Wire UId="30">
      <IdentCon UId="22" />
      <NameCon UId="25" Name="operand" />
    </Wire>
    <Wire UId="31">
      <NameCon UId="25" Name="out" />
      <NameCon UId="26" Name="in" />
    </Wire>
    <Wire UId="32">
      <IdentCon UId="23" />
      <NameCon UId="26" Name="operand" />
    </Wire>
  </Wires>
</FlgNet></NetworkSource>
          <ProgrammingLanguage>LAD</ProgrammingLanguage>
        </AttributeList>
        <ObjectList>
          <MultilingualText ID="9" CompositionName="Comment">
            <ObjectList>
              <MultilingualTextItem ID="A" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
          <MultilingualText ID="B" CompositionName="Title">
            <ObjectList>
              <MultilingualTextItem ID="C" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
        </ObjectList>
      </SW.Blocks.CompileUnit>
      <SW.Blocks.CompileUnit ID="D" CompositionName="CompileUnits">
        <AttributeList>
          <NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
  <Parts>
    <Access Scope="LocalVariable" UId="21">
      <Symbol>
        <Component Name="S2" />
      </Symbol>
    </Access>
    <Access Scope="TypedConstant" UId="22">
      <Constant>
        <ConstantValue>T#1s</ConstantValue>
      </Constant>
    </Access>
    <Access Scope="LocalVariable" UId="23">
      <Symbol>
        <Component Name="S1" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="24">
      <Symbol>
        <Component Name="S1" />
      </Symbol>
    </Access>
    <Part Name="Contact" UId="25" />
    <Part Name="TON" Version="1.0" UId="26">
      <Instance Scope="LocalVariable" UId="27">
        <Component Name="S2TON" />
      </Instance>
      <TemplateValue Name="time_type" Type="Type">Time</TemplateValue>
    </Part>
    <Part Name="Contact" UId="28" />
    <Part Name="O" UId="29">
      <TemplateValue Name="Card" Type="Cardinality">2</TemplateValue>
    </Part>
    <Part Name="Coil" UId="30" />
  </Parts>
  <Wires>
    <Wire UId="32">
      <Powerrail />
      <NameCon UId="25" Name="in" />
      <NameCon UId="28" Name="in" />
    </Wire>
    <Wire UId="33">
      <IdentCon UId="21" />
      <NameCon UId="25" Name="operand" />
    </Wire>
    <Wire UId="34">
      <NameCon UId="25" Name="out" />
      <NameCon UId="26" Name="IN" />
    </Wire>
    <Wire UId="35">
      <IdentCon UId="22" />
      <NameCon UId="26" Name="PT" />
    </Wire>
    <Wire UId="36">
      <NameCon UId="26" Name="Q" />
      <NameCon UId="29" Name="in1" />
    </Wire>
    <Wire UId="37">
      <NameCon UId="26" Name="ET" />
      <OpenCon UId="31" />
    </Wire>
    <Wire UId="38">
      <IdentCon UId="23" />
      <NameCon UId="28" Name="operand" />
    </Wire>
    <Wire UId="39">
      <NameCon UId="28" Name="out" />
      <NameCon UId="29" Name="in2" />
    </Wire>
    <Wire UId="40">
      <NameCon UId="29" Name="out" />
      <NameCon UId="30" Name="in" />
    </Wire>
    <Wire UId="41">
      <IdentCon UId="24" />
      <NameCon UId="30" Name="operand" />
    </Wire>
  </Wires>
</FlgNet></NetworkSource>
          <ProgrammingLanguage>LAD</ProgrammingLanguage>
        </AttributeList>
        <ObjectList>
          <MultilingualText ID="E" CompositionName="Comment">
            <ObjectList>
              <MultilingualTextItem ID="F" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
          <MultilingualText ID="10" CompositionName="Title">
            <ObjectList>
              <MultilingualTextItem ID="11" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
        </ObjectList>
      </SW.Blocks.CompileUnit>
      <SW.Blocks.CompileUnit ID="12" CompositionName="CompileUnits">
        <AttributeList>
          <NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
  <Parts>
    <Access Scope="LocalVariable" UId="21">
      <Symbol>
        <Component Name="S2TON" />
        <Component Name="Q" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="22">
      <Symbol>
        <Component Name="S2" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="23">
      <Symbol>
        <Component Name="S2" />
      </Symbol>
    </Access>
    <Part Name="Contact" UId="24">
      <Negated Name="operand" />
    </Part>
    <Part Name="Contact" UId="25" />
    <Part Name="Coil" UId="26" />
  </Parts>
  <Wires>
    <Wire UId="27">
      <Powerrail />
      <NameCon UId="24" Name="in" />
    </Wire>
    <Wire UId="28">
      <IdentCon UId="21" />
      <NameCon UId="24" Name="operand" />
    </Wire>
    <Wire UId="29">
      <NameCon UId="24" Name="out" />
      <NameCon UId="25" Name="in" />
    </Wire>
    <Wire UId="30">
      <IdentCon UId="22" />
      <NameCon UId="25" Name="operand" />
    </Wire>
    <Wire UId="31">
      <NameCon UId="25" Name="out" />
      <NameCon UId="26" Name="in" />
    </Wire>
    <Wire UId="32">
      <IdentCon UId="23" />
      <NameCon UId="26" Name="operand" />
    </Wire>
  </Wires>
</FlgNet></NetworkSource>
          <ProgrammingLanguage>LAD</ProgrammingLanguage>
        </AttributeList>
        <ObjectList>
          <MultilingualText ID="13" CompositionName="Comment">
            <ObjectList>
              <MultilingualTextItem ID="14" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
          <MultilingualText ID="15" CompositionName="Title">
            <ObjectList>
              <MultilingualTextItem ID="16" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
        </ObjectList>
      </SW.Blocks.CompileUnit>
      <SW.Blocks.CompileUnit ID="17" CompositionName="CompileUnits">
        <AttributeList>
          <NetworkSource><FlgNet xmlns="http://www.siemens.com/automation/Openness/SW/NetworkSource/FlgNet/v4">
  <Parts>
    <Access Scope="LocalVariable" UId="21">
      <Symbol>
        <Component Name="S1" />
      </Symbol>
    </Access>
    <Access Scope="LocalVariable" UId="22">
      <Symbol>
        <Component Name="Output" />
      </Symbol>
    </Access>
    <Part Name="Contact" UId="23" />
    <Part Name="Coil" UId="24" />
  </Parts>
  <Wires>
    <Wire UId="25">
      <Powerrail />
      <NameCon UId="23" Name="in" />
    </Wire>
    <Wire UId="26">
      <IdentCon UId="21" />
      <NameCon UId="23" Name="operand" />
    </Wire>
    <Wire UId="27">
      <NameCon UId="23" Name="out" />
      <NameCon UId="24" Name="in" />
    </Wire>
    <Wire UId="28">
      <IdentCon UId="22" />
      <NameCon UId="24" Name="operand" />
    </Wire>
  </Wires>
</FlgNet></NetworkSource>
          <ProgrammingLanguage>LAD</ProgrammingLanguage>
        </AttributeList>
        <ObjectList>
          <MultilingualText ID="18" CompositionName="Comment">
            <ObjectList>
              <MultilingualTextItem ID="19" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
          <MultilingualText ID="1A" CompositionName="Title">
            <ObjectList>
              <MultilingualTextItem ID="1B" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
        </ObjectList>
      </SW.Blocks.CompileUnit>
      <SW.Blocks.CompileUnit ID="1C" CompositionName="CompileUnits">
        <AttributeList>
          <NetworkSource />
          <ProgrammingLanguage>LAD</ProgrammingLanguage>
        </AttributeList>
        <ObjectList>
          <MultilingualText ID="1D" CompositionName="Comment">
            <ObjectList>
              <MultilingualTextItem ID="1E" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
          <MultilingualText ID="1F" CompositionName="Title">
            <ObjectList>
              <MultilingualTextItem ID="20" CompositionName="Items">
                <AttributeList>
                  <Culture>en-US</Culture>
                  <Text />
                </AttributeList>
              </MultilingualTextItem>
            </ObjectList>
          </MultilingualText>
        </ObjectList>
      </SW.Blocks.CompileUnit>
      <MultilingualText ID="21" CompositionName="Title">
        <ObjectList>
          <MultilingualTextItem ID="22" CompositionName="Items">
            <AttributeList>
              <Culture>en-US</Culture>
              <Text />
            </AttributeList>
          </MultilingualTextItem>
        </ObjectList>
      </MultilingualText>
    </ObjectList>
  </SW.Blocks.FB>
</Document>

4、Rockwell Automation Studio 5000

罗克韦尔自动化 Studio 5000 提供最小的 XML 文件导出。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RSLogix5000Content SchemaRevision="1.0" SoftwareRevision="33.02" TargetName="PLC_PRG" TargetType="Program" ContainsContext="true" Owner="szymon.palczynski@gmail.com" ExportDate="Mon Jun 24 20:50:17 2024" ExportOptions="References NoRawData L5KData DecoratedData Context Dependencies ForceProtectedEncoding AllProjDocTrans">
<Controller Use="Context" Name="emulate">
<DataTypes Use="Context">
</DataTypes>
<Programs Use="Context">
<Program Use="Target" Name="PLC_PRG" TestEdits="false" MainRoutineName="Main" Disabled="false" UseAsFolder="false">
<Tags>
<Tag Name="Output" TagType="Base" DataType="BOOL" Radix="Decimal" Usage="Output" Constant="false" ExternalAccess="Read Only">
<Data Format="L5K">
<![CDATA[0]]>
</Data>
<Data Format="Decorated">
<DataValue DataType="BOOL" Radix="Decimal" Value="0"/>
</Data>
</Tag>
<Tag Name="S1" TagType="Base" DataType="BOOL" Radix="Decimal" Constant="false" ExternalAccess="Read/Write">
<Data Format="L5K">
<![CDATA[0]]>
</Data>
<Data Format="Decorated">
<DataValue DataType="BOOL" Radix="Decimal" Value="0"/>
</Data>
</Tag>
<Tag Name="S1TON" TagType="Base" DataType="TIMER" Constant="false" ExternalAccess="Read/Write">
<Data Format="L5K">
<![CDATA[[0,1000,0]]]>
</Data>
<Data Format="Decorated">
<Structure DataType="TIMER">
<DataValueMember Name="PRE" DataType="DINT" Radix="Decimal" Value="1000"/>
<DataValueMember Name="ACC" DataType="DINT" Radix="Decimal" Value="0"/>
<DataValueMember Name="EN" DataType="BOOL" Value="0"/>
<DataValueMember Name="TT" DataType="BOOL" Value="0"/>
<DataValueMember Name="DN" DataType="BOOL" Value="0"/>
</Structure>
</Data>
</Tag>
<Tag Name="S2" TagType="Base" DataType="BOOL" Radix="Decimal" Constant="false" ExternalAccess="Read/Write">
<Data Format="L5K">
<![CDATA[0]]>
</Data>
<Data Format="Decorated">
<DataValue DataType="BOOL" Radix="Decimal" Value="0"/>
</Data>
</Tag>
<Tag Name="S2TON" TagType="Base" DataType="TIMER" Constant="false" ExternalAccess="Read/Write">
<Data Format="L5K">
<![CDATA[[0,1000,0]]]>
</Data>
<Data Format="Decorated">
<Structure DataType="TIMER">
<DataValueMember Name="PRE" DataType="DINT" Radix="Decimal" Value="1000"/>
<DataValueMember Name="ACC" DataType="DINT" Radix="Decimal" Value="0"/>
<DataValueMember Name="EN" DataType="BOOL" Value="0"/>
<DataValueMember Name="TT" DataType="BOOL" Value="0"/>
<DataValueMember Name="DN" DataType="BOOL" Value="0"/>
</Structure>
</Data>
</Tag>
</Tags>
<Routines>
<Routine Name="Main" Type="RLL">
<RLLContent>
<Rung Number="0" Type="N">
<Text>
<![CDATA[[XIC(S1) TON(S1TON,?,?) XIC(S1TON.DN) ,XIC(S2) ]OTE(S2);]]>
</Text>
</Rung>
<Rung Number="1" Type="N">
<Text>
<![CDATA[XIO(S1TON.DN)XIC(S1)OTE(S1);]]>
</Text>
</Rung>
<Rung Number="2" Type="N">
<Text>
<![CDATA[[XIC(S2) TON(S2TON,?,?) XIC(S2TON.DN) ,XIC(S1) ]OTE(S1);]]>
</Text>
</Rung>
<Rung Number="3" Type="N">
<Text>
<![CDATA[XIO(S2TON.DN)XIC(S2)OTE(S2);]]>
</Text>
</Rung>
<Rung Number="4" Type="N">
<Text>
<![CDATA[XIC(S1)OTE(Output);]]>
</Text>
</Rung>
</RLLContent>
</Routine>
</Routines>
</Program>
</Programs>
</Controller>
</RSLogix5000Content>

最重要的是,它将梯级(rung)代码保存为纯文本,相当容易阅读和比较。

[XIC(S1)TON(S1TON,?,?)XIC(S1TON.DN),XIC(S2)]OTE(S2);
XIO(S1TON.DN)XIC(S1)OTE(S1);
[XIC(S2)TON(S2TON,?,?)XIC(S2TON.DN),XIC(S1)]OTE(S1);
XIO(S2TON.DN)XIC(S2)OTE(S2);
XIC(S1)OTE(Output);

5、FactoryTalk Design Studio

有趣的是,罗克韦尔最新的产品 FactoryTalk Design Studio 允许以纯文本格式编辑梯形图。这代表了 PLC 编程世界向前迈出的重要一步。然而,基于 Web 的 IDE 实现存在卡顿问题,可能会影响生产力。

routine ld Area.smart_object.program1.main(
    output BOOL ^Output
) {

    [XIC(S1)TON(S1TON)XIC(s1ton.dn),XIC(S2)]OTE(s2);
    XIC(s1ton.dn)XIC(s1)OTE(s1);
    [XIC(S2)TON(S2TON)XIC(S2TON.DN),XIC(s1)]OTE(S1);
    XIC(S2TON.DN)XIC(S2)OTE(S2);
    XIC(s1)OTU(^output);

    tag BOOL S1;
    tag BOOL S2;
    tag TIMER S1TON {
        PRE := 1000;
    };
    tag TIMER S2TON {
        PRE := 1000;
    };
}

6、文本文件的优势

将梯形图保存为文本具有几个重要优势。与二进制文件相比,文本文件天生更易读、更易编辑,使程序员能够快速理解和修改逻辑。这种可读性还有助于使用 Git 等版本控制系统,实现高效的变更跟踪、协作编辑以及不同代码分支的无缝合并。此外,文本文件简化了调试过程和代码评审,因为问题更容易被发现和解决。通过将梯形图标准化为文本格式,我们使 PLC 编程与软件开发的最佳实践保持一致,促进更有条理、更易维护、更少错误的代码。

7、结束语

每家 PLC 制造商都有自己的程序文件存储方式,通常是二进制格式。虽然有些提供 XML 导出,但这些格式并未标准化,而且仍然难以阅读。这使得版本控制系统的使用变得困难,并拖慢了协作。

LadderScript 提出了一种单一的、基于文本的梯形图格式,易于阅读、比较,并可与 Git 等版本控制工具配合使用。由于是开源的,LadderScript 可以被广泛采用,并且可以创建工具将 LadderScript 转换为不同制造商使用的 XML 格式。图形化的 LadderScript 编辑器也可以让创建和管理梯形图变得更加容易。


原文链接: Why we need LadderScript

汇智网翻译整理,转载请标明出处