Delta PLC provides Modbus communication library DMT, which can be used in C# ​​to communicate with Delta PLC over RS485 (Modbus).

First of all to use DMT with your application following functions should be imported from kernel32.dll and DMT.dll:

using System.Reflection;

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
static extern IntPtr LoadLibrary(string dllPath);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool FreeLibrary(IntPtr hDll);

// Serial Communication
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
static extern int OpenModbusSerial(int conn_num, int baud_rate, int data_len, char parity, int stop_bits, int modbus_mode);
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
static extern void CloseSerial(int conn_num);
        
// MODBUS Address Calculation
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
static extern int DevToAddrW(string series, string device, int qty);

// Wrapped MODBUS Funcion : 0x02
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
static extern int ReadInputsW(int comm_type, int conn_num, int slave_addr, int dev_addr, int qty, UInt32[] data_r, StringBuilder req, StringBuilder res);
        
// Wrapped MODBUS Funcion : 0x05		   
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
static extern int WriteSingleCoilW(int comm_type, int conn_num, int slave_addr, int dev_addr, UInt32 data_w, StringBuilder req, StringBuilder res);

To load DMT.dll call “LoadLibrary” from kernel32.dll at the beginning and do not forget to call “FreeLibrary” from kernel32.dll at the end:

System.IntPtr hDMTDll = LoadLibrary(AppDomain.CurrentDomain.BaseDirectory + "DMT.dll"); // explicitly link to DMT.dll

We need also a delegate to disconnect from serial:

int conn_num = 1; //COM Port (COM1)
delegate void DelegateClose(int conn_num); // function pointer for disconnection
DelegateClose CloseModbus = new DelegateClose(CloseSerial);
CloseModbus = CloseSerial;

Then we should open serial connection to start communication:

int modbus_mode = 1; // 1:ASCII , 2:RTU
int baud_rate = 9600; 
int data_len = 7;
char parity = 'E'; // Even
int stop_bits = 1; 
int plc_node = 1; //Modbus node number

int status = OpenModbusSerial(conn_num, baud_rate, data_len, parity, stop_bits, modbus_mode);

If variable “status” is bigger than zero, it means we are successfully connected. Example code to write zero (false) to internal relay M21:

StringBuilder req = new StringBuilder(1024);
StringBuilder res = new StringBuilder(1024);
		
if (status > 0)
{

            int addr = DevToAddrW("DVP", "M21", 1); //Get int address of internal relay M21 
            int sonuc = WriteSingleCoilW(0, conn_num, plc_node, addr, 0, req, res);
            if (sonuc == -1)
            {
                MessageBox.Show("Error");
            }
			else
            {
                MessageBox.Show("Success");
            }

}

Example code to read internal relay M23:

UInt32[] data_from_dev = new UInt32[1];
data_from_dev[0] = 0;
UInt32[] data_to_dev = new UInt32[1];
data_to_dev[0] = 0;
		
int addr = DevToAddrW("DVP", "M23", 1);
int sonuc = ReadInputsW(0, conn_num, plc_node, addr, 1, data_from_dev, req, res);
if (sonuc != -1)
{
			MessageBox.Show("Read Success");
            if (data_from_dev[0] == 1)
            {
				MessageBox.Show("M23 is true");
			}
}

To close serial communication:

CloseModbus(conn_num);

With this code example abov you can manage your PLC software from your PC. To use it while entire machine is running put your code in a Thread.