Přejít k navigační liště

Zdroják » Různé » Raspberry Pi 2 a Windows 10 IoT Core

Raspberry Pi 2 a Windows 10 IoT Core

Články Různé

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í?

Nálepky:

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.

Komentáře

Subscribe
Upozornit na
guest
11 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
DawidFerenczy

Jen dvě drobná poznámky: grafické uživatelské prostředí (neboli grafický shell) mají linuxové distribuce jen, když si jej uživatel nainstaluje, rozhodně to není integrální součást Linuxu. Hrál jsem si na Raspberry Pi i s grafickým shellem, ale jinak jej provozuji bez něj.

A k energetické náročnosti – těch 3 až 5 W snad není zase tak moc. Smartphony mají řádově větší spotřebu a myslím, že je nikdo neprovozuje s prodlužkou ze zásuvky ;) Rozhodně Raspberry Pi (a podobné klony) mají ze všech mikro-počítačových platforem nejmenší spotřebu. Pokud je to stále moc, používá se většinou Arduino, příp. ještě menší SoC, ale to už je samozřejmě jinde s výkonem a možnostmi.

vaclav.sir

Řádově? Můj smartphone má baterku s kapacitou v jednotkách watt-hodin. Kdyby měl řádově větší spotřebu, než jednotky wattů, to by moc dlouho nevydržel…

sýrař

Chtělo by se to maličko doučit z fyziky. Případně základů elektrotechniky. A pak až mluvit.

Zephir

Co je to za XXXX odpověď? Buďto máte nějakou konkrétní námitku, nebo si skovte podobný pindy na koledu.

Kaacz

@Zephir: A to bylo na koho? Buď tu kulhá řazení příspěvků .. nebo nechápu. Prvotní příspěvek je konkrétní až dost ..

Kaacz

@vaclav.sir: smartfoun má kapacitu v Ah ne Wh. Li-Pol baterie mají 3.7V.
Pravdou je, že při odběru 4W a standardní baterii ~3000mAh .. by R-pi nejelo ani 3 hodiny .. :)
Smartfouny jsou i při větším výkonu úspornější než R-pi. Pokud makají a nemají zapnutý displej.

Kaacz

: ne, smartfouny nemají řádově větší spotřebu. Ba naopak. Na smartfoun baterce vám R-pi nevydrží ani 4 hodiny. A už vůbec na R-pi neuděláte nízkou spotřebu jako umí Linux smartfoun v idle šetřícím režimu (nic není zcela zastaveno! Multitask Linux) – 9mA při 3.7V = 0.0333W! jako udělá Nokia N9 (ano, je to jen jednojádro. Na BB-Z30 s dualcore 1.6GHz se v šetřícím běžícím režimu dostanu na 16mA =0.06W. Tak kde je s příkonem R-pi?? To je sakra skoro o 2 řády .. a opačně než tvrdíte. :)

Milan

Pánové, co to plancete, že kapacita akumulátoru se neudává ve Wh (watt-hodina). Právě Wh je jediný relevantní údaj o tom, kolik se do akumulátoru vleze energie. Ah udávají údaj kolik ampérů může akumulátor dodat během jedné hodiny. Ale co když má ten akumulátor 11,1V a ne jenom 3,7V? Ah jsou relevantní údaj pro max vybíjecí proud a max nabíjecí proud a slouží JEN A POUZE PRO VÝPOČET KAPACITY.

A chtěl bych vidět smartphone, který žere 5W. Klasický akumulátor 2000mAh má 7,4Wh -> 5W smartphone by ten akumulátor vybil za hodinu a půl. I kdyby mělo RPi spotřebu jenom 1W, stále je nepoužitelné při provozu na akumulátory – ledaže byste ho používali jako mobil, ale to je trochu nepraktické, vzhledem k tomu, že RPi je předurčeno pro Embedded systémy.

Petr Umlauf

Dobry den.
Zaujal me vas nazor na pouziti Raspi jako informacniho kiosku nebo bankomatu. Nerozumim vyhody pouziti, kdyz pro zobrazeni potrebuji jeste jedno zarizeni s grafickym vystupem, ktere by pres web zobrazilo vystup z aplikace nahrane na raspi v windows 10…. ?
diky za odpoved.

Petr

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.