本节在学习codesys怎样通过共享内存的方式进行与C#程序做通信
共享内存,多个进程可以对内存中的一块区域进行读写操作,达到数据交互的目的。
在共享内存使用时,需要将这个安装包SharedMemoryCommunication安装到codesys下,包文件需要的话私信联系我即可
在安装完成codesys的SharedMemoryCommunication后,就开始我们今天的学习吧
1.新建工程,然后在库管理器中添加,在高级这个选项卡。
2.在搜索框中搜索SysShm和SysTypes2 Interfaces这两个库文件
这样就添加完库了,库中具体函数的名称,在库中可以查看,也可以在百度中看到其他博主的介绍,我这就略过了哈
3.新建一个DUT,类型选择为结构,也就是说,在进行通信时,数据类型为建立的这几种类型,同样,也可以读数据的建立一个DUT,写数据的建立一个DUT,这样在共享内存时更加方便。本次实验采用了第一种方式。
TYPE DataExchange :
STRUCT
diValue1 : DINT;
diValue2 : DINT;
bValue3 :BOOL;
END_STRUCT
END_TYPE
4.PLC程序的建立
声明变量
// This program shows how to read and write to Shared Memory.
PROGRAM PLC_PRG
VAR
tt: Ton;
hShMemRead: RTS_IEC_HANDLE;
ResultRead: RTS_IEC_RESULT;
deInstRead : DataExchange;
ReadResult: RTS_IEC_RESULT;
iRead: __UXINT;
hShMemWrite: RTS_IEC_HANDLE;
ResultWrite: RTS_IEC_RESULT;
deInstWrite : DataExchange;
WriteResult: RTS_IEC_RESULT;
iWrite: __UXINT;
ulSize: UDINT := SIZEOF(DataExchange);
END_VAR
在这要注意的是,共享内存的名称一定要和C#中的统一,否则就存在通信失败的情况
tt(IN := TRUE,PT:=T#2000MS);
IF tt.Q THEN
// Read structure from Shared Memory.
hShMemRead := SysSharedMemoryCreate('Test_Read', 0, ADR(ulSize), ADR(ResultRead));
iRead := SysSharedMemoryRead(hShMemRead, 0, ADR(deInstRead), SIZEOF(deInstRead), ADR(ReadResult));
iRead := SysSharedMemoryClose(hShm := hShMemRead);
// Write structure to Shared Memory.
hShMemWrite := SysSharedMemoryCreate('Test_Write', 0, ADR(ulSize), ADR(ResultWrite));
deInstWrite.diValue1 := deInstWrite.diValue1 + 2;
deInstWrite.diValue2 := deInstWrite.diValue2 - 3;
deInstWrite.bValue3 := TRUE;
iWrite := SysSharedMemoryWrite(hShMemWrite, 0, ADR(deInstWrite), SIZEOF(deInstWrite), ADR(WriteResult));
iWrite := SysSharedMemoryClose(hShm := hShMemWrite);
tt(IN:=FALSE);
tt(IN:=TRUE);
END_IF
5.为了更好的体验共享内存的效果,我们在建立可视化Visualization,这个就根据大家的喜好,建立个视图就好了。
现在我们打开VS,建立C#工程,
代码就直接拿出来了
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Threading;
namespace SharedMemoryWin
{
// Example structure for data exchange
internal struct DataExchange
{
internal Int32 i1;
internal Int32 i2;
internal bool b1;
}
class Program
{
static void Main(string[] args)
{
DataExchange dataExchangeRead, dataExchangeWrite;
dataExchangeWrite.i1 = 0;
dataExchangeWrite.i2 = 0;
dataExchangeWrite.b1 = true;
Console.Out.WriteLine("Press 'q' to quit");
int dataSIze = Marshal.SizeOf(typeof(DataExchange));
// Open a mapped file with read access and one with write access.
using (var mmfRead = MemoryMappedFile.CreateOrOpen("Test_Write", dataSIze))
using (var mmfWrite = MemoryMappedFile.CreateOrOpen("Test_Read", dataSIze))
{
bool quit = false;
while (!quit)
{
using (var accessorRead = mmfRead.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Read))
using (var accessorWrite = mmfWrite.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Write))
{
// Read the structure
accessorRead.Read(0, out dataExchangeRead);
// Write the structure
accessorWrite.Write(0, ref dataExchangeWrite);
// Display the values
Console.Out.Write("Read i1: {0} i2: {1} b1 {2} Write i1: {3} i2: {4} b1 {5}\r",
dataExchangeRead.i1,
dataExchangeRead.i2,
dataExchangeRead.b1,
dataExchangeWrite.i1,
dataExchangeWrite.i2,
dataExchangeWrite.b1);
// Wait a second
Thread.Sleep(1000);
// Increment sample values
dataExchangeWrite.i1++;
dataExchangeWrite.i2--;
dataExchangeWrite.b1 = true;
// Check quit condition
if (Console.KeyAvailable)
if (Console.ReadKey().KeyChar == 'q')
quit = true;
}
}
}
}
}
}
需要注意的是,在C#中和CODESYS中的数据类型和共享内存的名字一定要相匹配
有问题咱们一起沟通学习啊