首页 > 学院 > 开发设计 > 正文

另类,用串口实现普通电脑的开关量输入

2019-11-17 03:19:07
字体:
来源:转载
供稿:网友

另类,用串口实现普通电脑的开关量输入

普通电脑没有通用的输入输出口(GPIO),但有时候我就想输入一个开关量。

比如让用户拉一下拉绳开关就启动某个应用,比如装一个触点开关判断门是打开的还是关闭的,比如....

需求是如此简单,你都不愿意花几十块钱去买一个单片机,更不用说PCI扩展卡、PLC之类的了。。怎么办呐?

有办法!最简单的用串口就能实现。

原理:

串口的pin4[DTR]和pin7[RTS] 可以输出+6V的电(好吧,你的电脑上不一定是+6V,但肯定大于+3V就可以了),将该输出分别接入到pin1[DCD]、pin6[DSR]、pin8[CTS],在PC上就能检测出来,从而实现开关量输入。

核心代码:

//往PIN口输出电压SerialPort.DtrEnable = true;SerialPort.RtsEnable = true;//判断PIN是否有电压输入bool cd = SerialPort.CDHolding;bool dsr = SerialPort.DsrHolding;bool cts = SerialPort.CtsHolding;

知道原理,剩下的就好办了。

首先是接线:(你需要一个9针串口母头、若干个开关、导线、电烙铁)

如图,我接了3个开关,4作为公共引脚,1、6、8分别接一个开关用于输入信号。当然,你只接一个开关也可以的。

(电脑主板上的带针的是公头,接线要用母头否则插不到电脑上,如果没有可以到电子城去买一个很便宜的,上面的编号很小要仔细看

没有串口的笔记本可以淘宝上买一条USB转串口线也可以的)

然后写一段代码不停检测1、6、8口是否有输入:

  1 /********************************************  2  * -------------  3  * / 1 2 3 4 5 /  4  *  / 6 7 8 9 /  5  *   ---------   6  * 原理:  7  * 4[DTR]作为+6V电源 也可以用[RTS]替代[DTR]  8  * 软件中不停检测  9  * 1[CD ] 10  * 6[DSR] 11  * 8[CTS] 12  * 三个端口的电压变化 13  *********************************************/ 14  15 using System; 16 using System.IO.Ports; 17 using System.Threading; 18  19 namespace PortSignalReader 20 { 21     /// <summary> 22     ///  23     /// </summary> 24     public delegate void SwitchEventHandler(Pin pin); 25  26     /// <summary> 27     /// 用一个串口采集3路开关输入信号(也叫钢节点或继电器输入) 28     /// </summary> 29     public class SerialPortSwitch 30     { 31         PRivate const int PRIORITY = 20; 32  33         /// <summary> 34         /// 瞬时信号过滤时间 35         /// </summary> 36         private const int FILTER = 100; 37  38         private readonly SerialPort port = new SerialPort(); 39  40         private readonly PinState[] pins; 41  42         public event SwitchEventHandler SwitchOn; 43  44         public event SwitchEventHandler SwitchOff; 45  46         public bool IsRunning { get; private set; } 47  48         public bool StopPedding { get; private set; } 49  50         public SerialPortSwitch(string portName) 51         { 52             this.port.PortName = portName; 53             this.port.BaudRate = 9600; 54             this.port.Parity = Parity.None; 55             this.port.DataBits = 8; 56             this.port.StopBits = StopBits.Two; 57             this.port.ReadBufferSize = 8; 58             this.port.WriteBufferSize = 8; 59             this.port.DtrEnable = true; 60             this.port.RtsEnable = true; 61  62             pins = new[] 63             { 64                 new PinState {PinName = Pin.CD}, 65                 new PinState {PinName = Pin.CTS}, 66                 new PinState {PinName = Pin.DSR}, 67             }; 68         } 69  70         public void Start() 71         { 72             if(IsRunning) return; 73             IsRunning = true; 74             StopPedding = false; 75             try 76             { 77                 Thread thread = new Thread(OnRunning); 78                 thread.Name = "SerialPortSwitch"; 79                 thread.Start(); 80             } 81             catch 82             { 83                 IsRunning = false; 84                 StopPedding = false; 85                 throw; 86             } 87         } 88  89         public void Stop(bool waitUntilStoped = true) 90         { 91             if (IsRunning) StopPedding = true; 92  93             if (waitUntilStoped) 94             { 95                 int timeout = Environment.TickCount + 10 * 1000; 96                 while (Environment.TickCount < timeout) 97                 { 98                     Thread.Sleep(100); 99                     if (IsRunning == false) return;100                 }101                 throw new TimeoutException("Stop SerialPortSwitch failed");102             }103         }104 105         private void OnRunning()106         {107             try108             {109                 port.Open();110                 while (StopPedding == false)111                 {112                     foreach (PinState pin in pins)113                     {114                         CheckState(pin);115                     }116                     Thread.Sleep(PRIORITY);117                 }118             }119             catch (Exception ex)120             {121                 //TODO:log error.122                 System.Diagnostics.Debug.WriteLine("SerialPortSwitch term:" + ex);123             }124             finally125             {126                 IsRunning = false;127                 StopPedding = false;128             }129         }130 131         private void CheckState(PinState pin)132         {133             bool newHoding = GetPinHoding(pin.PinName);134             if (pin.IsHoding == newHoding)135             {136                 pin.HodingStableTime = Environment.TickCount;137             }138             if (Environment.TickCount - pin.HodingStableTime > FILTER)139             {140                 pin.IsHoding = newHoding;141                 if (pin.IsHoding)142                 {143                     if (SwitchOn != null) SwitchOn(pin.PinName);144                 }145                 else146                 {147                     if (SwitchOff != null) SwitchOff(pin.PinName);148                 }149             }150         }151 152         private bool GetPinHoding(Pin pin)153         {154             switch (pin)155             {156                 case Pin.CD:157                     return port.CDHolding;158                 case Pin.DSR:159                     return port.DsrHolding;160                 case Pin.CTS:161                     return port.CtsHolding;162                 default:163                     throw new ArgumentOutOfRangeException();164             }165         }166     }167 168     /// <summary>169     /// 串口中的3个信号针170     /// </summary>171     public enum Pin172     {173         CD = 1,174         DSR = 6,175         CTS = 8,176     }177 178     public class PinState179     {180         public Pin PinName { get; set; }181 182         public bool IsHoding { get; set; }183 184         public int HodingStableTime { get; set; }185     }186 }
View Code

Man函数:

 1 class Program 2     { 3         static void Main(string[] args) 4         { 5             const string PORT_NAME = "COM6";//设置成你自己的端口 6  7             SerialPortSwitch portSwitch = new SerialPortSwitch(PORT_NAME); 8  9             portSwitch.SwitchOn += pin =>10             {11                 Console.WriteLine(pin + "/tOn");12             };13             portSwitch.SwitchOff += pin =>14             {15                 Console.WriteLine(pin + "/tOff");16             };17 18             portSwitch.Start();19             Console.WriteLine("串口输入运行中,按任意键结束...");20             Console.ReadKey();21             portSwitch.Stop();22         }23     }
View Code

怎么样,是不是很简单。一起来动手做一个吧~~~


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表