Win10 IoT C#開發 6 - 4x4矩陣鍵盤掃描

Windows 10 IoT Core 是微軟針對物聯網市場的一個重要產品,與以往的Windows版本不一樣,是爲物聯網設備專門設計的,硬件也不單單限於x86架構,同時能夠在ARM架構上運行。html

上一章咱們講了 Win10 IoT 如何對本地 IoT 設備內嵌 SQLite 數據庫進行 CURD 操做 ,這章咱們來學習如何使用 GPIO Pin 掃描4x4矩陣鍵盤按鍵狀態。若是對安裝部署過程還不熟悉能夠參考前幾篇文章,Raspberry安裝 IoT系統及搭建開發環境(http://www.cnblogs.com/cloudtech/p/5562120.html),建立 IoT應用及三種部署方法(http://www.cnblogs.com/cloudtech/p/5637983.html)。git

準備工做:

刷好Win 10 IoT Core系統的 Raspberry Pi 2

部署Visual Studio 2015開發環境的PC

4x4矩陣鍵盤

GPIO擴展板

IDC排線

杜邦線

麪包板github

 

實驗目標: 在4x4矩陣鍵盤上按下按鍵後,在程序界面上顯示對應的按鍵字符。數據庫

1.安裝元器件

首先將 GPIO擴展板 安裝到麪包板上,再經過 IDC排線 與 Raspberry Pi 2 的 GPIO 接口鏈接。微信

4x4矩陣鍵盤電路圖架構

行線R0-3分別與Pin五、Pin六、Pin1三、Pin19 引腳鏈接。框架

列線C0-3分別與Pin十二、Pin1六、Pin20、Pin21 引腳鏈接。async

2.編寫代碼

打開 VS 2015 點擊 New Project 在Visual C# -> Windows -> Universal 中找到 Blank App (Universal Windows) 項目模板,選中模板輸入項目名稱後點擊OK按鈕建立項目。工具

 項目建立完成後,在Reference Manager Extensions中 勾選Windows IoT Extensions for the UWP 添加 IoT擴展。學習

程序啓動後獲取默認GPIO控制器,對引腳進行初始化。

行線R0-3設置爲輸入端,20ms延時消抖,檢測到高電平認爲有按鍵按下,對列線逐一掃描確認。

列線C0-3設置爲輸出端高電平。

鍵碼映射表以下

行線R0-3對應鍵碼低4位。

列線C0-3對應鍵碼高4位。

這裏爲了簡便把MainPage.cs做爲ViewModel,來實現INotifyPropertyChanged接口完成一個簡易的MVVM框架。

代碼以下:

namespace CloudTechIot6
{
    //http://www.cnblogs.com/cloudtech
    //cloudtechesx@gmail.com
    public sealed partial class MainPage : Page, INotifyPropertyChanged
    {
        #region Fileds
        //GPIO控制器
        //Gpio Controller
        private GpioController _gpioController;
        //引腳集合
        //Pin Collection
        private GpioPin[] _pins;
        //鍵碼錶
        //KeyCode Table
        private Dictionary<byte, char> _keyMaps;
        private bool _initCompleted;

        #endregion

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties

        private string _msg;
        //鍵碼
        //Key Code
        public string Msg
        {
            get
            {
                return _msg;
            }

            set
            {
                _msg = value;
                OnPropertyChanged(this, new PropertyChangedEventArgs("Msg"));
            }
        }

        public string FreshTime
        {
            get
            {
                return _freshTime;
            }

            set
            {
                _freshTime = value;
                OnPropertyChanged(this, new PropertyChangedEventArgs("FreshTime"));
            }
        }

        private string _freshTime;

        #endregion

        #region Constructor

        public MainPage()
        {
            this.InitializeComponent();
            this.DataContext = this;
            _initCompleted = false;
            _keyMaps = new Dictionary<byte, char>();
            InitKeyMaps();
            //獲取默認GPIO控制器
            //Get Default Gpio Controller
            _gpioController = GpioController.GetDefault();
            if (null == _gpioController)
            {
                throw new Exception("GpioController init failed");
            }
            //初始化 GPIO Pin
            //Init GPIO 引腳
            _pins = new GpioPin[] { _gpioController.OpenPin(5), _gpioController.OpenPin(6), _gpioController.OpenPin(13), _gpioController.OpenPin(19), _gpioController.OpenPin(12), _gpioController.OpenPin(16), _gpioController.OpenPin(20), _gpioController.OpenPin(21) };

            for (int i = 0; i < 8; i++)
            {
                //設置爲輸入並監聽引腳電平變化
                //set input mode and listen pin level change
                if (i < 4)
                {
                    _pins[i].SetDriveMode(GpioPinDriveMode.Input);
                    _pins[i].DebounceTimeout = TimeSpan.FromMilliseconds(20);
                    _pins[i].ValueChanged += (GpioPin sender, GpioPinValueChangedEventArgs args) =>
                    {
                        lock (this)
                            //高電平
                            //high level 
                            if (_initCompleted && GpioPinEdge.RisingEdge == args.Edge)
                                //掃描列線
                                //scan column pin
                                for (int j = 4; j < 8; j++)
                                {
                                    _pins[j].Write(GpioPinValue.Low);
                                    if (GpioPinValue.Low == sender.Read())
                                    {
                                        //獲取生成鍵碼並輸出到界面
                                        //generate keycode and print on UI
                                        Msg = _keyMaps[(byte)((1 << ToIndex(sender)) | (1 << j))].ToString();
                                        FreshTime = DateTime.Now.ToString("HH:mm:ss");
                                        _pins[j].Write(GpioPinValue.High);
                                        break;
                                    }
                                    _pins[j].Write(GpioPinValue.High);
                                }
                    };
                }
                //設置爲輸出高電平
                //set output high level
                else
                {
                    _pins[i].SetDriveMode(GpioPinDriveMode.Output);
                    _pins[i].Write(GpioPinValue.High);
                }
            }
            Msg = "Push Button";
            //初始化完成
            //initialize completed
            _initCompleted = true;
        }

        #endregion

        #region Methods

        //MVVM依賴屬性通知事件
        private async void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { PropertyChanged?.Invoke(sender, e); });
        }

        //初始化鍵碼錶
        //initialize keycode
        private void InitKeyMaps()
        {
            _keyMaps.Add(0x88, '1');
            _keyMaps.Add(0x84, '2');
            _keyMaps.Add(0x82, '3');
            _keyMaps.Add(0x81, 'A');
            _keyMaps.Add(0x48, '4');
            _keyMaps.Add(0x44, '5');
            _keyMaps.Add(0x42, '6');
            _keyMaps.Add(0x41, 'B');
            _keyMaps.Add(0x28, '7');
            _keyMaps.Add(0x24, '8');
            _keyMaps.Add(0x22, '9');
            _keyMaps.Add(0x21, 'C');
            _keyMaps.Add(0x18, '*');
            _keyMaps.Add(0x14, '0');
            _keyMaps.Add(0x12, '#');
            _keyMaps.Add(0x11, 'D');
        }

        //獲取行線索引
        //get row pin index
        private int ToIndex(GpioPin pin)
        {
            int result = -1;
            for (int i = 0; i < _pins.Length; i++)
            {
                if (pin.Equals(_pins[i]))
                {
                    result = i;
                    break;
                }
            }
            if (0 > result)
            {
                throw new Exception("Unknow Pin Index");
            }
            else
            {
                return result;
            }
        }

        #endregion
    }
}

3.調試代碼

爲Raspberry鏈接電源及網線,鏈接HDMI顯示器。接通電源待系統啓動完成後顯示器上會顯示當前IoT設備的IP地址。

在 Visual Studio 2015 的工具欄中選擇 Remote Machine 進行調試,IP地址輸入設備對應地址。點擊運行後會自動部署到設備上。

這裏要注意平臺要選擇ARM。

程序啓動後按下4x4矩陣鍵盤上的按鍵後,程序界面上顯示對應的按鍵字符,與預期結果一致。

 

到這裏C#操做 Win10 IoT設備的4x4矩陣鍵盤過程就完成了,若是對代碼有優化的建議,歡迎留言或發郵件給我(cloudtechesx@gmail.com)。也能夠掃描下面的二維碼加個人微信號查看之前的文章。

完整項目源碼 GitHub https://github.com/CloudTechx/CloudTechIot 的 CloudTechIot6 目錄下。

Win10 IoT C#開發 1 - Raspberry安裝IoT系統及搭建開發環境 http://www.cnblogs.com/cloudtech/p/5562120.html
Win10 IoT C#開發 2 - 建立基於XAML的UI程序 及 應用的三種部署方法 http://www.cnblogs.com/cloudtech/p/5637983.html
Win10 IoT C#開發 3 - GPIO Pin 控制發光二極管 http://www.cnblogs.com/cloudtech/p/5617902.html
Win10 IoT C#開發 4 - UART 串口通訊 http://www.cnblogs.com/cloudtech/p/5518306.html
Win10 IoT C#開發 5 - 操做 IoT 設備內嵌 SQLite 數據庫 CURD http://www.cnblogs.com/cloudtech/p/5657123.html

相關文章
相關標籤/搜索