通过串口RS232和工控机连接,工控机可以接收设备(光电传感器)的IO信号
SerialPortSwitch portSwitch = new SerialPortSwitch("COM3");
ToolData.WriteLog(lrtxtLog, "打开" + cbcomname3.Text + "成功", 0);
portSwitch.SwitchOn += pin =>
{
//断开到闭合事件触发,CD、CTS、DSR之间任意一个触发都会进入该事件,可以在类中进行设置
};
portSwitch.SwitchOff += pin =>
{
//从闭合到断开事件触发
};
portSwitch.Start();
原理是软件后台线程一直发信号检测port.CDHolding以及port.DsrHolding和port.CtsHolding这三个的状态,如果状态变化则进入到事件
SerialPortSwitch类
/********************************************
* -------------
* \ 1 2 3 4 5 /
* \ 6 7 8 9 /
* ---------
* 原理:
* 4[DTR]作为+6V电源 也可以用[RTS]替代[DTR]
* 软件中不停检测
* 1[CD ]
* 6[DSR]
* 8[CTS]
* 三个端口的电压变化
*********************************************/
using System;
using System.IO.Ports;
using System.Threading;
namespace TrainDemo
{
/// <summary>
///
/// </summary>
public delegate void SwitchEventHandler(Pin pin);
/// <summary>
/// 用一个串口采集3路开关输入信号(也叫钢节点或继电器输入)
/// </summary>
public class SerialPortSwitch
{
private const int PRIORITY = 20;
/// <summary>
/// 瞬时信号过滤时间
/// </summary>
private const int FILTER = 40;
private readonly SerialPort port = new SerialPort();
private readonly PinState[] pins;
public event SwitchEventHandler SwitchOn;
public event SwitchEventHandler SwitchOff;
public bool IsRunning { get; private set; }
public bool StopPedding { get; private set; }
public SerialPortSwitch(string portName)
{
this.port.PortName = portName;
this.port.BaudRate = 9600;
this.port.Parity = Parity.None;
this.port.DataBits = 8;
this.port.StopBits = StopBits.Two;
this.port.ReadBufferSize = 8;
this.port.WriteBufferSize = 8;
this.port.DtrEnable = true;
this.port.RtsEnable = true;
this.port.Handshake = Handshake.RequestToSend;
pins = new[]//如果不需要全部信号都接收,可以在这里操作
{
new PinState {PinName = Pin.CD},
new PinState {PinName = Pin.CTS},
new PinState {PinName = Pin.DSR},
};
}
public void Start()
{
if (IsRunning) return;
IsRunning = true;
StopPedding = false;
try
{
Thread thread = new Thread(OnRunning);
thread.Name = "SerialPortSwitch";
thread.Start();
}
catch
{
IsRunning = false;
StopPedding = false;
throw;
}
}
public void Stop(bool waitUntilStoped = true)
{
if (IsRunning) StopPedding = true;
if (waitUntilStoped)
{
int timeout = Environment.TickCount + 10 * 1000;
while (Environment.TickCount < timeout)
{
Thread.Sleep(100);
if (IsRunning == false) return;
}
throw new TimeoutException("Stop SerialPortSwitch failed");
}
}
private void OnRunning()
{
try
{
port.Open();
while (StopPedding == false)
{
foreach (PinState pin in pins)
{
CheckState(pin);
}
Thread.Sleep(PRIORITY);
}
}
catch (Exception ex)
{
//TODO:log error.
System.Diagnostics.Debug.WriteLine("SerialPortSwitch term:" + ex);
}
finally
{
IsRunning = false;
StopPedding = false;
}
}
private void CheckState(PinState pin)
{
bool newHoding = GetPinHoding(pin.PinName);
if (pin.IsHoding == newHoding)
{
pin.HodingStableTime = Environment.TickCount;
}
if (Environment.TickCount - pin.HodingStableTime > FILTER)
{
pin.IsHoding = newHoding;
if (pin.IsHoding)
{
if (SwitchOn != null) SwitchOn(pin.PinName);
}
else
{
if (SwitchOff != null) SwitchOff(pin.PinName);
}
}
}
private bool GetPinHoding(Pin pin)
{
switch (pin)
{
case Pin.CD:
return port.CDHolding;
case Pin.DSR:
return port.DsrHolding;
case Pin.CTS:
return port.CtsHolding;
default:
throw new ArgumentOutOfRangeException();
}
}
}
/// <summary>
/// 串口中的3个信号针
/// </summary>
public enum Pin
{
CD = 1,
DSR = 6,
CTS = 8,
}
public class PinState
{
public Pin PinName { get; set; }
public bool IsHoding { get; set; }
public int HodingStableTime { get; set; }
}
}