共享内存 - C#与CoDeSys通讯-CODESYS资源下载区-酷德网 - CoDeSys软件教程下载,CoDeSys工控资讯门户 

酷德网

HSC6490-cn中国制造,中国芯~
查看: 6282|回复: 4

共享内存 - C#与CoDeSys通讯

  [复制链接]
  • TA的每日心情
    擦汗
    2019-8-13 14:13
  • 签到天数: 32 天

    [LV.5]常住居民I

    发表于 2020-6-17 12:12:18 | 显示全部楼层 |阅读模式
    测试环境:
    1、CODESYS 3.5.13.0(新建Codesys_ShareMemory项目)
    2、SharedMemoryCommunication.package(Codesysy共享内存库)

    SharedMemoryCommunication.package (23.03 MB, 下载次数: 114)

    3、Visual Studio2015(新建C#_ShareMemory项目)
    一、共享内存概念
    1、顾名思义,共享内存就是建立一块供协作进程共享的内存区域,多个进程可以透过此共享区域读取或者写入数据来交换信息;
    2、通信示意图:
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    二、CoDeSys程序
    1、添加库文件
    · SysShm,3.5.8.0 (System)
    · SysTypes2 Interfaces,3.5.4.0 (System)
    1)打开库管理器(Library Manager),选择“添加库(Add Library)”,点“高级(Advanced...)”;
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    2)在搜索框(String for a fulltext search...)中分别输入SysShm和SysTypes搜索添加SysShm,3.5.8.0 和SysTypes2 Interfaces,3.5.4.0 ,
    选中搜索到的库,点“OK”确认添加,
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    添加完成即可在库管理器(Library Manager)中查看到。
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    库文件介绍:
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    2、创建数据结构
    共享内存进行数据共享交互需要通过数据结构来进行。
    选中应用(Application)右键添加对象(Add Object),选择“DUT”,
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    创建数据结构,输入数据结构名称,选择类型(Type),点“Add”
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    本例分别创建两个数据结构,Str_ParaFromHMI和Str_ParaToHMI
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    3、创建ShareMemory
    新建ST(结构文本)程序,创建共享内存。
    程序页面概览:
    1)声明变量、共享内存名和功能函数等


    • [C] 纯文本查看 复制代码
      PROGRAM ShareMemory
      VAR
              
              bStart: BOOL:= FALSE;
              ReadHandle: RTS_IEC_HANDLE:= RTS_INVALID_HANDLE;
              WriteHandle: RTS_IEC_HANDLE:= RTS_INVALID_HANDLE;
              szNameRead: STRING:= 'CODESYS_MEMORY_READ';                //声明共享内存的读取内存名称
              szNameWrite: STRING:= 'CODESYS_MEMORY_WRITE';        //声明共享内存的写入内存名称
              ulPhysicalAddressRead: __UXINT:= 0;
              ulPhysicalAddressWrite: __UXINT:= 0;
              ulSizeRead: __UXINT:= 1024;
              ulSizeWrite: __UXINT:= 1024;
              ResultRead: ARRAY[0..2] OF RTS_IEC_RESULT;                //返回运行错误码
              ResultWrite: ARRAY[0..2] OF RTS_IEC_RESULT;
              
              SMRead: __UXINT;
              SMWrite: __UXINT;
              ulOffsetRead: __UXINT:= 0;
              ulOffsetWrite: __UXINT:= 0;
              
      END_VAR




    2)程序具体实现


    • [C] 纯文本查看 复制代码
      //Init Memory
      IF NOT bStart THEN
              ReadHandle:= SysSharedMemoryCreate(pszName:= szNameRead, ulPhysicalAddress:= ulPhysicalAddressRead, pulSize:= ADR(ulSizeRead), pResult:= ADR(ResultRead[0]));
              WriteHandle:= SysSharedMemoryCreate(pszName:= szNameWrite, ulPhysicalAddress:= ulPhysicalAddressWrite, pulSize:= ADR(ulSizeWrite), pResult:= ADR(ResultWrite[0]));
              IF RTS_INVALID_HANDLE <> ReadHandle AND RTS_INVALID_HANDLE <> WriteHandle THEN
                      bStart:= TRUE;
              END_IF
      END_IF
       
      //读取数据
      IF RTS_INVALID_HANDLE <> ReadHandle THEN
              SMRead:= SysSharedMemoryRead(
              hShm:= ReadHandle,                                         //读取内存的设备句柄
              ulOffset:= ulOffsetRead,                        //读取数据的偏移地址 
              pbyData:= ADR(GVL.GetPara),                 //指向读取数据的缓冲区
              ulSize:= SIZEOF(Str_ParaFromHMI),         //读取数据的字节大小        
              pResult:= ADR(ResultRead[1]));                //返回执行的错误码
      END_IF
       
      //写入数据
      IF RTS_INVALID_HANDLE <> WriteHandle THEN
              SMWrite:= SysSharedMemoryWrite(
              hShm:= WriteHandle,                                 //写入内存的设备句柄
              ulOffset:= ulOffsetWrite,                         //写入数据的偏移地址
              pbyData:= ADR(GVL.SetPara),                 //指向写入数据的缓冲区
              ulSize:= SIZEOF(Str_ParaToHMI),         //写入数据的字节大小
              pResult:= ADR(ResultWrite[2]));                //返回执行的错误码
      END_IF





    三、C#程序
    1、引用命名空间
    • [C] 纯文本查看 复制代码
      using System.IO.MemoryMappedFiles;      //引用共享内存命名空间
      using System.Threading;                 
      using System.Runtime.InteropServices;





    2、定义数据结构
    数据结构中的变量名不一定非要与Codesys的数据结构变量名保持相同(建议定义一致,便于查看和管理),但数据结构内的数据类型和数据总数必须保持一致。

    • [C] 纯文本查看 复制代码
          struct StrFromCodesys
          {
              internal bool bOut;
              internal int iOut;
              internal double fOut;
          }
          struct StrToCodesys
          {
              internal bool bIn;
              internal int iIn;
              internal double fIn;
          }
      




    3、创建ShareMemory
    1)声明定义共享内存使用的API
    20200520165726312.png
    2)共享内存初始化,注意检查MappedFile的内存名与Codesys内存名一致,这样才能确保访问同一块内存地址
    • [C] 纯文本查看 复制代码
       private void InitMemory()
              {
                  try
                  {
                      MMF_Write = MemoryMappedFile.CreateOrOpen("CODESYS_MEMORY_READ", 1024);        //打开Codesys_Read内存区域,意思就是说Codesys的读取区域是C#的写入区域
                      AccessorWrite = MMF_Write.CreateViewAccessor(0, Marshal.SizeOf(typeof(StrToCodesys)), MemoryMappedFileAccess.Write);
       
                      MMF_Read = MemoryMappedFile.CreateOrOpen("CODESYS_MEMORY_WRITE", 1024);        //打开Codesys_Write内存区域,意思就是说Codesys的写入区域是C#的读取区域
                      AccessorRead = MMF_Read.CreateViewAccessor(0, Marshal.SizeOf(typeof(StrFromCodesys)), MemoryMappedFileAccess.Read);
       
                  }
                  catch(Exception ex)
                  {
                      MessageBox.Show(ex.Message);
                  }
              }



    3)读取数据
    • [C] 纯文本查看 复制代码
              private void ReadData()
              {
                  while(true)
                  {
                      try
                      {
                          Thread.Sleep(5);
                          AccessorRead.Read(0, out ParaFromCodesys);      //读取Codesys的数据
                          Thread.Sleep(5);
                          if(ParaFromCodesys.bOut == true)
                              picbox_bRead.BackColor = Color.Red;
                          else
                              picbox_bRead.BackColor = Color.Gray;
       
                          textbox_iRead.Text = ParaFromCodesys.iOut.ToString("0");
                          textbox_fRead.Text = ParaFromCodesys.fOut.ToString("0.000");
       
                      }
                      catch(Exception ex)
                      {
                          MessageBox.Show(ex.Message);
                      }
                  }
              }




    4)写入数据




    • [C] 纯文本查看 复制代码
              private void btnWriteB(object sender, EventArgs e)
              {
                  ParaToCodesys.bIn = !ParaToCodesys.bIn;
                  AccessorWrite.Write(0, ref ParaToCodesys);
                  if(ParaToCodesys.bIn == true)
                  {
                      picbox_bWrite.BackColor = Color.Red;
                  }
                  else
                  {
                      picbox_bWrite.BackColor = Color.Gray;
                  }
              }
      



    四、通信测试
    运行CoDeSys和C#程序,通过读取和写入数据测试通信结果
    1)通信测试图片
    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3ODQ2NjE3,size_16,color_FFFFFF,t_70.jpg
    2)通信测试动图
    2020052017404935.gif

    +11
    不赞一个?

    最近谁赞过

    打赏鼓励一下!
    回复

    使用道具 举报

    该用户从未签到

    发表于 2021-6-24 13:37:49 | 显示全部楼层
    请问网盘链接失效了,可以再分享一下吗
    +10
    不赞一个?
    打赏鼓励一下!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2022-4-7 23:52:46 | 显示全部楼层

    请问网盘链接失效了,可以再分享一下吗
    +10
    不赞一个?
    打赏鼓励一下!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2022-11-10 01:21:46 | 显示全部楼层
    我只想问,这个必须要求codesys运行在c#所在的主机上吗?如果是网线连接的plc可不可以
    +10
    不赞一个?
    打赏鼓励一下!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2024-7-23 14:14:51 | 显示全部楼层
    请问下汇川AC系列或者松下AM1系列的CODESYS平台PLC都能这样用吗
    +10
    不赞一个?
    打赏鼓励一下!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

    本版积分规则

    
    顶部qrcode底部
    关注酷德网订阅号,获取更多资讯!

    QQ|Archiver|手机版|小黑屋|酷德论坛 ( 苏ICP备16065247号-1 )|网站地图

    GMT+8, 2026-10-9 10:30 , Processed in 0.168077 second(s), 73 queries .

    酷德网

    © 2001-2013 Hicodesys. 技术支持 by 酷德网

    快速回复 返回顶部 返回列表