程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 用串口實現普通電腦的開關量輸入

用串口實現普通電腦的開關量輸入

編輯:關於C#

普通電腦沒有通用的輸入輸出口(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 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 PortSignalReader
{
    /// <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 = 100;
    
        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;
    
            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; }
    }
}

Man函數:

class Program
    {
        static void Main(string[] args)
        {
            const string PORT_NAME = "COM6";//設置成你自己的端口
    
            SerialPortSwitch portSwitch = new SerialPortSwitch(PORT_NAME);
    
            portSwitch.SwitchOn += pin =>
            {
                Console.WriteLine(pin + "\tOn");
            };
            portSwitch.SwitchOff += pin =>
            {
                Console.WriteLine(pin + "\tOff");
            };
    
            portSwitch.Start();
            Console.WriteLine("串口輸入運行中,按任意鍵結束...");
            Console.ReadKey();
            portSwitch.Stop();
        }
    }

怎麼樣,是不是很簡單。一起來動手做一個吧~~~

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved