上一篇介紹了 Windows 10 IoT 的 Hello World 如何撰寫。
可以參考:http://www.ez2o.com/Blog/Post/Windows-10-IoT-Hello-World-Use-Raspberry-Pi-2
本篇要示範 燈泡閃爍 Blinky,此為 GPIO (General Purpose Input/Output) 的基礎操作,也是 物聯網 最基本的電路練習,務必要通盤了解清楚,日後開發上才會得心意手。
必須準備材料如下:
- Windows 10 IoT ( Raspberry Pi 2 )
- 麵包板 x 1
- 杜邦線 x 2
- LED x 1
- 220歐姆電阻 x 1
本篇需使用到 BlinkyHeadless 範例,開啟 BlinkyHeadlessCS.sln。
如果沒有範例,可以參考此篇:http://www.ez2o.com/Blog/Post/Windows-10-IoT-Hello-World-Use-Raspberry-Pi-2
開啟 StartupTask.cs 檔案,此範例是背景運作方式,並沒有 UI 介面,初學者比較不容易混淆!
我已經將說明寫在以下程式內:
// Copyright (c) Microsoft. All rights reserved. using System; using Windows.ApplicationModel.Background; using Windows.Devices.Gpio; //開發需要控制 GPIO 的程式,必須要加入 using Windows.System.Threading; namespace BlinkyHeadlessCS { public sealed class StartupTask : IBackgroundTask { private BackgroundTaskDeferral deferral; private GpioPinValue value = GpioPinValue.High; private const int LED_PIN = 5; //LED 使用到的 GPIO 編號 private GpioPin pin; //某個 GPIO 針腳 private ThreadPoolTimer timer; public void Run(IBackgroundTaskInstance taskInstance) { deferral = taskInstance.GetDeferral(); InitGPIO(); //GPIO 必須初始化才能使用 timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, TimeSpan.FromMilliseconds(500)); //每 500 毫秒執行一次 Timer_Tick } private void InitGPIO() { pin = GpioController.GetDefault().OpenPin(LED_PIN); //啟用 LED_PIN 針腳 pin.Write(GpioPinValue.High); //將 LED_PIN 針腳設為 高電平 pin.SetDriveMode(GpioPinDriveMode.Output); //設定 LED_PIN 針腳為 輸出 針腳 } private void Timer_Tick(ThreadPoolTimer timer) { value = (value == GpioPinValue.High) ? GpioPinValue.Low : GpioPinValue.High; //高低 電平 互換,就會有燈號閃爍的效果 pin.Write(value); //變更 LED_PIN 針腳 高低 電平 } } }
電平分為 高 (有電) 和 低(沒電),代表的就是 1 和 0,所以當 GpioPinValue.Low 燈泡就不會亮,GpioPinValue.High 燈泡就會亮!
LED_PIN = 5 表示使用 GPIO 5 這個針腳,針腳位置如下圖 (圖片來源-微軟):
從上圖就可以知道 GPIO 5 的位置,Windows 10 IoT 的 GPIO 針腳可以為 VCC GND 皆可,官方範例將 GPIO 針腳作為 GND,與其他 Arduino , Raspberry Pi 習慣將 GPIO 針腳作為 VCC 不同。
個人習慣當設定成 SetDriveMode(GpioPinDriveMode.Output) 表示為 VCC 端,所以另外一端要接在 GND。
接線方式如下圖:
LED 的其中一端必須接上 220歐姆電阻,否則 LED 會燒掉喔!
LED 針腳比較長的是 VCC,VCC 為紅線 GND 為黑線。
※ 如果是初學者可以多買幾顆 LED 燒壞還有備用。
( GPIO 做為 VCC 的接線圖,個人比較習慣這種接法,比較直覺 GpioPinValue.High 燈泡會亮、GpioPinValue.Low 燈泡不亮 )
( GPIO 做為 GND 的接線圖,官方介紹使用,GpioPinValue.High 燈泡不亮、GpioPinValue.Low 燈泡會亮 )
GpioPinValue.High 表示為 VCC 端口,另外一端也是 VCC,所以燈泡當然不會亮!
GpioPinValue.Low 表示為 GND 端口,另外一端是 VCC,所以燈泡會亮!
※ 個人不建議這種接法,因為兩端都是 VCC 造成電路問題,另外 GpioPinValue.High 為 OFF 邏輯上不容易了解。
為什麼要接 220歐姆電阻 呢?有些人可能不知道,就跟著接吧!這樣很像也沒錯!
LED 大約是 2V 20mA ( 0.02A ) 左右,不同的 LED 會有所不同,Raspberry Pi 的 GPIO 為 3.3V,所以必定會燒掉,所以必須透過電阻。
根據歐姆定律計算: R = V / I,所以 ( 3.3V - 2V ) / 0.02A = 65歐姆,所以大於 65歐姆 皆可,但是大於太多,可能燈泡不亮或太暗!
依照以上步驟接好電路,程式就可以部署到 Windows 10 IoT 進行測試,部署方式可以參考上一篇:http://www.ez2o.com/Blog/Post/Windows-10-IoT-Hello-World-Use-Raspberry-Pi-2
接下來打開進階的 Blinky 專案 Blinky.sln。
開啟 MainPage.xaml.cs 檔案,此範例是有 UI 介面的,可以觀看螢幕上的 圓圈閃爍 和 LED閃爍。
我已經將說明寫在以下程式內:
// Copyright (c) Microsoft. All rights reserved. using System; using Windows.Devices.Gpio; //開發需要控制 GPIO 的程式,必須要加入 using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; namespace Blinky { public sealed partial class MainPage : Page { private const int LED_PIN = 5; //LED 使用到的 GPIO 編號 private GpioPin pin; //某個 GPIO 針腳 private GpioPinValue pinValue; private DispatcherTimer timer; private SolidColorBrush redBrush = new SolidColorBrush(Windows.UI.Colors.Red); //按鈕 紅色 private SolidColorBrush grayBrush = new SolidColorBrush(Windows.UI.Colors.LightGray); //按鈕 淺灰色 public MainPage() { InitializeComponent(); timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(500); timer.Tick += Timer_Tick; InitGPIO(); if (pin != null) { timer.Start(); } } private void InitGPIO() { var gpio = GpioController.GetDefault(); // Show an error if there is no GPIO controller if (gpio == null) { pin = null; GpioStatus.Text = "There is no GPIO controller on this device."; return; } pin = gpio.OpenPin(LED_PIN); //啟用 LED_PIN 針腳 pinValue = GpioPinValue.High; //預設為 高電平 pin.Write(pinValue); //變更 LED_PIN 針腳 電平 pin.SetDriveMode(GpioPinDriveMode.Output); //設定 LED_PIN 針腳為 輸出 針腳 GpioStatus.Text = "GPIO pin initialized correctly."; } private void Timer_Tick(object sender, object e) { if (pinValue == GpioPinValue.High) { pinValue = GpioPinValue.Low; //變更為 低電平 pin.Write(pinValue); //變更 LED_PIN 針腳 電平 LED.Fill = redBrush; //變更 按鈕為紅色 } else { pinValue = GpioPinValue.High; //變更為 高電平 pin.Write(pinValue); //變更 LED_PIN 針腳 電平 LED.Fill = grayBrush; //變更 按鈕為淺灰色 } } } }
一樣程式部署到 Windows 10 IoT 進行測試,結果如下圖:
使用官方範例時,使用 GPIO 作為 VCC 端口的接法 ( 我的接法 ),可以發現 ON 燈泡不亮 OFF 燈泡會亮,那是因為跟官方的 GpioPinValue.High、GpioPinValue.Low 邏輯顛倒造成的,只需要自行修改程式即可。
https://www.ez2o.com/Blog/Post/Windows-10-IoT-Blinky-Use-Raspberry-Pi-2
https://www.ez2o.com/Blog/Post/561