Skip to main content

Mitsubishi MC

The MC module supports Mitsubishi MC Protocol 1E / 3E / 4E for Ethernet-based PLC access. Default mode is 3E Binary; ASCII, 1E, and 4E are also supported. Current coverage includes X/Y/M bit devices, D/W/R/ZR word devices, and 3E/4E random access.

Install

dotnet add package Zeus.Communications
dotnet add package Zeus.Protocols.Mc

Connect to a Real PLC

await using var app = ZeusHost.Create(builder =>
{
builder.AddTcpClient("plc-link", "192.168.1.10", 5000);
builder.AddMitsubishiMc("plc", "plc-link");
});

await app.StartAsync();

var plc = app.Devices.Get<McDevice>("plc");
var d100 = await plc.ReadDataRegistersAsync(address: 100, points: 2);
var y20 = await plc.ReadOutputRelaysAsync(address: 0x20, points: 8);
await plc.WriteDataRegistersAsync(address: 200, values: [123, 456]);
await plc.WriteOutputRelaysAsync(address: 0x20, values: [true, false, true, false]);

Pass Mc3EOptions when frame type, encoding, network number, PC number, I/O number, station number, or monitoring timer differs from defaults.

builder.AddMitsubishiMc("plc", "plc-link", new Mc3EOptions
{
FrameType = McFrameType.Frame4E,
DataEncoding = McDataEncoding.Ascii,
SerialNumber = 0x0001,
NetworkNumber = 0x00,
PcNumber = 0xFF,
IoNumber = 0x03FF,
StationNumber = 0x00,
MonitoringTimer = 0x0010
});

Common Device APIs

var d = await plc.ReadDataRegistersAsync(100, 4);
await plc.WriteDataRegistersAsync(100, [10, 20, 30, 40]);

var m = await plc.ReadInternalRelaysAsync(100, 8);
await plc.WriteInternalRelaysAsync(100, [true, false, true, false]);

var x = await plc.ReadInputRelaysAsync(0x10, 8);
var y = await plc.ReadOutputRelaysAsync(0x20, 8);
await plc.WriteOutputRelaysAsync(0x20, [true, false, true, false]);

var w = await plc.ReadLinkRegistersAsync(100, 2);
var r = await plc.ReadFileRegistersAsync(100, 2);
var zr = await plc.ReadExtendedFileRegistersAsync(100, 2);

Use generic APIs when you want to specify McDeviceCode directly:

var words = await plc.ReadWordsAsync(McDeviceCode.DataRegister, 100, 2);
var bits = await plc.ReadBitsAsync(McDeviceCode.InternalRelay, 100, 8);

Random Access

3E / 4E frames can access non-consecutive devices in one transaction:

var random = await plc.ReadRandomAsync(
wordDevices:
[
new McDeviceAddress(McDeviceCode.DataRegister, 100),
new McDeviceAddress(McDeviceCode.LinkRegister, 10)
],
doubleWordDevices:
[
new McDeviceAddress(McDeviceCode.DataRegister, 200)
]);

await plc.WriteRandomWordsAsync(
wordValues:
[
new McWordWrite(McDeviceCode.DataRegister, 110, 1234)
],
doubleWordValues:
[
new McDoubleWordWrite(McDeviceCode.DataRegister, 210, 0x12345678)
]);

Simulate Without a PLC

var memory = new McSlaveMemory();
memory.DataRegisters[100] = 1234;
memory.InternalRelays[10] = true;

await using var app = ZeusHost.Create(builder =>
{
builder.AddVirtualChannel("plc-link", new McSlaveResponder(memory));
builder.AddMitsubishiMc("plc", "plc-link");
});

Run sample: samples/Zeus.Samples.Console.Mc.

JSON Configuration

{
"channels": [
{ "name": "plc-link", "type": "tcp", "host": "192.168.1.10", "port": 5000 }
],
"devices": [
{
"name": "plc",
"channel": "plc-link",
"type": "mitsubishi-mc",
"frameType": "4e",
"encoding": "ascii",
"points": [
{ "name": "temperature", "deviceCode": "D", "address": 100, "scale": 0.1, "writable": true },
{ "name": "run", "deviceCode": "M", "address": 10, "writable": true },
{ "name": "ready", "deviceCode": "X", "address": "0x10" },
{ "name": "recipe", "deviceCode": "ZR", "address": 0 }
]
}
]
}

Virtual MC PLC channel:

{ "name": "plc-link", "type": "virtual", "responder": "mc" }

Scope

CapabilityStatus
3E / 4E Binary and ASCIISupported
1E Binary and ASCIICommon batch read/write supported
D, M, X, Y, W, R, ZR accessSupported, with ZR on 3E/4E
Random read/writeSupported on 3E/4E
JSON points, acquisition, write-backSupported
Virtual PLCSupported

Next: Modbus or Custom Framing.