Implementing Serial Communication Between a Host Computer and Mitsubishi FX3U PLC via FX-232-BD
This article details the implementation of serial communication between a host computer (PC) and a Mitsubishi FX3U Programmable Logic Controller (PLC) using the FX-232-BD communication board. The communication protocol used is the Mitsubishi computer link protocol with checksum (Sum Check) and protocol format 4.
PLC Configuraton
On the PLC side, the communication parameters must be configured to use the Sum Check + Protocol 4 format.
Reading Data from the PLC
To read a single word (16-bit) from data register D200, the host sends the following command frame:
Command: 05 30 30 46 46 57 52 30 44 30 32 30 30 30 31
Response (value 0x201): 02 30 30 46 46 30 30 43 39 03
Below is a C# method that constructs this read command. The method builds a byte array representing the ASCII characters of the command frame, calculates the checksum, and appends the required terminators.
private void SendReadCommand(string registerAddress)
{
byte[] commandFrame = new byte[20];
commandFrame[0] = 0x05; // ENQ (Start of transmission)
commandFrame[1] = 0x30; // Station Number (ASCII '0')
commandFrame[2] = 0x30; // Station Number (ASCII '0')
commandFrame[3] = 0x46; // PC Number (ASCII 'F')
commandFrame[4] = 0x46; // PC Number (ASCII 'F')
commandFrame[5] = 0x57; // Command Code 'WR' for Read (ASCII 'W')
commandFrame[6] = 0x52; // Command Code 'WR' for Read (ASCII 'R')
commandFrame[7] = 0x30; // Message Wait Time (ASCII '0')
// Register Address (e.g., "D0200")
commandFrame[8] = (byte)registerAddress[0];
commandFrame[9] = (byte)registerAddress[1];
commandFrame[10] = (byte)registerAddress[2];
commandFrame[11] = (byte)registerAddress[3];
commandFrame[12] = (byte)registerAddress[4];
commandFrame[13] = 0x30; // Number of Points (ASCII '0')
commandFrame[14] = 0x31; // Number of Points (ASCII '1')
// Calculate checksum (Sum of bytes 1-14)
int checksumValue = 0;
for (int index = 1; index <= 14; index++)
{
checksumValue += commandFrame[index];
}
string checksumHex = checksumValue.ToString("X");
// Append checksum as ASCII characters
commandFrame[15] = (byte)checksumHex[checksumHex.Length - 2];
commandFrame[16] = (byte)checksumHex[checksumHex.Length - 1];
commandFrame[17] = 0x0D; // CR (Carriage Return)
commandFrame[18] = 0x0A; // LF (Line Feed)
SendToPLC(commandFrame); // Method to send the byte array via serial port
}
Writing Data to the PLC
To write the value 1 (hex 0001) to data register D100, the host sends the following command frame:
Command: 05 30 30 46 46 57 57 30 44 30 31 30 30 30 31 30 30 30 31
Response (ACK): 06 30 30 46 46
The following C# method constructs this write command. It includes the data to be written in the frame before calculating the checksum.
private void SendWriteCommand(string registerAddress, string dataValue)
{
byte[] commandFrame = new byte[24];
commandFrame[0] = 0x05; // ENQ
commandFrame[1] = 0x30; // Station Number
commandFrame[2] = 0x30;
commandFrame[3] = 0x46; // PC Number
commandFrame[4] = 0x46;
commandFrame[5] = 0x57; // Command Code 'WW' for Write (ASCII 'W')
commandFrame[6] = 0x57; // Command Code 'WW' for Write (ASCII 'W')
commandFrame[7] = 0x30; // Message Wait Time
// Register Address (e.g., "D0100")
commandFrame[8] = (byte)registerAddress[0];
commandFrame[9] = (byte)registerAddress[1];
commandFrame[10] = (byte)registerAddress[2];
commandFrame[11] = (byte)registerAddress[3];
commandFrame[12] = (byte)registerAddress[4];
commandFrame[13] = 0x30; // Number of Points
commandFrame[14] = 0x31;
// Data to Write (e.g., "0001")
commandFrame[15] = (byte)dataValue[0];
commandFrame[16] = (byte)dataValue[1];
commandFrame[17] = (byte)dataValue[2];
commandFrame[18] = (byte)dataValue[3];
// Calculate checksum (Sum of bytes 1-18)
int checksumValue = 0;
for (int index = 1; index <= 18; index++)
{
checksumValue += commandFrame[index];
}
string checksumHex = checksumValue.ToString("X");
// Append checksum as ASCII characters
commandFrame[19] = (byte)checksumHex[checksumHex.Length - 2];
commandFrame[20] = (byte)checksumHex[checksumHex.Length - 1];
commandFrame[21] = 0x0D; // CR
commandFrame[22] = 0x0A; // LF
SendToPLC(commandFrame); // Method to send the byte array via serial port
}