国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

C#實現(xiàn)在PC端讀取紅外線遙控器信號

2019-11-17 04:16:46
字體:
供稿:網(wǎng)友

這幾天要完成個任務(wù),就是利用一個紅外線適配器接受紅外線遙控器的信號,在PC上讀取信號,并判斷按的是哪個鍵,因為整個項目的需要,要求用C#實現(xiàn)。

 

首先,需要一個紅外線適配器(廢話~),因為我是用本本開發(fā)的,而我的本本沒有串口,所以就用了一個USB的紅外線適配器,這里需要一個USB轉(zhuǎn)串口的驅(qū)動,網(wǎng)上搜一下就有了,CSDN的下載里也有朋友上傳。

 

驅(qū)動裝上之后,就可以進行開發(fā)了。.net 為我們提供了一個串口類(有且僅有一個~~),就是SerialPort類,在名稱空間System.IO.Ports里。要實例化一個SerialPort類,我們必須知道串口的名字,使用方法System.IO.Ports.SerialPort.GetPortNames()可以獲得當(dāng)前電腦可用的串口,如果計算機上有多個串口,計算機很難判斷哪個串口是用來接受紅外線數(shù)據(jù)的,因此只能由用戶決定,這里我們可以用一個comboBox將可用串口列出來,供用戶選擇

view plaincopy to clipboardPRint?
string[] ports = System.IO.Ports.SerialPort.GetPortNames();  
           foreach (string port in ports)  
           {  
               combComName.Items.Add(port);  
           } 
 string[] ports = System.IO.Ports.SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                combComName.Items.Add(port);
            }

用戶選擇完之后就可以通過構(gòu)造方法實例化一個SerialPort對象了。對于一般的紅外線遙控器,使用以下的參數(shù)就可以了。

view plaincopy to clipboardprint?
port = new SerialPort( combComName.SelectedItem.ToString() , 9600, Parity.None, 8, StopBits.One);  
            port.Open(); 
port = new SerialPort( combComName.SelectedItem.ToString() , 9600, Parity.None, 8, StopBits.One);
            port.Open();

打開串口之后,我們就可以讀取串口信號了。這里我們使用read方法。由于一條按鍵信號一般為32位,這里我們就只接收32位數(shù)據(jù)了。

view plaincopy to clipboardprint?
byte[] buffer = new byte[36];  
System.Threading.Thread.Sleep(100);  
port.Read(buffer, 0, 36); 
byte[] buffer = new byte[36];
System.Threading.Thread.Sleep(100);
port.Read(buffer, 0, 36);

接下來是要把byte轉(zhuǎn)化成為16進制代碼。可以寫一個函數(shù)

view plaincopy to clipboardprint?
private string BytesToHexString(byte[] buffer, int offset, int length)  
       {  
           string info = "";  
           for (int i = offset; i < offset + length; i++)  
           {  
               info += string.Format("{0:X} ", buffer[i]).Trim();  
           }  
           return info;  
       } 
 private string BytesToHexString(byte[] buffer, int offset, int length)
        {
            string info = "";
            for (int i = offset; i < offset + length; i++)
            {
                info += string.Format("{0:X} ", buffer[i]).Trim();
            }
            return info;
        }

好的,現(xiàn)在如果我們用上述方法把接收到的信號顯示出來,應(yīng)該是類似于這樣的:

 

00FEFCFEFEFCFEFEFC0000000000000000FCFCFCFC00F8F8F000000000F00000

而且即使是同一個按鍵,有時候編碼還會有不一樣的。

 

 

對于一般的紅外遙控器來說,不可能會是這么長的編碼的,例如NEC的編碼規(guī)則就是:用戶識別碼(8位)+ 用戶識別碼反碼(8位)+ 數(shù)據(jù)碼(8位)+ 數(shù)據(jù)碼反碼(8位)。經(jīng)過一番研究,將上述編碼按字節(jié)分開:

00 FE FC FE FE FC FE FE FC 00 00 00 00 00 00 00 00 FC FC FC FC 00 F8 F8 F0 00 00 00 00 F0 00 00 00 00 00 00

如果把00當(dāng)做0,把FE、FC這些當(dāng)做1,改寫一下:

0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 0 0 0 0 1 0 0

再把這些0、1代碼8位分成一組,末尾多余的0去掉,轉(zhuǎn)化為16進制:

7F807B84

哈哈,看到這里應(yīng)該清楚了吧,經(jīng)過這樣一番轉(zhuǎn)換的信號完全符合NEC的編碼規(guī)則,而我使用的遙控器確實就是采用了NEC的芯片的。

 

回頭分析一下,我猜想產(chǎn)生這樣情況的原因可能是和串口設(shè)置的波特率有關(guān),因為我們我們不知道紅外遙控器的頻率,不知道一個脈沖式多少時間,因此在較高波特率的情況下,0信號變成了多個0,1信號變成了多個1,至于為什么會有FC、FE這樣不一樣的編碼,我猜想應(yīng)該是因為一個脈沖的末尾電壓不穩(wěn)定造成的。

 

知道了這些,接下來的事情就簡單了,寫個函數(shù)轉(zhuǎn)化一下就可以了,下面我附上源碼。具體實現(xiàn)的時候我用到了DataReceived事件對串口數(shù)據(jù)進行監(jiān)聽,這樣只要遙控器有信號過來就可以顯示了。

view plaincopy to clipboardprint?
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Linq;  
using System.Text;  
using System.Windows.Forms;  
using System.IO.Ports;  
namespace testseral  
{  
    public partial class Form1 : Form  
    {  
        private SerialPort port;  
        private const int CodeLength = 32;  
        delegate void SetInfo(string info);  
        public Form1()  
        {  
            InitializeComponent();  
        }  
        private void button1_Click(object sender, EventArgs e)  
        {  
            //初始化并打開串口  
            port = new SerialPort( combComName.SelectedItem.ToString() , 9600, Parity.None, 8, StopBits.One);  
            port.Open();  
            //監(jiān)聽串口數(shù)據(jù)  
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);  
            btOpen.Enabled = false;  
            btClose.Enabled = true;  
        }  
        private void button2_Click(object sender, EventArgs e)  
        {  
            port.Close();  
            btOpen.Enabled = true;  
            btClose.Enabled = false;  
        }  
        void port_DataReceived(object sender, SerialDataReceivedEventArgs e)  
        {  
              
                byte[] buffer = new byte[CodeLength];  
                System.Threading.Thread.Sleep(100);  
                int length = port.Read(buffer, 0, CodeLength);  
                if (length < CodeLength)  
                    return;  
                this.Invoke(new SetInfo(DataReceived), BytesToHexString(buffer, 0, length));  
        }  
        private string BytesToHexString(byte[] buffer, int offset, int length)  
        {  
            string info = "";  
            for (int i = offset; i < offset + length; i++)  
            {  
                info += string.Format("{0:X2} ", buffer[i]).Trim();  
            }  
            return info;  
        }  
        protected void DataReceived(string info)  
        {  
            rtbSerialInfo.Text += SignalToHexCode( info );  
        }  
        //將原始的二進制信號轉(zhuǎn)化為二進制編碼  
        private string SignalToBinaryCode(string Signal)  
        {  
            if (string.IsNullOrEmpty(Signal))  
            {  
                return null;  
            }  
            else 
            {  
                string Code = "";  
                for (int i = 0; i < CodeLength*2; i = i + 2)  
                {  
                    if (Signal.Substring(i,1).Equals( "0") )  
                    {  
                        Code = Code + "0";  
                    }  
                    else 
                    {  
                        Code = Code + "1";  
                    }  
                }  
                return Code;  
            }  
        }  
        //將二進制編碼轉(zhuǎn)化為16進制編碼  
        private string SignalToHexCode(string Signal)  
        {  
            Signal = SignalToBinaryCode(Signal);  
            if (!string.IsNullOrEmpty(Signal))  
            {  
                string HexCode = "";  
                string HexCodePiece = "";  
                for (int i = 0; i < CodeLength; i = i + 4)  
                {  
                    HexCodePiece = Signal.Substring(i, 4);  
                    HexCode = HexCode + Convert.ToString(Convert.ToInt32(HexCodePiece, 2), 16);  
                }  
                return HexCode;  
            }  
            else 
                return null;  
        }  
        private void comboBox1_DropDown(object sender, EventArgs e)  
        {  
            //獲得所有串口  
            combComName.Items.Clear();  
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();  
            foreach (string port in ports)  
            {  
                combComName.Items.Add(port);  
            }  
        }  
    }  
}

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 晋中市| 海兴县| 阿图什市| 东阿县| 调兵山市| 南阳市| 庆城县| 资溪县| 衡阳市| 巫山县| 日土县| 吴堡县| 天门市| 白水县| 吉林市| 南溪县| 西青区| 呈贡县| 东港市| 天全县| 普洱| 淮南市| 南充市| 都江堰市| 合川市| 纳雍县| 佛山市| 都昌县| 申扎县| 西城区| 科尔| 呼伦贝尔市| 安溪县| 穆棱市| 吉林省| 宁津县| 三河市| 恭城| 渭源县| 新丰县| 青浦区|