Raspberry Pi 2 a Windows 10 IoT Core

Před několika měsíci oznámila společnost Microsoft speciální edici Windows 10 pro „IoT“ projekty. Asi největší pozornost vzbudilo oznámení podpory pro Raspberry Pi 2. Minulý týden se toto oznámení stalo skutečností. Jak tedy vypadá Windows 10 na Raspberry Pi 2 a co to umí?

Jedna platforma vládne všem

Asi nejzásadnější změnu, kterou přináší Windows 10 z hlediska vývoje aplikací, je tzv. Universal Windows Platform. Zjednodušeně řečeno, jedna aplikace poběží na různém hardware a různém vydání Windows 10 (PC, telefon, Xbox, HoloLens, Raspberry Pi 2, …). Bude třeba jen zajistit, aby se aplikace uměla přizpůsobit použitému zobrazovacímu zařízení. Pro některý hardware, třeba Raspberry Pi 2, bude třeba aplikaci samozřejmě přeložit pro odpovídající procesorovou architekturu. V principu půjde ale pořád o tu stejnou aplikaci se stejnými zdrojovými kódy.

Raspberry Pi 2 a Windows 10 IoT Core

Verze Windows 10 IoT Core je určena pro minipočítače typu Raspberry Pi. V tuto chvíli je ještě k dispozici obraz pro MinnowBoard Max. Pro Intel Galileo není Windows 10 IoT Core k dispozici a asi ani nebude. Popisem instalace se zde nebudu zabývat. Je to jen stažení a překopírování obrazu systému na SD kartu. Zaměřím se na problémy, s kterými jsem se potkal a jak jsem je řešil. Přeci jen vše zatím běží na testovacích verzích operačního systému i vývojového prostředí.

  1. Chcete-li si jen Windows 10 IoT Core na Raspberry Pi 2 pustit a podívat se, jak vypadá, není nutné na počítač instalovat Visual Studio 2015 a Windows 10. Neuvidíte ale nic zajímavého. Windows 10 IoT Core nemá uživatelské rozhraní. Spravuje se přes webové rozhraní nebo Powershell nebo na něm běží vaše aplikace, která uživatelské rozhraní může mít. Pokud uživatelské rozhraní nepotřebujete, nastartujte Windows 10 IoT Core v „headless“ módu.
    image1image2
  1. Pokud vám nejde spustit aplikace Windows IoT Core Watcher, která zobrazuje IP adresy Windows 10 IoT Core zařízení v sítí, tak vyzkoušejte vynutit spuštění aplikace v 32-bit režimu. Mně to pomohlo. Pokud IP adresu nebo jméno zařízení znáte, tak tuto aplikaci nepotřebujete.
    image3
  1. Pro první start doporučuji Raspberry Pi 2 připojit k monitoru, abyste věděli, co se děje. První start trvá vcelku dlouho a dojde k jednomu restartu. Na obrazovce pak uvidíte informaci o připojení k síti a základní možnosti nastavení. Stačí mít připojenou klávesnici a myš. Mně se osvědčila klávesnice s touchpad Logitech K400. Funguje i s Raspberry Pi a Linuxem.

Vývoj aplikací

Pro vývoj aplikací potřebujete Windows 10 a Visual Studio 2015. Obojí je v tuto chvíli (květen 2015) v testovacích verzích, proto počítejte, že ne vždy bude vše fungovat, jak by mělo. Pokud chcete vytvořit aplikaci, která má uživatelské rozhraní a nepotřebuje pracovat s GPIO, tak vytvoříte Windows Universal aplikaci, kterou můžete komplet odladit na normálním počítači.

image4

GPIO, I2C, SPI

Pro práci s GPIO, I2C a SPI stačí použít příslušné objekty ze jmenných prostorů Windows.Devices.Gpio, Windows.Devices.I2c a Windows.Devices.Spi. To se může samozřejmě u finální verze změnit. V kódu je třeba otestovat, zda dané periférie (GPIO, I2C, SPI) zařízení podporuje. Typ projektu, Windows Universal, se nemění. Nezapomeňte přidat referenci na Windows IoT Extension SDK.

image5

Ukázková aplikace

Na několika přednáškách v poslední době jsem při ukázkách I2C sběrnice použil maticový LED displej 8×8. Pokud chcete na tomto displeji udělat obrázek, tak musíte pro každý řádek připravit správnou kombinaci jedniček a nul. Co řádek, to jeden byte. Jednotlivé bity představují jednotlivé LED, sloupce. Bohužel jsou sloupce zpřeházené, takže udělat pěkný obrázek chvilku trvá. Ukázková aplikace zobrazí na obrazovce jednotlivé LED z matice a myší je budeme rozsvěcet a zhasínat. Výsledek rovnou uvidíme na připojeném displeji pro kontrolu a na obrazovce uvidíme hodnoty pro jednotlivé řádky. Aplikaci lze spustit i na normálním počítači nebo telefonu.

image6

image8

Zdrojový kód

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;

using Windows.Devices.I2c;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
using Windows.Devices.Enumeration;


namespace GPIO101
{
    public sealed partial class MainPage : Page
    {
        private const int MATRIX_SIZE = 8;

        private SolidColorBrush _on = new SolidColorBrush(Colors.Red);
        private SolidColorBrush _off = new SolidColorBrush(Colors.White);

        private TextBlock[] _matrixRowValue = new TextBlock[MATRIX_SIZE];

        private byte[,] _matrixData = new byte[MATRIX_SIZE, MATRIX_SIZE];

        // I2C zařízení
        private I2cDevice _matrixDevice = null;

        public MainPage()
        {
            this.InitializeComponent();

            initLedMatrixDevice();

            for (int i = 0; i < MATRIX_SIZE; i++)
            {
                TextBlock tb = new TextBlock();
                tb.Text = "0x00";
                tb.HorizontalAlignment = HorizontalAlignment.Center;
                tb.VerticalAlignment = VerticalAlignment.Center;
                tb.SetValue(Grid.RowProperty, i);
                tb.SetValue(Grid.ColumnProperty, MATRIX_SIZE);
                _matrix.Children.Add(tb);

                _matrixRowValue[i] = tb;

                for (int j = 0; j < MATRIX_SIZE; j++)
                {
                    Ellipse led = new Ellipse();
                    led.Width = 40;
                    led.Height = 40;
                    led.HorizontalAlignment = HorizontalAlignment.Center;
                    led.VerticalAlignment = VerticalAlignment.Center;
                    led.Fill = _off;
                    led.SetValue(Grid.RowProperty, i);
                    led.SetValue(Grid.ColumnProperty, j);
                    led.PointerPressed += Led_PointerPressed;
                    _matrix.Children.Add(led);

                    setMatrixData(i, j, 0);
                }
            }
        }

        // viz http://robodoupe.cz/2013/maticovy-displej-8x8/
        private void setMatrixData(int row, int column, byte state)
        {
            column = (column + 7) & 7;
            _matrixData[row, column] = state;

            byte rowData = 0x00;

            for (int i = 0; i < MATRIX_SIZE; i++)
            {
                rowData |= (byte)(_matrixData[row, i] << (byte)i);
            }

            _matrixRowValue[row].Text = String.Format("0x{0:X2}", rowData);


            if (_matrixDevice == null)
            {
                return;
            }

            _matrixDevice.Write(new byte[] { (byte)(row*2), rowData });
        }

        private void Led_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            Ellipse led = (Ellipse)sender;

            if (led.Fill == _off)
            {
                led.Fill = _on;
                setMatrixData((int)led.GetValue(Grid.RowProperty),
                    (int)led.GetValue(Grid.ColumnProperty),
                    0x01);
            }
            else
            {
                led.Fill = _off;
                setMatrixData((int)led.GetValue(Grid.RowProperty),
                    (int)led.GetValue(Grid.ColumnProperty),
                    0x00);
            }
        }

        private async void initLedMatrixDevice()
        {
            try
            {
                // Nastavení I2C sběrnice
                I2cConnectionSettings settings = new I2cConnectionSettings(0x70);
                settings.BusSpeed = I2cBusSpeed.StandardMode;

                string aqs = I2cDevice.GetDeviceSelector("I2C1");
                var dis = await DeviceInformation.FindAllAsync(aqs);
                _matrixDevice = await I2cDevice.FromIdAsync(dis[0].Id, settings);

                // inicializace displeje
                _matrixDevice.Write(new byte[] { 0x21 });
                _matrixDevice.Write(new byte[] { 0x81 });

                // zhasnutí všech LED
                for (int i = 0; i < (MATRIX_SIZE * 2); i = i + 2)
                {
                    _matrixDevice.Write(new byte[] { (byte)i, 0x00 });
                }
            }
            catch
            {
                _matrixDevice = null;
            }
        }
    }
}

Nasazení a spuštění aplikace

Oboje se odehrává pomocí Remote Debugger, který je automaticky k dispozici na Windows 10 IoT Core. Stačí nastavit Visual Studio.

image9

V mém případě bohužel nefungovalo vyhledání zařízení pomocí tlačítka Find… Musel jsem připojení nakonfigurovat ručně.

Aplikace se v Debug módu chová stejně, jako kdyby byla spuštěna na lokálním počítači. Pro nasazení aplikace stačí přepnout na Release a z nabídky Build vybrat Deploy Solution. Aplikaci můžete také nasadit a spustit přes webové rozhraní.

image10

Co si o tom myslím

Následující řádky budou zcela subjektivní, založené na aktuálních informacích a krátké zkušenosti s kombinací Raspberry Pi 2 a Windows 10 IoT Core.

S Raspberry Pi jsem již realizoval několik krátkodobých projektů. Asi největší problém, který s Raspberry Pi mám, a je jedno, jaký je tam operační systém, je energetická náročnost. Bez napájení ze sítě se v podstatě neobejdete.

Asi největší rozdíl mezi Windows 10 IoT Core a Linux distribucemi pro Raspberry Pi je chybějící uživatelské rozhraní na Windows 10 IoT Core. To by na druhou stranu mohlo ukazovat na jednodušší, a tedy i spolehlivější, systém pro dlouhodobé provozování. Čím méně věcí tam běží, tím se toho může méně rozbít.

Pro .NET vývojáře a správce Windows sítí může být Windows 10 IoT Core vstupem do světa malých počítačů a GPIO.

Kde vidím využití

Kombinace Raspberry Pi 2 a Windows 10 IoT Core je podle mě geniální v situaci, kdy mám hotovou aplikaci pro Windows Phone nebo tablet s Windows a chci umožnit její provozování na „statickém“ místě. Představte si, že máte aplikaci pro orientaci v obchodním centru pro mobilní telefon. Tu samou aplikaci, s minimem úprav, pak spustíte na Raspberry Pi 2 na informačním kiosku přímo v obchodním centru. Tato kombinace by také mohla v některých situacích nahradit Windows Embedded, např. v bankomatech.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 11

Přehled komentářů

DawidFerenczy Grafické prostředí a spotřeba
vaclav.sir Re: Grafické prostředí a spotřeba
sýrař Re: Grafické prostředí a spotřeba
Zephir Re: Grafické prostředí a spotřeba
Kaacz Re: Grafické prostředí a spotřeba
Kaacz Re: Grafické prostředí a spotřeba
Kaacz Re: Grafické prostředí a spotřeba
Milan Programátoři s páječkou :D
Petr Umlauf pouziti Raspberry jako informacni kiosek nebo bankomat
Štěpán Bechynský Re: pouziti Raspberry jako informacni kiosek nebo bankomat
Štěpán Bechynský Re: pouziti Raspberry jako informacni kiosek nebo bankomat
Zdroj: https://www.zdrojak.cz/?p=14831