Windows 10 IoT 燈泡閃爍 Blinky 範例 ( Raspberry Pi 2 ) Windows 10 IoT 燈泡閃爍 Blinky 範例 ( Raspberry Pi 2 )
  .NET 、   Raspberry Pi 、   Windows 10 IoT 、   物聯網       ez      2015-08-21

上一篇介紹了 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 邏輯顛倒造成的,只需要自行修改程式即可。


標籤:   .NET 、   Raspberry Pi 、   Windows 10 IoT 、   實戰 、   物聯網

我要留言