程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
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