Felix Weiß 9bcffad77b Fix some of the old tests
- add new examples
- fix struct builder
- complete array interfaces
2023-07-20 23:28:58 +02:00
2023-07-20 23:28:58 +02:00
2023-07-20 23:28:58 +02:00
2023-07-20 23:28:58 +02:00
2023-07-20 23:28:58 +02:00
2023-06-28 18:59:28 +02:00
2022-06-20 15:50:09 +02:00
2023-06-23 15:40:34 +02:00
2022-06-20 15:53:35 +02:00
2023-07-20 23:28:58 +02:00
2023-07-07 00:23:22 +02:00

Publish pipeline Test pipeline GitHub tag gencov GitHub Status

MewtocolNet

An easy to use Mewtocol protocol library to interface with Panasonic PLCs over TCP/Serial.

Disclaimer

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).

Features

Features that are not checked still need implementation

  • Read out stats from your PLC
  • Read and write registers in real time
  • Dynamic register type casting from properties
  • Change run / prog modes
  • Write / read byte blocks in a whole chain
  • Upload / Download programs to the PLC
  • Reading / writing PLC system registers

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

PLC Support

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

For a Support List check this table

Where is the RS232/Serial support?

Support for the serial protocol will be added soon, feel free to contribute

Installing

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

Usage

See More examples here

Connecting to a PLC

Connecting to a PLC is as simple as

 //attaching a logger
Logger.LogLevel = LogLevel.Verbose;
Logger.OnNewLogMessage((date, msg) => {
    Console.WriteLine($"{date.ToString("HH:mm:ss")} {msg}");
});

//setting up a new PLC interface
MewtocolInterface plc = new MewtocolInterface("192.168.115.5");

await plc.ConnectAsync();

Reading data registers / contacts

Detailed instructions

  • Create a new class that inherits from RegisterCollectionBase
public class TestRegisters : RegisterCollectionBase {

    //corresponds to a R100 boolean register in the PLC
    [Register(100, RegisterType.R)]
    public bool TestBool1 { get; private set; }

    //corresponds to a XD input of the PLC
    [Register(RegisterType.X, SpecialAddress.D)]
    public bool TestBoolInputXD { get; private set; } 

    //corresponds to a DT7012 - DT7013 as a 32bit time value that gets parsed as a timespan (TIME)
    //the smallest value to communicate to the PLC is 10ms
    [Register(7012)]
    public TimeSpan TestTime { get; private set; }  
    
    //corresponds to a DT1101 - DT1104 string register in the PLC with (STRING[4])
    [Register(1101, 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
//setting up a new PLC interface and register collection
MewtocolInterface plc = new MewtocolInterface("192.168.115.5");
TestRegisters registers = new TestRegisters();

//attaching the register collection and an automatic poller
plc.WithRegisterCollection(registers).WithPoller();

await plc.ConnectAsync(
    (plcinf) => {
        //reading a value from the register collection
        Console.WriteLine($"Time Value is: {registers.TestTime}");
    }
);
  • Your properties are getting automatically updated after the initial connection

Note! this is not your only option to read registers, see here

Writing data registers / contacts

Registers are stored in an underlying layer for automatic handling, each register has a unique name and address.

Classes that derive from RegisterCollectionBase reference these registers automatically using attributes. All the heavy lifting is done automatically for you, setting this up is described here

Asynchronous

This operations awaits a task to make sure the register was actually set to your desired value before progressing

//sets the register to false
await plc.SetRegisterAsync(nameof(registers.TestBool1), false);

//set the current second to the PLCs TIME register
await plc.SetRegisterAsync(nameof(registers.TestTime), TimeSpan.FromSeconds(DateTime.Now.Second));

Synchronous

Sets the register without feedback if it was set

You can use the method to set a register

//inverts the boolean register
plc.SetRegister(nameof(registers.TestBool1), !registers.TestBool1);

//set the current second to the PLCs TIME register
plc.SetRegister(nameof(registers.TestTime), TimeSpan.FromSeconds(DateTime.Now.Second));

 //writes 'Test' to the PLCs string register
plc.SetRegister(nameof(registers.TestString1), "Test");

or write to a register in your RegisterCollectionBase directly (you need to attach a register collection to your interface beforehand)

//inverts the boolean register
registers.TestBool1 = true;

You can also set a register by calling its name directly (Must be either in an attached register collection or added to the list manually)

Adding registers to a manual list

plc.AddRegister<bool>(105, _name: "ManualBoolRegister");

Reading the value of the manually added register

//get the value as a string
string value = plc.GetRegister("ManualBoolRegister").GetValueString();
//get the value by casting
bool value2 = plc.GetRegister<BRegister>("ManualBoolRegister").Value;
//for double casted ones like numbers
var value2 = plc.GetRegister<NRegister<short>>("NumberRegister").Value;
Languages
C# 100%