- fix logger always printing to console if disabled - add register adding at connected time and clearing
MewtocolNet
An easy to use Mewtocol protocol library to interface with Panasonic PLCs over TCP/Serial.
⚠️ This library is not an official panasonic product nor does panasonic provide financial support or limitations in any form. This software was written by WOLF Medizintechnik GmbH (@WOmed/dev).
PLC Support
For a full list check this table
This library was only tested with a few PLCs, other types that support the Panasonic Mewtocol protocol might work. Use at your own risk, others might follow with community feedback
Features
Fully implemented
- TCP/IP and Serial Port support
- Get type and hardware information of PLCs
- Get PLC program metadata such as program version and IDs
- Read and write registers in real time
- Basic data types / structures support
- Fast readback cycles due to a MemoryManager that optimizes TCP / Serial frames by combining areas
- Fully customizable heartbeats and polling levels (tell the interface when you need register updates)
- Easy to use builder patterns for interface and register generation
- Register type casting from property attributes
- Change RUN / PROG modes
- Delete Programs
- Write / read low level byte blocks to areas
- Scanning for network devices and change network settings (WDConfigurator features)
Planned
- Upload / Download programs to the PLC
- Reading / writing PLC system registers
- Advanced data structures like SDTs and SDT Arrays
- Custom open source program compiler for PLC cpus
Support
.NET Support
This library was written in netstandard2.0 and should be compatible with a lot of .NET environments.
For a full list of supported .NET clrs see this page
Installation
Use the dotnet CLI and run
dotnet add package Mewtocol.NET
Protocol description
Panasonic has published a protocol definition on their site. Refer to this site if you want to see the general functionality or add / report missing features.
This library is at the time not feature complete, but all essential features are provided
Examples
To see a full list of examples click here.
Connecting to a PLC
Connecting to a PLC is as simple as
using MewtocolNet;
using (var plc = Mewtocol.Ethernet("192.168.178.55").Build()) {
await plc.ConnectAsync();
if (!plc.IsConnected) {
Console.WriteLine("Failed to connect to the plc...");
} else {
Console.WriteLine(plc.PlcInfo);
}
}
Reading data registers / contacts
- Create a new class that inherits from
RegisterCollection
using MewtocolNet;
using MewtocolNet.RegisterAttributes;
public class TestRegisters : RegisterCollection {
//corresponds to a R100 boolean register in the PLC
[Register("R100")]
public bool TestBool1 { get; private set; }
//corresponds to a XD input of the PLC
[Register("XD")]
public bool TestBoolInputXD { get; private set; }
//corresponds to a DDT7012 - DDT7013 as a 32bit time value that gets parsed as a timespan (TIME)
//the smallest value to communicate to the PLC is 10ms
[Register("DDT7012")]
public TimeSpan TestTime { get; private set; }
//corresponds to a DT1101 - DT1104 string register in the PLC with (STRING[4])
[Register("DT1101", "STRING[4]")]
public string TestString1 { get; private set; }
}
- Connect to the PLC and attach the register collection and logger
- attach an automatic poller by chaining
.WithPoller()after the register attachment
TestRegisters registers = null;
//setting up a new PLC serial interface and tell it to use the register collection
var plc = Mewtocol.Serial("COM4", BaudRate._19200)
.WithPoller()
.WithRegisterCollections(c => {
registers = c.AddCollection<TestRegisters>();
// or use
// c.AddCollection(new TestRegisters());
// if you want to pass data to a constructor
})
.Build();
//connect to it
await plc.ConnectAsync(async () => {
//restart the plc program during the connection process
await plc.RestartProgramAsync();
});
//wait for the first data cycle of the poller module
//otherwise the property value might still be unset or null
await App.ViewModel.Plc.AwaitFirstDataCycleAsync();
if (App.ViewModel.Plc.IsConnected) {
Console.WriteLine(registers.TestBool1);
}
- Your properties are getting automatically updated after the initial connection
Note! this is not your only option to read registers, see here
Reading & Writing
In addition to the automatic property binding you can use these patterns:
Reading & Writing by using the anonymous builder pattern
await plc.Register.Struct<short>("DT100").WriteAsync(100);
var value = await plc.Register.Struct<short>("DT100").ReadAsync();
Reading & Writing by using the direct reference from the builder pattern
IRegister<bool> outputContactReference;
var plc = Mewtocol.Ethernet("127.0.0.1")
.WithRegisters(b => {
b.Bool("Y4").Build(out outputContactReference);
})
.Build();
await plc.ConnectAsync();
await outputContactReference.WriteAsync(true);