Click here to Skip to main content
14,546,466 members

Omron PLC Serial Interface

Rate this:
4.75 (21 votes)
Please Sign up or sign in to vote.
4.75 (21 votes)
1 Aug 2011CPOL
Surpass Omron OCX OPC Component and use a user friendly .NET based class to interface Omron PLC Series


If you're tired of using some complex non-realtime COM/COM+ components (as I'm ;D) that force you to connect Omron PLC series and are interested in an easy understanding, open source, real real-time .NET based object, you've just selected the right article.

This article introduces a purely code-based Host link protocol implementation, what you can easily add into your project ensures you a safe reliable RS232/485 PC-PLC communication.


OOP programming and using an accurate implementation in realtime hardware dependant is something I've done once in DeltaDTB PID Controller. You can refer to it from here.

Using the Code

1. Wiring

With no doubt, the most confusing matter one may face, after reading the PDF file reduced from Omron describing the Host Link attributes, is physical connection (cable wiring). After first perusing, I made some wiring hoping it would work, but there was no success despite all my efforts. Finally, the old popular RS232 (2-2, 3-3, 5-5) was the thing answered properly (look at the below picture).


2. Communication Protocol

2.1 Basic Definitions

  • Host Computer

    In host link communication protocol, the host computer (please note Omron refers to "computer" for its PLC series, please don’t mix up!) has the transition priority, but for the case of peer to peer connection (e.g. you directly connected to a PLC via RS232 physical layer) noting this matter is not very important, but if you’re very sensitive and scrupulous about, due to Omron definition "Data transfer between the host computer and the Host Link System is, therefore, initiated when the computer sends a command to a PC in the Host Link System." (part 3-2, Communication Protocol, page 62), the PC which runs the application assumed as Host Computer.

  • Block

    A set of data in a transmission is called a block.

  • Command Block

    The data block sent from the host computer to the Host Link System is called a command block.

  • Response Block

    The block sent from the Host Link System to the computer is called a response block.

  • Multiplex Communication versus Single Link Communication

    In a multiple-link communications system, each block starts with a unit number and a header, and ends with a Frame Checksum (FCS) code and a terminator (* and CR). In a single-link system, however, each block starts with only a header, and ends with only a terminator.

  • Termination

    The terminator in the command block enables the PC to send a response. The terminator in the response block enables the host computer to send another command.

2.2 Block Formation

Below is a scheme of a formal data block. A block is usually made up of one unit called a frame, but long blocks of data (over 131 characters) must be divided into more than one frame before transmission. In a multiple-link system, the first frame can have up to 131 characters, and subsequent frames can have up to 128 characters.

In a single-link system, however, every frame (the first included) has up to 128 characters. The data must then be divided into more than one frame when there is a block consisting of more than 131 characters in a multiple-link system and of more than 128 characters in a single-link system. In this case, the beginning and intermediate blocks end with a delimiter (CR), instead of a terminator (* CR).


Note: In this project, Multiple-link System is assumed as in-use method, so, inserting "@" and unit number is mandatory and done automatically when requests for reading/writing is demanded.

2.2.1 Block Formation with more than one frame in Multi-Link System

First Frame (131 characters or less)


Intermediate Frame(s) (128 Characters or less)


Last Frame (128 characters or less)


2.3 Sending Commands

To send a command block with more than one frame from the computer (host computer), initially send only the first frame in the block. We must wait for sending the next frame until the host computer has received the delimiter which should have been sent back from the PC.

Note: Do not separate data from a single word into different frames for any write command.


The best place of use is when you try to write a long stream of data in a sequence of registers (although I don't advice this matter).

        str_in = str_in & Link.ReadExisting
    Loop While ((str_in.Length < length_predicted) And _
	((DateAndTime.Now.Ticks - tmr_indicator) < lng_length))
    'Checking FCS code
    'Checking PLC Response code (No Command Error)
    'Assume we're waiting for frame(s)
    'The matter that must be checked is the penultimate and the last
    'character received from PLC.
    if mid$(str_in,str_int.length - 1,1)<>"*" then 	'Means some frame(s) 
						'are ready to be received
        'First Process Data 
        'Clear RS232 Input Buffer
        str_out = Link.readExisting
        'str_out = ""
        link.Write(vbCr)'Indicates Host Computer is ready to receive data
    end if
Loop While loop_condition

2.4 Receiving Commands

To receive a response block consisting of more than one frame from the PC, the host computer must send the carriage return code (delimiter) to the PC after receiving the delimiter from the PC. This enables the PC to send the next frame.


Its obvious usage is in Read method, where for example, the user's demanded reading a more 30 consequence registers. After making the string indicates from what address and how many register(s) user requested, we entered a loop waiting for PLC response. Don't forget it's essential to keep the requested numbers in a variable.

Dim loop_count As Integer = 0, count_predicted As Integer = 0, 
_As Long = 0, tmr_indicator As Long = 0, 
_As Integer = 0
Dim str_in As String = "", str_in_final As String = "" 
str_in = Link.ReadExisting()
str_in = "" 
    str_in = "" 
    count_predicted = IIf(count > 30, 30, count)
    If loop_count = 0 Then
        If count_predicted = count Then 
            length_predicted = count_predicted * 4 + 11
            length_predicted = count_predicted * 4 + 10
        End If 
        If count_predicted = count Then 
            length_predicted = count_predicted * 4 + 4
            length_predicted = count_predicted * 4 + 3
        End If
    End If 
    lng_length = (length_predicted * ByteTime * 1000) + delay_ms
    lng_length *= TimeSpan.TicksPerMillisecond
    tmr_indicator = DateAndTime.Now.Ticks
        str_in = str_in & Link.ReadExisting
    Loop While ((str_in.Length < length_predicted) And _
	((DateAndTime.Now.Ticks - tmr_indicator) < lng_length))
    If ((loop_count > 0) And (str_in.Length < length_predicted)) _
	Then Throw New OmronException("Error in Data line, Data corrupted!")
    If loop_count = 0 Then 'Indicates first frame
        p_response = Hex2Int(Mid$(str_in, 6, 2))
        If Mid$(str_in, str_in.Length, 1) <> vbCr Then _
	Throw New OmronException("Error in Data line, Data corrupted!")
        If Not (FCSCode_Get(str_in)) Then Throw New OmronException_
	("Comminucation Error, Please check the line!")If p_response <> _
	Omron_Response_Code.Command_Completed_Normally Then _
	Throw New OmronException(Response(p_response)(0))
        If count_predicted = count Then 'One block contains the whole response 
            str_in_final = str_in_final & Mid$(str_in, 8, str_in.Length - 11)
        Else 'It's the first block of a sequence of response blocks 
            str_in_final = str_in_final & Mid$(str_in, 8, str_in.Length - 10)
        End If
        If count_predicted = count Then 'Indicates last frame 
            str_in_final = str_in_final & Mid$(str_in, 1, str_in.Length - 4)
        Else 'Indicates intermediate frame 
            str_in_final = str_in_final & Mid$(str_in, 1, str_in.Length - 3)
        End If
    End If 
    str_in = Link.ReadExisting
    if count_predicted < count then Link.Write(vbCr)
    str_in = "" 
    count = IIf(count - 30 > 0, count - 30, 0)
    loop_count += 1

Loop While count > 0 

2.5 Data Representation

Unit Address, Register Address and number of registers to be read must be represented in Decimal format, Register contents which to be read/written must be presented in hexadecimal format and Boolean is represented as "1" (ASCII 49dec)(true) and "0" (ASCII 48dec)(false).

2.6 Frame CheckSum (FCS) Calculation

The Frame Checksum is 8-bit data converted into two ASCII characters. The 8-bit data is the result of an EXCLUSIVE OR sequentially performed between each character, from the first character in the frame to the last character of the text in that frame.


Dim [xor] As Integer = IIf(is_last, 0, 64) '@ascii code 
For I As Integer = 1 To Message.Length - 1
    [xor] = [xor] Xor Convert.ToInt32(Convert.ToChar(Message.Substring(I, 1)))
Return ([String].Format("{0:X}",[xor]))

The FCS generator piece of code is mentioned above.

3. Command Level

The tables on pages 60 to 62, give the commands and responses available for the Host Link Units, the command levels, and the modes in which they are applicable. Details of the command and response formats are given in Omron Document, Section 4 Commands and Responses.

Using the Demo, Step by Step

3.1 Running the program


3.2 Checking whether any PLC is connected or not


Program could not find any PLC (No response from PLC).


Program could find a PLC (Response is received).

3.3 Reading PLC Status and Errors


3.4 Reading 30 sequence Registers from PLC



It's my appreciation to thank Prof. Kamalaldin Farzaneh, who is not only my manager, but also my teacher who has let me test, fall and rise again.


  • Creation Time: Wednesday Apr 27 2011
  • First Release: Saturday Apr 30 2011
  • Updated: Tuesday May 03 2011
  • Updated: Sunday July 24 2011, Labview 7.0 Implementation added


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Mahdi Mansouri
Iran (Islamic Republic of) Iran (Islamic Republic of)
Control System Engineer

Comments and Discussions

QuestionWrite bit in working area memory (W) of Omron PLC Pin
Siripong Buasim28-Nov-17 17:54
MemberSiripong Buasim28-Nov-17 17:54 
Questionhow can i write W400.7 a true? Pin
Member 1199292313-Mar-17 16:29
MemberMember 1199292313-Mar-17 16:29 
Questionomron serial port communication Pin
valtuntas16-Mar-16 8:31
Membervaltuntas16-Mar-16 8:31 
QuestionSerial Interface between OMRON CP1E- N to Another API(Software) Pin
Member 117552989-Jun-15 23:29
MemberMember 117552989-Jun-15 23:29 
QuestionCommunicating with Omron CP1H Pin
Member 113624158-Jan-15 12:04
MemberMember 113624158-Jan-15 12:04 
QuestionWrite() not behaving Pin
chriskat26-Oct-14 18:25
Memberchriskat26-Oct-14 18:25 
AnswerRe: Write() not behaving Pin
chriskat28-Oct-14 17:54
Memberchriskat28-Oct-14 17:54 
AnswerRe: Write() not behaving Pin
Mahdi Mansouri1-Dec-14 15:55
MemberMahdi Mansouri1-Dec-14 15:55 
QuestionWhat PLC Pin
fab4real23-Jan-13 0:45
Memberfab4real23-Jan-13 0:45 
AnswerRe: What PLC Pin
fab4real23-Jan-13 3:03
Memberfab4real23-Jan-13 3:03 
GeneralRe: What PLC Pin
Mahdi Mansouri25-Jan-13 1:32
MemberMahdi Mansouri25-Jan-13 1:32 
GeneralRe: What PLC Pin
Mr-H 201010-Jul-13 0:42
MemberMr-H 201010-Jul-13 0:42 
QuestionHie Pin
sajidconsultrics26-Nov-12 11:01
Membersajidconsultrics26-Nov-12 11:01 
AnswerRe: Hie Pin
Mahdi Mansouri25-Jan-13 1:25
MemberMahdi Mansouri25-Jan-13 1:25 
Questiondeny Pin
poliku12-Sep-12 14:34
Memberpoliku12-Sep-12 14:34 
AnswerRe: deny Pin
Mahdi Mansouri27-Oct-12 17:53
MemberMahdi Mansouri27-Oct-12 17:53 
GeneralMy vote of 5 Pin
NeXoR.aT29-Jul-12 23:01
MemberNeXoR.aT29-Jul-12 23:01 
GeneralRe: My vote of 5 Pin
Mahdi Mansouri27-Oct-12 18:41
MemberMahdi Mansouri27-Oct-12 18:41 
QuestionProgram could not find any PLC (No response from PLC). Pin
COl2nSheZz26-Jun-12 16:27
MemberCOl2nSheZz26-Jun-12 16:27 
AnswerRe: Program could not find any PLC (No response from PLC). Pin
Mahdi Mansouri27-Oct-12 17:50
MemberMahdi Mansouri27-Oct-12 17:50 
QuestionError (LabVIEW2010) : "This assembly contains no public controls" Pin
kanjoot10-Apr-12 21:57
Memberkanjoot10-Apr-12 21:57 
AnswerRe: Error (LabVIEW2010) : "This assembly contains no public controls" Pin
Mahdi Mansouri11-Apr-12 23:32
MemberMahdi Mansouri11-Apr-12 23:32 
GeneralTransmission failed in progress Pin
qnguyen522-Mar-12 18:21
Memberqnguyen522-Mar-12 18:21 
AnswerRe: Transmission failed in progress Pin
Mahdi Mansouri23-Mar-12 0:23
MemberMahdi Mansouri23-Mar-12 0:23 
GeneralRe: Transmission failed in progress Pin
qnguyen524-Mar-12 18:15
Memberqnguyen524-Mar-12 18:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Posted 30 Apr 2011


51 bookmarked