Ok there are MANY ways to communicate with a PLC or HMI, or related devices. If youre not sure what a PLC is, allow me to paraphrase:
Programmable Logic Controllers (PLCs) are industry-standard devices designed primarily for controlling high-voltage and industrial systems. Think of them as proprietary, industrial-grade Arduinos. They are not general-purpose computers, and often rely on obscure or archaic programming methods. First introduced in 1969, many PLCs still implement variations of Relay Control Logic (RCL), a system of representing electrical control diagrams that dates back over 160 years.
PLCs are complex in their simplicity. While their core concepts remain consistent, OEMs implement a wide range of communication protocols to enable control and data exchange. Through investigation, clear similarities emerge across these protocols; however, a fully open standard that enables true interoperability between platforms does not yet exist.
This lack of interoperability reinforces vendor lock-in. Once a system is built around a specific manufacturer’s ecosystem, future expansion becomes constrained by compatibility requirements. Even when more suitable or advanced components become available, the cost and complexity of redesigning the system discourages change. In practice, this often limits integration not only across different manufacturers, but even across product lines within the same OEM.
This project explores the development of interoperable control systems using Arduino and Arduino-compatible devices to interface with and control PLCs. The goal is to investigate practical pathways toward more flexible, open, and adaptable industrial control architectures.
#### Using the Arduino MEGA to Communicate with the HMI ##############
The Arduino Mega is acting as an IDEC PLC so the IDEC HMI can connect to it over Ethernet to read and write read PLC data registers.
The HMI expects the PLC at: 192.168.1.50:2101
The HMI initiates the connection, sends read requests, and waits for valid PLC-style replies.
The HMI Has an initialization sequence where it first reads:
Y-M-D-W-H-m-S as 16 bit data registers ( 16 bit words )
HMI -> connects to Arduino on TCP port 2101
HMI -> sends maintenance protocol read command
MEGA -> replies with ACK + data
HMI -> accepts data and updates screen
########## Wait What is Maintenance Protocol?? #########
Maintenace Protocol is one name for a UART style communication framing method.
It follows the pattern:
05 ENQ / start of request
46 46 "FF" device number
30 "0" no continuation
52 "R" read command
44 "D" data register
30 31 35 38 "0158" = D158
30 32 "02" = read 2 bytes
32 44 BCC
0D carriage return / end of frame
########## I've never heard of such a thing! ##########
Maintenance Protocol isnt one of the hot communication models at this time,
but its use is wide spread across the IDEC product lines, and extends to other OEM and devices as well.
There is documentation for the protocol, but its kind of chaotic.
There are MANY documents, writen with varying levels of detail and quality.
I happen to work with IDEC PLCs on a regular basis, and kinda just stumbled upon its use
for a wide range of interesting applications.
# How The protocol works:The protocol request pattern :
ENQ = ACK/NAK
DEVICE = FF/0:N #BYTE
CONTINUATION = 1: wait for more instructions, or 0: don't.
TYPE = Read / Write / Clear
Datatype: bits, words, floats etc
value=bytes varies based on datatype.
checksum=BCC, an XOR operation on the sum of the data being requested.
terminator = \verb|\0h| \\
# Then the server responds with:
ACK/NAK = 06h / 15h indicating success or error
DEVICE = Echo of the addressed device (FF / 1:N)
STATUS = Execution result code (00 = OK, nonzero = error)
DATA = Returned value; format depends on datatype (bit = 0/1, register = word/bytes)
CONTINUATION = 1: more data follows, 0: final response
CHECKSUM = BCC, XOR of all response bytes excluding ENQ and terminator
TERMINATOR = \0d (carriage return)
Sending Method work in both ASCII and HEXADECIMAL
########### Where are the DOCS?? ########
Im working on it.
###### Where is the source?? ##########
Well, it exists, and I could share it, but its not like human readable,
or even extensible for other functions yet.
Ill post something when I have a more friendly interface.
###### TODO:: ##################
* Write interfaces to Analog / Digital IO, I2C, SPI, and CAN to return registers
* Write proper functions, and a human usable library.
* Do more testing.
*write a wrapper for Serial on arduino
####### PONIES ( Dreaming ) ########
I could Make:
an automated system installer ( I already did this, but it uses a PC to run )
a Unit State Emulator
a full system debuger
use of any product compatible with Arduino, or IDEC in the same project
code in C on a PLC
Code in Python on a PLC.
use the arduino as an IoT compatibility layer.
any device or tool that was previously unavailable, or prohibithively expensive, using open scource design patterns.
##### Arduino UNO Q ############
TL;DR: the Arduino Uno Q isn't even an Arduino anymore, let alone an UNO.
I originally intended to do this on the Arduino Uno Q, because on paper it actually looks amazing.
It is basically a Linux SBC disguised as an Arduino.
You get analog IO, shield compatibility, Linux, networking, and a lot of potential flexibility in one package.
Unfortunately, using it for this particular project became increasingly impractical.
That did not stop me from sinking about 12 hours of my precious free time into trying to make the thing cooperate.
I am really trying not to crash out on the Uno Q, because there are things I genuinely like about it.
The hardware concept is cool.
The fact that it can run Linux while, still exposing Arduino-style hardware interfaces opens up a lot of interesting possibilities.
I absolutely plan to use it for future projects.
But for this project specifically, it fought me every step of the way.
I only had to edit one Ethernet shield library source file to get the Ethernet shield working.
That is not a huge obstacle for me personally, but it is absolutely a showstopper for a beginner.
A beginner is going to plug in an Ethernet shield, compile an example, watch it fail, and assume either the board or the shield is defective.
Then there is the Serial library.
They changed the Serial behavior in a way that breaks a massive amount of existing Arduino code and examples.
Yes, technically I can fix it. I probably will fix it by writing a wrapper or adding some compatibility macros.
But that is not really the point.
There are decades worth of code examples, tutorials, forum posts, libraries, videos, blogs, and existing user knowledge
built around the traditional Arduino Serial behavior.
Breaking that compatibility without providing a transparent compatibility layer creates a huge amount of unnecessary grief.
So you end up in this bizarre situation where you have an Arduino that does not run Arduino code.
It would be funnier if I were not trying to actually use the thing.
The larger issue for me, is that I was trying to rapidly prototype a very specific industrial communication project using an existing knowledge base.
I was not trying to stop in the middle of the project and learn an entirely new workflow that breaks the old one.
In fact, that is the antithesis of what I was trying to accomplish.
The goal here is to emulate an IDEC PLC well enough that an IDEC HMI would accept the Arduino as a real controller over maintenance protocol Ethernet communications.
That required focusing on protocol behavior, packet structure, BCC generation, register mapping, and HMI polling patterns,
not debugging framework compatibility problems on a brand new board ecosystem.
So in the end, I went back to the Arduino Mega, implemented a sparse register map to conserve RAM,
and got the HMI fully communicating over TCP port 2101 using maintenance protocol emulation.