├── .gitattributes ├── .gitignore ├── README.md └── 简单三菱组态实现按照三菱协议使用Socket通信 ├── WindowsFormsApplication4.sln ├── WindowsFormsApplication4.suo └── WindowsFormsApplication4 ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── WindowsFormsApplication4.csproj ├── bin └── Debug │ ├── WindowsFormsApplication4.exe │ ├── WindowsFormsApplication4.pdb │ ├── WindowsFormsApplication4.vshost.exe │ ├── WindowsFormsApplication4.vshost.exe.manifest │ ├── config.txt │ └── iterms.txt ├── mcp.cs └── obj └── x86 └── Debug ├── DesignTimeResolveAssemblyReferences.cache ├── DesignTimeResolveAssemblyReferencesInput.cache ├── WindowsFormsApplication4.Form1.resources ├── WindowsFormsApplication4.Properties.Resources.resources ├── WindowsFormsApplication4.csproj.FileListAbsolute.txt ├── WindowsFormsApplication4.csproj.GenerateResource.Cache ├── WindowsFormsApplication4.csprojResolveAssemblyReference.cache ├── WindowsFormsApplication4.exe └── WindowsFormsApplication4.pdb /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MCSo 2 | ==== 3 | 简单三菱组态实现按照三菱协议使用Socket通信 4 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApplication4", "WindowsFormsApplication4\WindowsFormsApplication4.csproj", "{ECFCD793-7A99-403F-9C09-9565E5608A7A}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {ECFCD793-7A99-403F-9C09-9565E5608A7A}.Debug|x86.ActiveCfg = Debug|x86 13 | {ECFCD793-7A99-403F-9C09-9565E5608A7A}.Debug|x86.Build.0 = Debug|x86 14 | {ECFCD793-7A99-403F-9C09-9565E5608A7A}.Release|x86.ActiveCfg = Release|x86 15 | {ECFCD793-7A99-403F-9C09-9565E5608A7A}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4.suo -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace WindowsFormsApplication4 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); 33 | this.button1 = new System.Windows.Forms.Button(); 34 | this.timer1 = new System.Windows.Forms.Timer(this.components); 35 | this.button2 = new System.Windows.Forms.Button(); 36 | this.SuspendLayout(); 37 | // 38 | // flowLayoutPanel1 39 | // 40 | this.flowLayoutPanel1.AutoScroll = true; 41 | this.flowLayoutPanel1.Location = new System.Drawing.Point(12, 68); 42 | this.flowLayoutPanel1.Name = "flowLayoutPanel1"; 43 | this.flowLayoutPanel1.Size = new System.Drawing.Size(800, 400); 44 | this.flowLayoutPanel1.TabIndex = 0; 45 | // 46 | // button1 47 | // 48 | this.button1.Location = new System.Drawing.Point(737, 28); 49 | this.button1.Name = "button1"; 50 | this.button1.Size = new System.Drawing.Size(75, 23); 51 | this.button1.TabIndex = 1; 52 | this.button1.Text = "import"; 53 | this.button1.UseVisualStyleBackColor = true; 54 | this.button1.Click += new System.EventHandler(this.button1_Click); 55 | // 56 | // timer1 57 | // 58 | this.timer1.Interval = 1000; 59 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 60 | // 61 | // button2 62 | // 63 | this.button2.Enabled = false; 64 | this.button2.Location = new System.Drawing.Point(592, 30); 65 | this.button2.Name = "button2"; 66 | this.button2.Size = new System.Drawing.Size(92, 21); 67 | this.button2.TabIndex = 2; 68 | this.button2.Text = "开始监视"; 69 | this.button2.UseVisualStyleBackColor = true; 70 | this.button2.Click += new System.EventHandler(this.button2_Click); 71 | // 72 | // Form1 73 | // 74 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 75 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 76 | this.ClientSize = new System.Drawing.Size(835, 487); 77 | this.Controls.Add(this.button2); 78 | this.Controls.Add(this.button1); 79 | this.Controls.Add(this.flowLayoutPanel1); 80 | this.Name = "Form1"; 81 | this.Text = "Form1"; 82 | this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed); 83 | this.Load += new System.EventHandler(this.Form1_Load); 84 | this.ResumeLayout(false); 85 | 86 | } 87 | 88 | #endregion 89 | 90 | private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; 91 | private System.Windows.Forms.Button button1; 92 | private System.Windows.Forms.Timer timer1; 93 | private System.Windows.Forms.Button button2; 94 | 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | using System.IO; 10 | using System.Collections; 11 | using System.Threading; 12 | using MCP; 13 | 14 | namespace WindowsFormsApplication4 15 | { 16 | 17 | 18 | 19 | public partial class Form1 : Form 20 | { 21 | public int count=0; 22 | Hashtable hshTable = new Hashtable(); 23 | Plc qplc; 24 | 25 | public Form1() 26 | { 27 | InitializeComponent(); 28 | } 29 | 30 | private void button1_Click(object sender, EventArgs e) 31 | { 32 | 33 | if (!File.Exists("iterms.txt")) 34 | { 35 | MessageBox.Show("不存在要被监视的软元件列表文件items.txt"); 36 | return; 37 | } 38 | StreamReader sr_iterms = new StreamReader("iterms.txt"); 39 | string iterm_line; 40 | while((iterm_line=sr_iterms.ReadLine())!=null) 41 | { 42 | if (iterm_line.Length <= 0) continue; 43 | //MessageBox.Show(iterm_line+"::"+iterm_line.Length.ToString()); 44 | count++; 45 | Panel p = new Panel(); 46 | p.Size = new Size(80, 40); 47 | p.BorderStyle = BorderStyle.FixedSingle; 48 | Label lb = new Label(); 49 | lb.Text = count.ToString()+": " + iterm_line; 50 | p.Controls.Add(lb); 51 | 52 | Label lb_value = new Label(); 53 | lb_value.Text = "null"; 54 | lb_value.Location = new Point(lb.Location.X,lb.Location.Y+25); 55 | p.Controls.Add(lb_value); 56 | info i=new info(); 57 | i.lb = lb_value; 58 | i.temp_value = lb_value.Text; 59 | hshTable.Add(iterm_line, i); 60 | //MessageBox.Show(((info)hshTable[iterm_line]).lb.Text); 61 | flowLayoutPanel1.Controls.Add(p); 62 | 63 | } 64 | sr_iterms.Close(); 65 | button2.Enabled = true; 66 | 67 | } 68 | 69 | private void timer1_Tick(object sender, EventArgs e) 70 | { 71 | //把hshTable中的temp_value赋给其lb的text,用以刷新 72 | //foreach (DictionaryEntry de in hshTable) 73 | IDictionaryEnumerator de = hshTable.GetEnumerator(); 74 | while (de.MoveNext()) 75 | { 76 | //MessageBox.Show(de.Key.ToString()); 77 | //MessageBox.Show(((info)de.Value).temp_value); 78 | 79 | ((info)de.Value).lb.Text = ((info)de.Value).temp_value; //+ new Random().Next(0, 10).ToString() 80 | //这里可以添加<<规则>> 81 | 82 | } 83 | } 84 | 85 | 86 | Thread monitor_Thread = null; 87 | string plc_ip, plc_port, plc_staionnumber; 88 | 89 | public void monitor() 90 | { 91 | qplc = new McProtocolTcp(plc_ip, int.Parse(plc_port), McFrame.MC3E, (uint)int.Parse(plc_staionnumber)); 92 | //qplc = new McProtocolTcp("192.168.0.2", int.Parse("2000"), McFrame.MC3E, (uint)int.Parse("8")); 93 | try { qplc.Open(); } 94 | catch(Exception e) 95 | { 96 | MessageBox.Show(e.Message); 97 | return; 98 | } 99 | 100 | while (true) 101 | { 102 | //foreach (DictionaryEntry de in hshTable) 103 | IDictionaryEnumerator de = hshTable.GetEnumerator(); 104 | while (de.MoveNext()) 105 | { 106 | //if markup abortflag then qplc.close,thread.abort 107 | PlcDeviceType type; 108 | int addr; 109 | McProtocolApp.GetDeviceCode(de.Key.ToString(), out type, out addr); 110 | 111 | var val = new int[1]; 112 | //int rtCode = McProtocolApp.IsBitDevice(type) ? qplc.GetBitDevice(de.Key.ToString(), val.Length, val) : 113 | // qplc.ReadDeviceBlock(de.Key.ToString(), val.Length, val); 114 | try 115 | { 116 | int rtCode = McProtocolApp.IsBitDevice(type) ? qplc.GetBitDevice(de.Key.ToString(), val.Length, val) : 117 | qplc.ReadDeviceBlock(de.Key.ToString(), val.Length, val); 118 | } 119 | catch (Exception e) 120 | { 121 | MessageBox.Show(e.Message); 122 | return; 123 | } 124 | ((info)de.Value).temp_value=val[0].ToString(); 125 | } 126 | Thread.Sleep(20); 127 | } 128 | qplc.Close(); 129 | } 130 | 131 | 132 | private void button2_Click(object sender, EventArgs e) 133 | { 134 | if (!File.Exists("config.txt")) 135 | { 136 | MessageBox.Show("不存在用于设置plc网络信息的文件config.txt"); 137 | return; 138 | } 139 | StreamReader sr_config = new StreamReader("config.txt"); 140 | 141 | plc_ip = sr_config.ReadLine(); 142 | plc_port = sr_config.ReadLine(); 143 | plc_staionnumber = sr_config.ReadLine(); 144 | 145 | /*config.txt内容: 146 | * 192.168.0.2 147 | * 2000 148 | * 8 149 | * 150 | */ 151 | sr_config.Close(); 152 | 153 | button2.Enabled = false; 154 | monitor_Thread = new Thread(new ThreadStart(this.monitor)); 155 | monitor_Thread.Start(); 156 | timer1.Start(); 157 | } 158 | 159 | private void Form1_Load(object sender, EventArgs e) 160 | { 161 | 162 | } 163 | 164 | private void Form1_FormClosed(object sender, FormClosedEventArgs e) 165 | { 166 | if (monitor_Thread!=null){ 167 | //markup abortflag 168 | monitor_Thread.Abort(); 169 | } 170 | } 171 | } 172 | 173 | class info 174 | { 175 | public Label lb; 176 | public string temp_value; 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace WindowsFormsApplication4 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// 应用程序的主入口点。 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new Form1()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("WindowsFormsApplication4")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WindowsFormsApplication4")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("73eed33d-4d42-4bb8-afa9-44006c51e615")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 内部版本号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本: 4.0.30319.18444 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WindowsFormsApplication4.Properties 12 | { 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// 返回此类使用的、缓存的 ResourceManager 实例。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApplication4.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 为所有资源查找重写当前线程的 CurrentUICulture 属性, 56 | /// 方法是使用此强类型资源类。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WindowsFormsApplication4.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/WindowsFormsApplication4.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {ECFCD793-7A99-403F-9C09-9565E5608A7A} 9 | WinExe 10 | Properties 11 | WindowsFormsApplication4 12 | WindowsFormsApplication4 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Form 51 | 52 | 53 | Form1.cs 54 | 55 | 56 | 57 | 58 | 59 | Form1.cs 60 | 61 | 62 | ResXFileCodeGenerator 63 | Resources.Designer.cs 64 | Designer 65 | 66 | 67 | True 68 | Resources.resx 69 | 70 | 71 | SettingsSingleFileGenerator 72 | Settings.Designer.cs 73 | 74 | 75 | True 76 | Settings.settings 77 | True 78 | 79 | 80 | 81 | 88 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.exe -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.pdb -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.vshost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.vshost.exe -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/WindowsFormsApplication4.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/config.txt: -------------------------------------------------------------------------------- 1 | 192.168.0.2 2 | 2000 3 | 8 4 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/bin/Debug/iterms.txt: -------------------------------------------------------------------------------- 1 | D100 2 | M30 3 | D35 4 | D99 5 | L100 6 | Z5 7 | D102 8 | D111 9 | D190 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/mcp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Net.Sockets; 5 | using System.Net; 6 | /* 7 | * 用法: 8 | * (0)把本文件加到你的工程中,对工程新建 类,mcp.cs,复制下面文本然后黏贴 9 | * (1)在要调用的程序里加入 using MCP; 10 | * (2)定义变量 Plc FApp; 11 | * (3) 指定PLC地址、端口、协议、站号: FApp = new McProtocolTcp("192.168.0.2", 2000, McFrame.MC3E,0x0008u);然后打开它:FApp.Open(); 12 | * (4) 13 | * 创建 var buffer=new int[N]; 14 | * A.读N位元件数据到buffer: FApp.GetBitDevice("M1", buffer.Length, buffer); 15 | * B.读N位元件数据到buffer: FApp.ReadDeviceBlock("D100", buffer.Length, buffer); 16 | * C.写N个buffer中的数据到N个位软元件: FApp.SetBitDevice("M1", buffer.Length, buffer) 注意这里buffer[*]的值只能为0或1 17 | * D.写N个buffer中的数据到N个字软元件: FApp.WriteDeviceBlock("D100", buffer.Length, buffer) 18 | * (5)可选:FApp.Close(),因为C-Sharp的GC机制它会自动帮你Close,故这是可选的。 19 | */ 20 | namespace MCP 21 | { 22 | // ==================================================================================== 23 | public enum McFrame 24 | { 25 | MC3E 26 | , MC4E 27 | } 28 | // ==================================================================================== 29 | // PLC软元件定义 30 | public enum PlcDeviceType 31 | { 32 | M = 0x90 33 | , 34 | SM = 0x91 35 | , 36 | L = 0x92 37 | , 38 | F = 0x93 39 | , 40 | V = 0x94 41 | , 42 | S = 0x98 43 | , 44 | X = 0x9C 45 | , 46 | Y = 0x9D 47 | , 48 | B = 0xA0 49 | , 50 | SB = 0xA1 51 | , 52 | DX = 0xA2 53 | , 54 | DY = 0xA3 55 | , 56 | D = 0xA8 57 | , 58 | SD = 0xA9 59 | , 60 | R = 0xAF 61 | , 62 | ZR = 0xB0 63 | , 64 | W = 0xB4 65 | , 66 | SW = 0xB5 67 | , 68 | TC = 0xC0 69 | , 70 | TS = 0xC1 71 | , 72 | TN = 0xC2 73 | , 74 | CC = 0xC3 75 | , 76 | CS = 0xC4 77 | , 78 | CN = 0xC5 79 | , 80 | SC = 0xC6 81 | , 82 | SS = 0xC7 83 | , 84 | SN = 0xC8 85 | , 86 | Z = 0xCC 87 | , 88 | TT 89 | , 90 | TM 91 | , 92 | CT 93 | , 94 | CM 95 | , 96 | A 97 | , Max 98 | } 99 | // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 100 | // PLC通用MC Protocol 功能接口定义 101 | public interface Plc : IDisposable 102 | { 103 | int Open(); 104 | int Close(); 105 | int SetBitDevice(string iDeviceName, int iSize, int[] iData); 106 | int SetBitDevice(PlcDeviceType iType, int iAddress, int iSize, int[] iData); 107 | int GetBitDevice(string iDeviceName, int iSize, int[] oData); 108 | int GetBitDevice(PlcDeviceType iType, int iAddress, int iSize, int[] oData); 109 | int WriteDeviceBlock(string iDeviceName, int iSize, int[] iData); 110 | int WriteDeviceBlock(PlcDeviceType iType, int iAddress, int iSize, int[] iData); 111 | int ReadDeviceBlock(string iDeviceName, int iSize, int[] oData); 112 | int ReadDeviceBlock(PlcDeviceType iType, int iAddress, int iSize, int[] oData); 113 | int SetDevice(string iDeviceName, int iData); 114 | int SetDevice(PlcDeviceType iType, int iAddress, int iData); 115 | int GetDevice(string iDeviceName, out int oData); 116 | int GetDevice(PlcDeviceType iType, int iAddress, out int oData); 117 | } 118 | // ######################################################################################## 119 | abstract public class McProtocolApp : Plc 120 | { 121 | // ==================================================================================== 122 | public McFrame CommandFrame { get; set; } // 命令帧 123 | public string HostName { get; set; } // ip地址或者主机名 124 | public int PortNumber { get; set; } // 端口号 125 | public uint appcn { get; set; } //站号 126 | // ==================================================================================== 127 | // 构造函数,用于设定通讯协议为3E,参数为目标e71的ip地址和端口号 128 | protected McProtocolApp(string iHostName, int iPortNumber, McFrame mf, uint ucn) 129 | { 130 | CommandFrame = mf; 131 | HostName = iHostName; 132 | PortNumber = iPortNumber; 133 | appcn = ucn; 134 | } 135 | // ==================================================================================== 136 | // GC时的释放 137 | public void Dispose() 138 | { 139 | Close(); 140 | } 141 | // ==================================================================================== 142 | public int Open() 143 | { 144 | DoConnect(); 145 | Command = new McCommand(CommandFrame); 146 | Command.SetChannelNumber(appcn); 147 | return 0; 148 | } 149 | // ==================================================================================== 150 | public int Close() 151 | { 152 | DoDisconnect(); 153 | return 0; 154 | } 155 | // ==================================================================================== 156 | public int SetBitDevice(string iDeviceName, int iSize, int[] iData) 157 | { 158 | PlcDeviceType type; 159 | int addr; 160 | GetDeviceCode(iDeviceName, out type, out addr); 161 | return SetBitDevice(type, addr, iSize, iData); 162 | } 163 | // ==================================================================================== 164 | public int SetBitDevice(PlcDeviceType iType, int iAddress, int iSize, int[] iData) 165 | { 166 | var type = iType; 167 | var addr = iAddress; 168 | var data = new List(6) 169 | { 170 | (byte) addr 171 | , (byte) (addr >> 8) 172 | , (byte) (addr >> 16) 173 | , (byte) type 174 | , (byte) iSize 175 | , (byte) (iSize >> 8) 176 | }; 177 | var d = (byte)iData[0]; 178 | var i = 0; 179 | while (i < iData.Length) 180 | { 181 | if (i % 2 == 0) 182 | { 183 | d = (byte)iData[i]; 184 | d <<= 4; 185 | } 186 | else 187 | { 188 | d |= (byte)(iData[i] & 0x01); 189 | data.Add(d); 190 | } 191 | ++i; 192 | } 193 | if (i % 2 != 0) 194 | { 195 | data.Add(d); 196 | } 197 | byte[] sdCommand = Command.SetCommand(0x1401, 0x0001, data.ToArray()); 198 | byte[] rtResponse = TryExecution(sdCommand); 199 | int rtCode = Command.SetResponse(rtResponse); 200 | return rtCode; 201 | } 202 | // ==================================================================================== 203 | public int GetBitDevice(string iDeviceName, int iSize, int[] oData) 204 | { 205 | PlcDeviceType type; 206 | int addr; 207 | GetDeviceCode(iDeviceName, out type, out addr); 208 | return GetBitDevice(type, addr, iSize, oData); 209 | } 210 | // ==================================================================================== 211 | public int GetBitDevice(PlcDeviceType iType, int iAddress, int iSize, int[] oData) 212 | { 213 | PlcDeviceType type = iType; 214 | int addr = iAddress; 215 | var data = new List(6) 216 | { 217 | (byte) addr 218 | , (byte) (addr >> 8) 219 | , (byte) (addr >> 16) 220 | , (byte) type 221 | , (byte) iSize 222 | , (byte) (iSize >> 8) 223 | }; 224 | byte[] sdCommand = Command.SetCommand(0x0401, 0x0001, data.ToArray()); 225 | byte[] rtResponse = TryExecution(sdCommand); 226 | int rtCode = Command.SetResponse(rtResponse); 227 | byte[] rtData = Command.Response; 228 | for (int i = 0; i < iSize; ++i) 229 | { 230 | if (i % 2 == 0) 231 | { 232 | oData[i] = (rtCode == 0) ? ((rtData[i / 2] >> 4) & 0x01) : 0; 233 | } 234 | else 235 | { 236 | oData[i] = (rtCode == 0) ? (rtData[i / 2] & 0x01) : 0; 237 | } 238 | } 239 | return rtCode; 240 | } 241 | // ==================================================================================== 242 | public int WriteDeviceBlock(string iDeviceName, int iSize, int[] iData) 243 | { 244 | PlcDeviceType type; 245 | int addr; 246 | GetDeviceCode(iDeviceName, out type, out addr); 247 | return WriteDeviceBlock(type, addr, iSize, iData); 248 | } 249 | // ==================================================================================== 250 | public int WriteDeviceBlock(PlcDeviceType iType, int iAddress, int iSize, int[] iData) 251 | { 252 | PlcDeviceType type = iType; 253 | int addr = iAddress; 254 | var data = new List(6) 255 | { 256 | (byte) addr 257 | , (byte) (addr >> 8) 258 | , (byte) (addr >> 16) 259 | , (byte) type 260 | , (byte) iSize 261 | , (byte) (iSize >> 8) 262 | }; 263 | foreach (int t in iData) 264 | { 265 | data.Add((byte)t); 266 | data.Add((byte)(t >> 8)); 267 | } 268 | byte[] sdCommand = Command.SetCommand(0x1401, 0x0000, data.ToArray()); 269 | byte[] rtResponse = TryExecution(sdCommand); 270 | int rtCode = Command.SetResponse(rtResponse); 271 | return rtCode; 272 | } 273 | // ==================================================================================== 274 | public int ReadDeviceBlock(string iDeviceName, int iSize, int[] oData) 275 | { 276 | PlcDeviceType type; 277 | int addr; 278 | GetDeviceCode(iDeviceName, out type, out addr); 279 | return ReadDeviceBlock(type, addr, iSize, oData); 280 | } 281 | // ==================================================================================== 282 | public int ReadDeviceBlock(PlcDeviceType iType, int iAddress, int iSize, int[] oData) 283 | { 284 | PlcDeviceType type = iType; 285 | int addr = iAddress; 286 | var data = new List(6) 287 | { 288 | (byte) addr 289 | , (byte) (addr >> 8) 290 | , (byte) (addr >> 16) 291 | , (byte) type 292 | , (byte) iSize 293 | , (byte) (iSize >> 8) 294 | }; 295 | byte[] sdCommand = Command.SetCommand(0x0401, 0x0000, data.ToArray()); 296 | byte[] rtResponse = TryExecution(sdCommand); 297 | int rtCode = Command.SetResponse(rtResponse); 298 | byte[] rtData = Command.Response; 299 | for (int i = 0; i < iSize; ++i) 300 | { 301 | oData[i] = (rtCode == 0) ? BitConverter.ToInt16(rtData, i * 2) : 0; 302 | } 303 | return rtCode; 304 | } 305 | // ==================================================================================== 306 | public int SetDevice(string iDeviceName, int iData) 307 | { 308 | PlcDeviceType type; 309 | int addr; 310 | GetDeviceCode(iDeviceName, out type, out addr); 311 | return SetDevice(type, addr, iData); 312 | } 313 | // ==================================================================================== 314 | public int SetDevice(PlcDeviceType iType, int iAddress, int iData) 315 | { 316 | PlcDeviceType type = iType; 317 | int addr = iAddress; 318 | var data = new List(6) 319 | { 320 | (byte) addr 321 | , (byte) (addr >> 8) 322 | , (byte) (addr >> 16) 323 | , (byte) type 324 | , 0x01 325 | , 0x00 326 | , (byte) iData 327 | , (byte) (iData >> 8) 328 | }; 329 | byte[] sdCommand = Command.SetCommand(0x1401, 0x0000, data.ToArray()); 330 | byte[] rtResponse = TryExecution(sdCommand); 331 | int rtCode = Command.SetResponse(rtResponse); 332 | return rtCode; 333 | } 334 | // ==================================================================================== 335 | public int GetDevice(string iDeviceName, out int oData) 336 | { 337 | PlcDeviceType type; 338 | int addr; 339 | GetDeviceCode(iDeviceName, out type, out addr); 340 | return GetDevice(type, addr, out oData); 341 | } 342 | // ==================================================================================== 343 | public int GetDevice(PlcDeviceType iType, int iAddress, out int oData) 344 | { 345 | PlcDeviceType type = iType; 346 | int addr = iAddress; 347 | var data = new List(6) 348 | { 349 | (byte) addr 350 | , (byte) (addr >> 8) 351 | , (byte) (addr >> 16) 352 | , (byte) type 353 | , 0x01 354 | , 0x00 355 | }; 356 | byte[] sdCommand = Command.SetCommand(0x0401, 0x0000, data.ToArray()); 357 | byte[] rtResponse = TryExecution(sdCommand); 358 | int rtCode = Command.SetResponse(rtResponse); 359 | if (0 < rtCode) 360 | { 361 | oData = 0; 362 | } 363 | else 364 | { 365 | byte[] rtData = Command.Response; 366 | oData = BitConverter.ToInt16(rtData, 0); 367 | } 368 | return rtCode; 369 | } 370 | // ==================================================================================== 371 | //public int GetCpuType(out string oCpuName, out int oCpuType) 372 | //{ 373 | // int rtCode = Command.Execute(0x0101, 0x0000, new byte[0]); 374 | // oCpuName = "dummy"; 375 | // oCpuType = 0; 376 | // return rtCode; 377 | //} 378 | // ==================================================================================== 379 | public static PlcDeviceType GetDeviceType(string s) 380 | { 381 | return (s == "M") ? PlcDeviceType.M : 382 | (s == "SM") ? PlcDeviceType.SM : 383 | (s == "L") ? PlcDeviceType.L : 384 | (s == "F") ? PlcDeviceType.F : 385 | (s == "V") ? PlcDeviceType.V : 386 | (s == "S") ? PlcDeviceType.S : 387 | (s == "X") ? PlcDeviceType.X : 388 | (s == "Y") ? PlcDeviceType.Y : 389 | (s == "B") ? PlcDeviceType.B : 390 | (s == "SB") ? PlcDeviceType.SB : 391 | (s == "DX") ? PlcDeviceType.DX : 392 | (s == "DY") ? PlcDeviceType.DY : 393 | (s == "D") ? PlcDeviceType.D : 394 | (s == "SD") ? PlcDeviceType.SD : 395 | (s == "R") ? PlcDeviceType.R : 396 | (s == "ZR") ? PlcDeviceType.ZR : 397 | (s == "W") ? PlcDeviceType.W : 398 | (s == "SW") ? PlcDeviceType.SW : 399 | (s == "TC") ? PlcDeviceType.TC : 400 | (s == "TS") ? PlcDeviceType.TS : 401 | (s == "TN") ? PlcDeviceType.TN : 402 | (s == "CC") ? PlcDeviceType.CC : 403 | (s == "CS") ? PlcDeviceType.CS : 404 | (s == "CN") ? PlcDeviceType.CN : 405 | (s == "SC") ? PlcDeviceType.SC : 406 | (s == "SS") ? PlcDeviceType.SS : 407 | (s == "SN") ? PlcDeviceType.SN : 408 | (s == "Z") ? PlcDeviceType.Z : 409 | (s == "TT") ? PlcDeviceType.TT : 410 | (s == "TM") ? PlcDeviceType.TM : 411 | (s == "CT") ? PlcDeviceType.CT : 412 | (s == "CM") ? PlcDeviceType.CM : 413 | (s == "A") ? PlcDeviceType.A : 414 | PlcDeviceType.Max; 415 | } 416 | // ==================================================================================== 417 | public static bool IsBitDevice(PlcDeviceType type) 418 | { 419 | return !((type == PlcDeviceType.D) 420 | || (type == PlcDeviceType.SD) 421 | || (type == PlcDeviceType.Z) 422 | || (type == PlcDeviceType.ZR) 423 | || (type == PlcDeviceType.R) 424 | || (type == PlcDeviceType.W)); 425 | } 426 | // ==================================================================================== 427 | public static bool IsHexDevice(PlcDeviceType type) 428 | { 429 | return (type == PlcDeviceType.X) 430 | || (type == PlcDeviceType.Y) 431 | || (type == PlcDeviceType.B) 432 | || (type == PlcDeviceType.W); 433 | } 434 | // ==================================================================================== 435 | public static void GetDeviceCode(string iDeviceName, out PlcDeviceType oType, out int oAddress) 436 | { 437 | string s = iDeviceName.ToUpper(); 438 | string strAddress; 439 | // 获取软元件的首字母(大写) 440 | string strType = s.Substring(0, 1); 441 | switch (strType) 442 | { 443 | case "A": 444 | case "B": 445 | case "D": 446 | case "F": 447 | case "L": 448 | case "M": 449 | case "R": 450 | case "V": 451 | case "W": 452 | case "X": 453 | case "Y": 454 | // 获取这个软元件号,比如D1F4,则1F4被提取 455 | strAddress = s.Substring(1); 456 | break; 457 | case "Z": 458 | // Z开头可能是变址寄存器Z,也可能是文件寄存器ZR 459 | strType = s.Substring(0, 2); 460 | // 如果是文件寄存器ZR : 2 461 | // 变址寄存器Z : 1 462 | strAddress = s.Substring(strType.Equals("ZR") ? 2 : 1); 463 | if (strType != "ZR") strType = "Z"; 464 | break; 465 | case "C": 466 | strType = s.Substring(0, 2); 467 | switch (strType) 468 | { 469 | case "CC": 470 | case "CM": 471 | case "CN": 472 | case "CS": 473 | case "CT": 474 | strAddress = s.Substring(2); 475 | break; 476 | default: 477 | throw new Exception("Invalid format."); 478 | } 479 | break; 480 | case "S": 481 | strType = s.Substring(0, 2); 482 | switch (strType) 483 | { 484 | case "SD": 485 | case "SM": 486 | strAddress = s.Substring(2); 487 | break; 488 | default: 489 | throw new Exception("Invalid format."); 490 | } 491 | break; 492 | case "T": 493 | strType = s.Substring(0, 2); 494 | switch (strType) 495 | { 496 | case "TC": 497 | case "TM": 498 | case "TN": 499 | case "TS": 500 | case "TT": 501 | strAddress = s.Substring(2); 502 | break; 503 | default: 504 | throw new Exception("Invalid format."); 505 | } 506 | break; 507 | default: 508 | throw new Exception("Invalid format."); 509 | } 510 | oType = GetDeviceType(strType); 511 | oAddress = IsHexDevice(oType) ? Convert.ToInt32(strAddress, BlockSize) : 512 | Convert.ToInt32(strAddress); 513 | } 514 | // &&&&& protected &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 515 | abstract protected void DoConnect(); 516 | abstract protected void DoDisconnect(); 517 | abstract protected byte[] Execute(byte[] iCommand); 518 | // &&&&& private &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 519 | private const int BlockSize = 0x0010; 520 | private McCommand Command { get; set; } 521 | // ================================================================================ 522 | private byte[] TryExecution(byte[] iCommand) 523 | { 524 | byte[] rtResponse; 525 | int tCount = 10; 526 | do 527 | { 528 | rtResponse = Execute(iCommand); 529 | --tCount; 530 | if (tCount < 0) 531 | { 532 | throw new Exception("正确的值不能从PLC被检索。"); 533 | } 534 | } while (Command.IsIncorrectResponse(rtResponse)); 535 | return rtResponse; 536 | } 537 | // #################################################################################### 538 | // 用于通信命令的内部类 539 | class McCommand 540 | { 541 | private McFrame FrameType { get; set; } // 帧类型,用于哪种通信协议3E、4E 542 | private uint SerialNumber { get; set; } // 编号 543 | private uint NetwrokNumber { get; set; } // 网络号 544 | private uint PcNumber { get; set; } // PC号 545 | private uint IoNumber { get; set; } // e71模块的IO编号,手册上:1号 QCPU:03E0 H;控制CPU包括单CPU系统构成时的 QCPU 03FF H 546 | private uint ChannelNumber { get; set; } // e71的站号 547 | private uint CpuTimer { get; set; } // CPU监视定时器,e71发送数据到plc cpu后等待plc cpu反应的时间。 548 | private int ResultCode { get; set; } // 返回码 549 | public byte[] Response { get; private set; } // PLC响应返回的数据 550 | // ================================================================================ 551 | // 构造函数 552 | public McCommand(McFrame iFrame) 553 | { 554 | FrameType = iFrame; 555 | SerialNumber = 0x0001u;//用于4E frame协议 556 | NetwrokNumber = 0x0000u;//0x0002u是不符合手册的。单联时默认0x0000u 557 | PcNumber = 0x00FFu;//同上默认0x00FFu; 558 | IoNumber = 0x03FFu;//同上默认0x03FFu; 559 | ChannelNumber = 0x0008u;//e71站号 560 | CpuTimer = 0x000Au;//同上默认 561 | } 562 | // ================================================================================ 563 | // 用于产生相应的命令 564 | public void SetChannelNumber(uint cn) 565 | { 566 | ChannelNumber = cn;//e71站号 567 | } 568 | public byte[] SetCommand(uint iMainCommand, uint iSubCommand, byte[] iData) 569 | { 570 | var dataLength = (uint)(iData.Length + 6); 571 | var ret = new List(iData.Length + 20); 572 | uint frame = (FrameType == McFrame.MC3E) ? 0x0050u : 573 | (FrameType == McFrame.MC4E) ? 0x0054u : 0x0000u; 574 | ret.Add((byte)frame); 575 | ret.Add((byte)(frame >> 8)); 576 | if (FrameType == McFrame.MC4E) 577 | { 578 | ret.Add((byte)SerialNumber); 579 | ret.Add((byte)(SerialNumber >> 8)); 580 | ret.Add(0x00); 581 | ret.Add(0x00); 582 | } 583 | ret.Add((byte)NetwrokNumber); 584 | ret.Add((byte)PcNumber); 585 | ret.Add((byte)IoNumber); 586 | ret.Add((byte)(IoNumber >> 8)); 587 | ret.Add((byte)ChannelNumber); 588 | ret.Add((byte)dataLength); 589 | ret.Add((byte)(dataLength >> 8)); 590 | ret.Add((byte)CpuTimer); 591 | ret.Add((byte)(CpuTimer >> 8)); 592 | ret.Add((byte)iMainCommand); 593 | ret.Add((byte)(iMainCommand >> 8)); 594 | ret.Add((byte)iSubCommand); 595 | ret.Add((byte)(iSubCommand >> 8)); 596 | ret.AddRange(iData); 597 | return ret.ToArray(); 598 | } 599 | // ================================================================================ 600 | public int SetResponse(byte[] iResponse) 601 | { 602 | int min = (FrameType == McFrame.MC3E) ? 11 : 15; 603 | if (min <= iResponse.Length) 604 | { 605 | var btCount = new[] { iResponse[min - 4], iResponse[min - 3] }; 606 | var btCode = new[] { iResponse[min - 2], iResponse[min - 1] }; 607 | int rsCount = BitConverter.ToUInt16(btCount, 0); 608 | ResultCode = BitConverter.ToUInt16(btCode, 0); 609 | Response = new byte[rsCount - 2]; 610 | Buffer.BlockCopy(iResponse, min, Response, 0, Response.Length); 611 | } 612 | return ResultCode; 613 | } 614 | // ================================================================================ 615 | public bool IsIncorrectResponse(byte[] iResponse) 616 | { 617 | // if (iResponse.Length<5) return false; 618 | var min = (FrameType == McFrame.MC3E) ? 11 : 15; 619 | var btCount = new[] { iResponse[min - 4], iResponse[min - 3] };//request data length 620 | var btCode = new[] { iResponse[min - 2], iResponse[min - 1] };//完成码complete code 621 | var rsCount = BitConverter.ToUInt16(btCount, 0) - 2; 622 | var rsCode = BitConverter.ToUInt16(btCode, 0); 623 | return (rsCode == 0 && rsCount != (iResponse.Length - min)); 624 | } 625 | } 626 | } 627 | // ######################################################################################## 628 | public class McProtocolTcp : McProtocolApp 629 | { 630 | // ==================================================================================== 631 | // 构造函数 632 | public McProtocolTcp() : this("192.168.0.8", 2000, McFrame.MC3E, 0x0008u) { } 633 | public McProtocolTcp(string iHostName, int iPortNumber, McFrame mf, uint cn) 634 | : base(iHostName, iPortNumber, mf, cn) 635 | { 636 | Client = new TcpClient(); 637 | } 638 | // &&&&& protected &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 639 | override protected void DoConnect() 640 | { 641 | TcpClient c = Client; 642 | if (!c.Connected) 643 | { 644 | // Keep Alive功能 645 | var ka = new List(sizeof(uint) * 3); 646 | ka.AddRange(BitConverter.GetBytes(1u)); 647 | ka.AddRange(BitConverter.GetBytes(45000u)); 648 | ka.AddRange(BitConverter.GetBytes(5000u)); 649 | c.Client.IOControl(IOControlCode.KeepAliveValues, ka.ToArray(), null); 650 | c.Connect(HostName, PortNumber); 651 | Stream = c.GetStream(); 652 | } 653 | } 654 | // ==================================================================================== 655 | override protected void DoDisconnect() 656 | { 657 | TcpClient c = Client; 658 | if (c.Connected) 659 | { 660 | c.Close(); 661 | } 662 | } 663 | // ================================================================================ 664 | override protected byte[] Execute(byte[] iCommand) 665 | { 666 | NetworkStream ns = Stream; 667 | ns.Write(iCommand, 0, iCommand.Length); 668 | ns.Flush(); 669 | using (var ms = new MemoryStream()) 670 | { 671 | var buff = new byte[256]; 672 | do 673 | { 674 | int sz = ns.Read(buff, 0, buff.Length); 675 | if (sz == 0) 676 | { 677 | throw new Exception("已断开连接"); 678 | } 679 | ms.Write(buff, 0, sz); 680 | } while (ns.DataAvailable); 681 | return ms.ToArray(); 682 | } 683 | } 684 | // &&&&& private &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 685 | private TcpClient Client { get; set; } 686 | private NetworkStream Stream { get; set; } 687 | } 688 | // ######################################################################################## 689 | public class McProtocolUdp : McProtocolApp 690 | { 691 | // ==================================================================================== 692 | // 构造函数 693 | public McProtocolUdp() : this("192.168.0.8", 2000, McFrame.MC3E, 0x0008u) { } 694 | public McProtocolUdp(int iPortNumber) : this("192.168.0.8", iPortNumber, McFrame.MC3E, 0x0008u) { } 695 | public McProtocolUdp(string iHostName, int iPortNumber, McFrame mf, uint cn) 696 | : base(iHostName, iPortNumber, mf, cn) 697 | { 698 | Client = new UdpClient(iPortNumber); 699 | } 700 | // &&&&& protected &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 701 | override protected void DoConnect() 702 | { 703 | UdpClient c = Client; 704 | c.Connect(HostName, PortNumber); 705 | } 706 | // ==================================================================================== 707 | override protected void DoDisconnect() 708 | { 709 | // UDP不需要该功能 710 | } 711 | // ================================================================================ 712 | override protected byte[] Execute(byte[] iCommand) 713 | { 714 | UdpClient c = Client; 715 | // 发 716 | c.Send(iCommand, iCommand.Length); 717 | using (var ms = new MemoryStream()) 718 | { 719 | IPAddress ip = IPAddress.Parse(HostName); 720 | var ep = new IPEndPoint(ip, PortNumber); 721 | do 722 | { 723 | // 收 724 | byte[] buff = c.Receive(ref ep); 725 | ms.Write(buff, 0, buff.Length); 726 | } while (0 < c.Available); 727 | return ms.ToArray(); 728 | } 729 | } 730 | // &&&&& private &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 731 | private UdpClient Client { get; set; } 732 | } 733 | } 734 | 735 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.Form1.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.Form1.resources -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.Properties.Resources.resources -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | c:\users\wangchao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\bin\Debug\WindowsFormsApplication4.exe 2 | c:\users\wangchao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\bin\Debug\WindowsFormsApplication4.pdb 3 | c:\users\wangchao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.Properties.Resources.resources 4 | c:\users\wangchao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.csproj.GenerateResource.Cache 5 | c:\users\wangchao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.exe 6 | c:\users\wangchao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.pdb 7 | C:\Users\WangChao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.csprojResolveAssemblyReference.cache 8 | C:\Users\WangChao\documents\visual studio 2010\Projects\WindowsFormsApplication4\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.Form1.resources 9 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.exe 10 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.pdb 11 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\bin\Debug\WindowsFormsApplication4.exe 12 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\bin\Debug\WindowsFormsApplication4.pdb 13 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.csprojResolveAssemblyReference.cache 14 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.Form1.resources 15 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.Properties.Resources.resources 16 | C:\Users\WangChao\Dropbox\正在进行的项目\三菱组态软件\WindowsFormsApplication4\obj\x86\Debug\WindowsFormsApplication4.csproj.GenerateResource.Cache 17 | -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.exe -------------------------------------------------------------------------------- /简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zjsxwc/McProtocolTcpUdpExample/2e873be4c2e5e19508ab14826997d6a4e4e981c7/简单三菱组态实现按照三菱协议使用Socket通信/WindowsFormsApplication4/obj/x86/Debug/WindowsFormsApplication4.pdb --------------------------------------------------------------------------------