欧姆龙D4BS安全门开关(工控:C#中的串口,网口和PLC通讯)
Posted
篇首语:青春须早为,岂能长少年。本文由小常识网(cha138.com)小编为大家整理,主要介绍了欧姆龙D4BS安全门开关(工控:C#中的串口,网口和PLC通讯)相关的知识,希望对你有一定的参考价值。
欧姆龙D4BS安全门开关(工控:C#中的串口,网口和PLC通讯)
一.串口通讯方式
首先,串口、UART口、COM口、USB口是指的物理接口形式(硬件)。而TTL、RS-232、RS-485是指的电平标准(电信号)。
串口:串口是一个泛称,UART、TTL、RS232、RS485都遵循类似的通信时序协议,因此都被通称为串口
工控中常用的协议:RS232 RS485
RS232:是电子工业协会(Electronic Industries Association,EIA) 制定的异步传输标准接口,同时对应着电平标准和通信协议(时序),其电平标准:+3V~+15V对应0,-3V~-15V对应1。rs232 的逻辑电平和TTL 不一样但是协议一样
RS485:RS485是一种串口接口标准,为了长距离传输采用差分方式传输,传输的是差分信号,抗干扰能力比RS232强很多。两线压差为-(2~6)V表示0,两线压差为+(2~6)V表示1
常见的D型9针串口(通俗说法)。在台式电脑后边都可以看到。这种接口的协议只有两种:RS-232和RS-485
二.网口通讯方式
TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议。像这样把与互联网相关联的协议集合起来总称为 TCP/IP。也有说法认为,TCP/IP 是指 TCP 和 IP 这两种协议。还有一种说法认为,TCP/IP 是在 IP 协议的通信过程中,使用到的协议族的统称。
工控中常用的通讯有TCP和UDP
这两个区别就是:TCP 用于在传输层有必要实现可靠传输的情况。由于它是面向有链接并具备顺序控制、重发控制等机制的,所以他可以为应用提供可靠的传输。 而在一方面,UDP 主要用于那些对高速传输和实时性有较高要求的通信或广播通信。 我们举一个通过 IP 电话进行通话的例子。如果使用 TCP,数据在传送途中如果丢失会被重发,但这样无法流畅的传输通话人的声音,会导致无法进行正常交流。而采用 UDP,他不会进行重发处理。从而也就不会有声音大幅度延迟到达的问题。即使有部分数据丢失,也支持会影响某一小部分的通话。此外,在多播与广播通信中也是用 UDP 而不是 TCP。
三.确定PLC硬件
首先要确定PLC是否支持网口或者串口通信,大多数都支持RS232,TCP或者UDP,有的可能要购买拓展模块才能进行通信
四.确定PLC通信协议
通信协议:是指双方实体完成通信或服务所必须遵循的规则和约定。通过通信信道和设备互连起来的多个不同地理位置的数据通信系统,要使其能协同工作实现信息交换和资源共享,它们之间必须具有共同的语言。交流什么、怎样交流及何时交流,都必须遵循某种互相都能接受的规则。这个规则就是通信协议。
以下以欧姆龙FINS通信协议为例
一,握手命令
1、客户端向服务器发送命令00000000。这个命令长20字节,分成5组4字节。分别是:
头(FINS) + 长度(Hex0C) + 命令(00000000)+ 错误码(00000000) + 客户机节点地址。
46494E53是FINS的ASCII码值,即命令头。
0000000C是命令长度20。
00000000是命令码。
00000000是错误码。
00000005是客户节点地址,即电脑IP地址的末位。
在发送区输入:
46494E53 0000000C 00000000 00000000 00000005
点击发送,PLC立即回应:
46494E53 00000010 00000001 00000000 00000005 00000020
到此我们已经成功地完成了第一步!接下来需要的就是之前介绍过的HostLink协议里面FINS的知识了。
图3 网络调试助手 握手成功
2、这个是服务器端(PLC)向客户端(电脑)发送的命令00000001。这个命令长24字节,分成6组4字节。分别是:
头(FINS)+ 长度(Hex10) + 命令(00000001) + 错误码 + 客户机节点地址 + 服务器地址。
上面的命令错误代码为0,客户端ip地址05已被服务器32(hex20)成功记录。
如果发生错误,服务器回应的命令会包含错误码,连接断开,端口立刻关闭。当连接建立之后,不要再次发送这个命令,否则服务器会返回03错误码,即不支持的命令。全部的错误代码如下:
十六进制错误码 含义
00000000 正常
00000001 头不是‘FINS’ (ASCII code)。
00000002 数据太长。
00000003 不支持的命令。
00000020 所有的连接被占用。
00000021 制定的节点已经连接。
00000022 未被指定的IP地址试图访问一个被保护的节点。
00000023 客户端FINS节点地址超范围。
00000024 相同的FINS节点地址已经被使用。
00000025 所有可用的节点地址都已使用。
二、FINS帧发送命令
如果向服务器发送FINS帧,就要用到这个命令。由于FINS帧长度是12-2012,因此命令长度可变,
头(FINS)+长度+命令(00000002)+错误码+FINS帧。
FINS命令帧内容可参考欧姆龙OMRON PLC之HostLink通讯协议-FINS命令W字/位操作篇,里面有存储区代码和操作代码的内容。
例2-1、读DM0开始的2个通道:
发送:
46494E53 0000001A 00000002 00000000 80000200 20000005 00FF0101 82000000 0002
20000005:20是目标地址,05是源地址;
00FF0101 :0101是读操作;
82000000:82是DM存储区代码,000000是起始地址;
0002:是数量。
返回:
46494E53 0000001A 00000002 00000000 C0000200 05000020 00FF0101 00001234 5678
00001234:0000代表操作成功,1234是读回的第一个字,即D0=Hex1234,
5678:D1=Hex5678
例2-2、W210寄存器写入Hex0388:
发送:
46494E53 0000001C 00000002 00000000 80000200 20000005 00FF0102 B100D200 00010388
20000005:20是目标地址,05是源地址;
00FF0102:0102是写操作代码;
B100D200:B1是W字代码,00D2是起始地址,Hex00D2=212,;
00010388:是写入数量,0388是写入首个内容;
回应:
46494E53 00000016 00000002 00000000 C0000200 05000020 00FF0102 0000
0102后面紧跟的0000代表写入成功。
例2-3、W210寄存器读取:
发送:
46494E53 0000001A 00000002 00000000 80000200 20000005 00FF0101 B100D200 0001
20000005:20是目标地址,05是源地址;
00FF0101:0101是读操作代码;
B100D200:B1是W字代码,00D2是起始地址,Hex00D2=212,;
0001:是读取数量。
回应:
46494E53 00000018 00000002 00000000 C0000200 05000020 00FF0101 00000388
0102后面紧跟的0000代表读取成功,W210=Hex0388
例2-4、强制W212.01=On:
发送:
46494E53 0000001C 00000002 00000000 80000200 20000005 00FF2301 00010001 3100D401
20000005:20是目标地址,05是源地址;
00FF2301:2301是强制操作代码;
00010001:前面的0001是数量,后面的0001代表强制置位操作;
3100D401:31是W位代码,00D401是起始地址,Hex00D4.01=212.01。
回应:
46494E53 00000016 00000002 00000000 C0000200 05000020 00FF2301 0000
2301后面紧跟的0000表示操作成功。
注意在CX-Programmer查看窗口中W212.01的值1后面的(强制)字样。
图4 网络调试助手 强制置位
图5 CX-Programmer 强制置位成功
例2-5、强制W212.01=Off:
发送:
46494E53 0000001C 00000002 00000000 80000200 20000005 00FF2301 00010000 3100D401
20000005:20是目标地址,05是源地址;
00FF2301:2301是强制操作代码;
00010000:0001是数量,0000代表强制复位操作;
3100D401:31是W位代码,00D401是起始地址,Hex00D4.01=212.01。
回应:
46494E53 00000016 00000002 00000000 C0000200 05000020 00FF2301 0000
2301后面紧跟的0000表示操作成功。
例2-6、取消W212.01强制:
发送:
46494E53 0000001C 00000002 00000000 80000200 20000005 00FF2301 0001FFFF 3100D401
20000005:20是目标地址,05是源地址;
00FF2301:2301是强制操作代码;
0001FFFF:0001是数量,FFFF代表取消强制操作;
3100D401:31是W位代码,00D401是起始地址,Hex00D4.01=212.01。
回应:
46494E53 00000016 00000002 00000000 C0000200 05000020 00FF2301 0000
2301后面紧跟的0000表示操作成功。
注意在CX-Programmer查看窗口中W212.01的值0后面的(强制)字样不见了,表示已经成功地取消了强制。
图6 网络调试助手 取消强制
图7 CX-Programmer 取消强制成功
与CIO不同,对于W、A、H及D 这样的寄存器进行位操作,其实不用强制操作,直接写入更简洁,可以减少操作步骤,下面以W位操作为例介绍。
例2-7、W212.01 按位置位:
发送:
46494E53 0000001B 00000002 00000000 80000200 20000005 00FF0102 3100D401 000101
20000005:20是目标地址,05是源地址;
00FF0102:0102是寄存器写操作代码;
3100D401:31是W位代码,00D401是地址,Hex00D4.01=212.01;
000101:0001是数量,01代表写入值1;
回应:
46494E53 00000016 00000002 00000000 C0000200 20000005 00FF0102 0000
0102后面紧跟的0000表示操作成功。
例2-8、W212.01 按位复位:
发送:
46494E53 0000001B 00000002 00000000 80000200 20000005 00FF0102 3100D401 000100
20000005:20是目标地址,05是源地址;
00FF0102:0102是寄存器写操作代码;
3100D401:31是W位代码,00D401是地址,Hex00D4.01=212.01;
000100:0001是数量,00代表写入值0;
回应:
46494E53 00000016 00000002 00000000 C0000200 20000005 00 FF0102 0000
0102后面紧跟的0000表示操作成功。
五.使用C#进行通信
1.串口
串口在C#中使用的是SerialPort这个类
要注意通讯协议中报文内容是16进制,还是ASCII码,还是就是普通的字符串,有格式的话注意发送和接收的报文需要转换
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.IO.Ports;using System.Threading;using System.Windows.Forms;public class SerialOP : IDisposable private SerialPort Comport = new SerialPort(); private AutoResetEvent _manualEvent = new AutoResetEvent(false); private object _lockRead = new object(); private object _lockWrite = new object(); private byte[] _reivedData; private string reive=null; private object onRecive =new object(); public delegate void UpdateByteDelegate(byte[] reive); public event UpdateByteDelegate UpdateByte; /// <summary> /// 打开串口 /// </summary> /// <param name="com"></param> /// <param name="bps"></param> /// <param name="databit"></param> /// <param name="stopbit"></param> /// <param name="check"></param> public bool Open(string com, string bps, string databit, string stopbit, string check) try if (Comport.IsOpen) Comport.Close(); Thread.Sleep(100); //串口端口号 Comport.PortName = com; //串口波特率 Comport.BaudRate = int.Parse(bps); //串口数据位 Comport.DataBits = int.Parse(databit); //串口停止位 switch (stopbit) case "0": Comport.StopBits = StopBits.None; break; case "1": Comport.StopBits = StopBits.One; break; case "1.5": Comport.StopBits = StopBits.OnePointFive; break; case "2": Comport.StopBits = StopBits.Two; break; default: Comport.StopBits = StopBits.None; break; //串口奇偶校验 switch (check) case "无": Comport.Parity = Parity.None; break; case "奇校验": Comport.Parity = Parity.Odd; break; case "偶校验": Comport.Parity = Parity.Even; break; default: Comport.Parity = Parity.None; break; //Comport.ReceivedBytesThreshold = 1;//1字节触发数据获取 //Comport.DataReceived += new SerialDataReceivedEventHandler(OnReceived); Comport.Open(); Comport.DtrEnable = true; Comport.RtsEnable = true; return true; catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("连续打开关闭串口出现错误:" + ex.Message,"SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); return false; /// <summary> /// 检测串口是否打开 /// </summary> /// <returns></returns> private bool IsOpen() try if (Comport == null) return false; if (Comport.IsOpen) return true; else return false; catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("检测串口是否打开出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); return false; private void OnReceived(object sender, SerialDataReceivedEventArgs e) try lock (onRecive) byte[] reive = new byte[Comport.BytesToRead]; Comport.Read(reive, 0, Comport.BytesToRead); UpdateByte.Invoke(reive); catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("串口接收数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); finally _manualEvent.Set(); /// <summary> /// 字符串转ASII码发送 /// </summary> /// <returns></returns> public void Send_ASCII(string str) try lock (_lockWrite) var ByteSendW = Encoding.ASCII.GetBytes(str );//把发送数据转换为ASCII数组 Comport.Write(ByteSendW, 0, ByteSendW.Length); catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("串口发送数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 发送16进制数组,需要用,隔开 /// </summary> /// <param name="Hex"></param> /// <param name="check"></param> public void Send_HEX(string Hex) try lock (_lockWrite) //16进制字符串转换成16进制数组 var HEX = Hex.Split(',').Select(temp => "0x" + temp).Select(temp => (byte)Convert.ToInt32(temp, 16)).ToArray(); Comport.Write(HEX, 0, HEX.Length); catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("串口发送数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 发送字符串不转换 /// </summary> /// <param name="str"></param> public void Send_String(string str) try lock (_lockWrite) Comport.Write(str); catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("串口发送数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 接收ASCII码,并转换成字符串 /// </summary> /// <param name="str"></param> public void Read_ASCII(out string str) str = "error"; try lock (_lockRead) if (Comport.BytesToRead == 0) LogHelper.error("缓存区没有数据"); return; for (int i = 0; i < 100; i++)//读取100个字节 if (Comport.BytesToRead == 0) str = reive; reive = null; break; string reivestring = ""; _reivedData = new byte[1]; Comport.Read(_reivedData, 0, _reivedData.Length); reivestring = Encoding.ASCII.GetString(_reivedData); reive += reivestring; //Comport.DiscardInBuffer(); catch (Exception ex) str = ex.ToString(); LogHelper.error(ex.ToString()); MessageBox.Show("串口读取数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 接收字符串,不进行任何转换 /// </summary> /// <param name="str"></param> public void Read_String(out string str) str = "error"; try lock (_lockRead) if (Comport.BytesToRead == 0) LogHelper.error("缓存区没有数据"); return; for (int i = 0; i < 100; i++)//读取100个字节 if (Comport.BytesToRead == 0) str = reive; reive = null; break; _reivedData = new byte[1]; Comport.Read(_reivedData, 0, _reivedData.Length); reive += _reivedData[0].ToString() + " "; catch (Exception ex) str = ex.ToString(); LogHelper.error(ex.ToString()); MessageBox.Show("串口读取数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 接收到16进制,转成字符串 /// </summary> /// <param name="str"></param> public void Read_HEX_String(out string str) str = "error"; try lock (_lockRead) if (Comport.BytesToRead == 0) LogHelper.error("缓存区没有数据"); return; for (int i = 0; i < 100; i++)//读取100个字节 if (Comport.BytesToRead == 0) reive = reive.Substring(0, reive.Length - 1);//移除最后一位逗号 str = reive; reive = null; break; _reivedData = new byte[1]; Comport.Read(_reivedData, 0, _reivedData.Length); reive += _reivedData[0].ToString("x2").ToUpper() + ","; catch (Exception ex) str = ex.ToString(); LogHelper.error(ex.ToString()); MessageBox.Show("串口读取数据出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 关闭串口 /// </summary> public void Close() try if (Comport.IsOpen) Comport.Close(); catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("关闭串口出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); /// <summary> /// 释放串口 /// </summary> public void Dispose() try if (Comport.IsOpen) Comport.Close(); Comport.Dispose(); catch (Exception ex) LogHelper.error(ex.ToString()); MessageBox.Show("释放串口出现错误:" + ex.Message, "SerialPort---Message", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); //Comport.DataReceived -= new SerialDataReceivedEventHandler(Comport_DataReceived); /// <summary> /// CRC16校验 /// </summary> /// <param name="data"></param> /// <returns></returns> public string CRCCalc(string data) string[] datas = data.Split(' '); List<byte> bytedata = new List<byte>(); foreach (string str in datas) bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier)); byte[] crcbuf = bytedata.ToArray(); //计算并填写CRC校验码 int crc = 0xffff; int len = crcbuf.Length; for (int n = 0; n < len; n++) byte i; crc = crc ^ crcbuf[n]; for (i = 0; i < 8; i++) int TT; TT = crc & 1; crc = crc >> 1; crc = crc & 0x7fff; if (TT == 1) crc = crc ^ 0xa001; crc = crc & 0xffff; string[] redata = new string[2]; redata[1] = Convert.ToString((byte)((crc >> 8) & 0xff), 16); redata[0] = Convert.ToString((byte)((crc & 0xff)), 16); return redata[0].ToUpper() + " " + redata[1].ToUpper();
2.网口
网口分客户端和服务器,协议有TCP和UDP
以下以TCP为例
TCP客户端
public class TcpClient public bool connected =false ; Socket socketClient;//客户端接口 Task threadAcceptClient,//客户端接收线程 threadClient; //客户端线程 private string IpAddress = string.Empty; private int Port = 0; public TcpClient(string IpAddress, int Port) this.IpAddress = IpAddress; this.Port = Port; ClientConnectSever(); /// <summary> /// 客户端连接服务器 /// </summary> public bool ClientConnectSever() IPAddress ip = IPAddress.Parse(IpAddress); IPEndPoint port = new IPEndPoint(ip, Port);//服务器port //创建TCP类型端口 socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try socketClient.Connect(port); connected = true; return true; catch (Exception ex) LogHelper.error(IpAddress+"连接服务器失败:" + ex.Message); return false; public void ColseConnect() socketClient.Close(); public bool ClientSendData(string data) if (!connected) LogHelper.error(IpAddress+"未连接到服务器"); return false; byte[] msg = Encoding.Default.GetBytes(data); try NetworkStream netStream = new NetworkStream(socketClient); netStream.Write(msg, 0, msg.Length); netStream.Flush(); return true; catch (Exception ex) LogHelper.error(IpAddress+"发送失败:" + ex.Message); return false; public string ClientReadData() try if (!connected) LogHelper.error(IpAddress+"未连接到服务器"); return "error"; NetworkStream netStream = new NetworkStream(socketClient); byte[] dataSize = new byte[1024]; netStream.Read(dataSize, 0, dataSize.Length); var Result = Encoding.Default.GetString(dataSize).TrimEnd('\\0'); if (Result.Length > 1) return Result; else return string.Empty; //this.rtb_accept1.Rtf = Encoding.Unicode.GetString(message); catch (Exception ex) LogHelper.error(IpAddress+"读取数据失败:" + ex.Message); return "error";
TCP服务器
public class TcpServer public delegate void UpdateObjectDelegate(object sender); public event UpdateObjectDelegate UpdataDataString; public event UpdateObjectDelegate UpdateMessage; private string IpAddress = string.Empty; private int Port = 0; public TcpServer(string IpAddress, int Port) this.IpAddress = IpAddress; this.Port = Port; static Socket serverSocket; List<Socket> ClientList = new List<Socket>(); //客户端列表 public bool connected = false; public void StartListen() Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); serverSocket = socket; //ip port socket.Bind(new IPEndPoint( IPAddress.Parse(IpAddress), Port)); //listen socket.Listen(10);//连接等待队列 ThreadPool.QueueUserWorkItem(new WaitCallback(this.AcceptClientConnect), socket); private void AcceptClientConnect(object socket) var serverSocket = socket as Socket; UpdateMessage.Invoke("服务器开始监听"); while (true) try var proxSocket = serverSocket.Accept(); ClientList.Add(proxSocket); UpdateMessage.Invoke((object)("客户端" + proxSocket.RemoteEndPoint.ToString() + "连接上了")); //接受消息 ThreadPool.QueueUserWorkItem(new WaitCallback(this.ReceiveData), proxSocket); connected = true; catch (Exception e) UpdateMessage.Invoke("服务器监听错误:" + e.ToString()); connected = false; private void ReceiveData(object obj) Socket proxSocket = obj as Socket; byte[] data = new byte[1024 * 1024]; while (true) int readLen = 0; try readLen = proxSocket.Receive(data, data.Length,0); //if (readLen <= 0) // // //客户端正常退出 // UpdateMessage.Invoke(string.Format("客户端0正常退出", proxSocket.RemoteEndPoint.ToString())); // ClientList.Remove(proxSocket); // CloseListen(proxSocket); // connected = false; // return;//方法结束->终结当前接受客户端数据的异步线程 // string txt = Encoding.Default.GetString(data, 0, readLen).TrimEnd('\\0'); if(txt.Length>1) UpdataDataString.Invoke(txt); catch (Exception ex) //异常退出时 UpdateMessage.Invoke(string.Format("客户端0非正常退出,原因1", proxSocket.RemoteEndPoint.ToString(), ex.ToString())); ClientList.Remove(proxSocket); CloseListen(proxSocket); connected = false; return; private void CloseListen(Socket proxSocket) try if (proxSocket.Connected) proxSocket.Shutdown(SocketShutdown.Both); proxSocket.Close(100); connected = false; catch (Exception) UpdateMessage("服务器关闭发生异常"); connected = false; public bool ServerSendData(string msg) try foreach (Socket s in this.ClientList) //服务端广播式发送给客户端 (s as Socket).Send(Encoding.Default.GetBytes(msg)); return true; catch return false;
相关参考
广州凌华工控机(强悍如斯可扩展18路串口或6路千兆以太网方案强势来袭)
集微网消息随着工控机应用逐渐从传统的冶金、电力、石化等行业转向储能、自动化、物联网等新兴领域。持续变化的市场也愈发需要与时俱进的工控机方案,一机多网、丰富接口以及高可靠性等成为当下应用端最迫切的诉求。...
施耐德EZD塑壳断路器(电气采购找中晨工控,自动化方案也找中晨工控)
...,与施耐德、驱易、安拓、西门子、德力西、罗克韦尔、欧姆龙、正泰、ABB、魏德米勒、明纬、菲尼克斯、霍尼韦尔、上海二工、三菱、常熟开关、威图
武汉欧姆龙开关(欧姆龙微动开关SS-5GL在体外诊断仪中的应用)
体外诊断医疗器械是指制造商预定用于体外检查从人体取得的样品,包括血液及组织供体的,无论单独使用或是组合使用的任何医疗器械,包括试剂、试剂产品、校准材料、控制材料、成套工具、仪表、装置、设备或系统。体外...
欧姆龙限位开关(欧姆龙微动开关_欧姆龙微动开关D3VJ,实现微波炉联锁监控)
...EC)的规定,所有微波炉出厂必须至少有一个联锁装置,而欧姆龙微动开关,可以实现联锁监控装置,确保人们安全;微波炉的工作原理是什么?欧姆龙微动开关在微波炉中的应用又在哪里呢?一.微波炉的工作原理微波炉,是一...
现代社会人们对住房的要求也不段在提升高,不再是能遮风挡雨就能满足了,更多考虑的是居家安全.随着智能家居产业蓬勃发展,越来越多的人将目光投向了外观时尚、功能多样化的智能锁。智能锁是近几年在我国家居行业兴起的...
欧姆龙安全开关(欧姆龙开关:欧姆龙微动开关D3VJ在执行器上的应用)
欧姆龙微动开关也是比较全面的,应用于多种场景及领域。开关在我们的生活中是很常见的了,它能够为我们控制各种电器设备的开启和停止;欧姆开关作为发展趋势,已成为世界著名的机械自动化和电子产品生产企业;虽然是...
欧姆龙PLC用锂电池(工控中最常见的7种PLC编程语言,据说精通5种以上就可以月薪过万)
plc编程软件有哪些?1、欧姆龙plc编程软件欧姆龙plc编程软件集成了CX-ProgrammerV9.5,能够为欧姆龙PLC编程提供全面的软件支持,本版本为最新版,全面支持32/64位WIN8系统,为多国语言版,支持简体中文。能为网络、可编程终端及伺...
应用程序的main方法中有以下(C# 中的Async 和 Await 的用法详解)
众所周知C#提供Async和Await关键字来实现异步编程。在本文中,我们将共同探讨并介绍什么是Async和Await,以及如何在C#中使用Async和Await。同样本文的内容也大多是翻译的,只不过加上了自己的理解进行了相关知识点的补充,如果...
我是李工,我来了,今天讲一下0欧姆电阻。0欧姆电阻的阻值是多少?0欧姆电阻即电阻标值为0欧姆的电阻,多用于PCB设计等方面,是一种理想电阻。那0欧姆电阻是表示没有电阻吗?当然不是,0欧姆电阻的阻值不是0欧姆,只是...
德国SIEMENS西门子(工控界的泰山北斗,PLC界的扛把子,西门子PLC介绍以及软件分享)
...言,而是称霸PLC界的三大霸主,S指西门子,F指三菱,C指欧姆龙。这三家PLC几乎占领了中国自动化界白分之九十以上的市场。其中西门子是欧系的代表,三菱时日系的代表,而欧姆龙更像是一个美国大兵娶了日本歌姬集合的产物...