PI-windows10iot1.jpg




See what can be done in only a few hours of learning:-

P1010592.JPG


Hi everyone, there has been a lot of speculation as to the functionality of Windows 10 on the PI2

 

This has focused initially on the fact it wont have a GUI display and be well rather none eventful

 

Well I have been playing around with this for the last couple of days and I have to say

 

HOW WRONG THAT THOUGHT IS !, see the above image and read on to see how I did it


The Windows 10 for IOT on the Raspberry PI does not have a GUI console sure. BUT it does have a GUI display, just waiting to be tapped into

 

In this post I will take you through basic setup of the PC and the PI, getting Windows 10 Technical preview to talk to the PI and also using Visual Studio 2015 Community Edition up and running with your first apps


So what do you need


1.    A Raspberry PI 2 of course

2.    Download the Raspberry PI Windows 10 IoT software from Microsoft:- https://insider.windows.com/ you will need to register as an insider to get the download

3.    Setup the image on the SD card as described in my video and based on these instructions:- Windows IoT - SetupBoard

4.    In order to setup the PI you will need to be running windows 10, this can be downloaded from here:- Download Windows 10 Insider Preview ISO - Microsoft Windows

5.    In order to setup windows boot you will need the above image put onto a bootable media, either a USB key or CD rom. I had to use RUFUS to get the image to work with my Tablet due to its EUFI bios. The windows 7 USB imager would not work.

6.    Once you have the image running on the PI then you will see a screen like this

P1010590.JPG

You will notice that it shows you the IP Address and time zone your in. It may take as much as 5 minutes to get this booted up the first time so be patient.


Now lets get some coding done

 

 

There are loads of examples available on GitHub

https://github.com/Microsoft/Windows-universal-samples

https://github.com/ms-iot/samples


I took two examples from the samples on github, the "Hello World" here: https://github.com/ms-iot/samples/tree/develop/HelloWorld/CS and the "Potentiometer Sensor" from here: https://github.com/ms-iot/samples/tree/develop/PotentiometerSensor/CS, fixing them as described in the video (There are issues with the dependencies and it was easier to create new projects with the same names and copy the primary content over.


The Hello World I left as is with the exception of copying over the core code into the new project. The Potentiometer Code I changed screen layout by extending it to display all 8 channels of ADC on the PI HDMI screen and added a software LED to the GUI. This included extending the code behind to handle all the additional channels.


here is the hello world code (Only from the significant two files MainPage.XAML and MainPage.XAML.CS

<Page
    x:Class="HelloWorld.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWorld"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">


    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox x:Name="HelloMessage" Text="Hello, World!" Margin="10" IsReadOnly="True"/>
            <Button x:Name="ClickMe" Content="Click Me!"  Margin="10" HorizontalAlignment="Center" Click="ClickMe_Click"/>
        </StackPanel>
    </Grid>
</Page>







and the code behind

/*
    Copyright(c) Microsoft Open Technologies, Inc. All rights reserved.


    The MIT License(MIT)


    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files(the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions :


    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.


    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
*/


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;


// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409


namespace HelloWorld
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            InitializeComponent();
        }


        private void ClickMe_Click(object sender, RoutedEventArgs e)
        {
            HelloMessage.Text = "Hello, Windows 10 IoT Core!";
        }
    }
}







 

there are many other files in the folder that are basic plumming for the program but this is the custom part. he rest is created automatically when the project is created

 

This is the extended files for the potentiometer Sensor Project and the corrected breadboard schematic for the LED wiring

P1010586.JPGPI_WINDOWS_10_ADC.png

<Page
    x:Class="PotentiometerSensor.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PotentiometerSensor"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:igCA="http://infragistics.com/Chart"
>
    <Grid  VerticalAlignment="Center" HorizontalAlignment="Center">
        <Border BorderBrush="BlanchedAlmond" CornerRadius="6"  BorderThickness="4" HorizontalAlignment="Left" VerticalAlignment="Top">
    <Grid Background="Silver" >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Grid.Row="0" HorizontalAlignment="Center">
            <Image Source="Assets\Breadboard.jpg"  Height="200" Stretch="Uniform"  />
        </StackPanel>
                <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
                    <Ellipse x:Name="LED" Fill="LightGray" Stroke="White" Width="30" Height="30" Margin="5"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Center">
            <TextBlock x:Name="GpioStatus" Text="Waiting for GPIO to be initialized" Margin="10,30,10,10" TextAlignment="Center"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch0: " TextAlignment="Left" />
            <TextBlock x:Name="textPlaceHolder0" Text="Show Values 0 Here" TextAlignment="Right"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="4" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch1: "  TextAlignment="Left" />
            <TextBlock x:Name="textPlaceHolder1" Text="Show Values 1 Here"  TextAlignment="Right"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="5" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch2: "  TextAlignment="Left" />
            <TextBlock x:Name="textPlaceHolder2" Text="Show Values 2 Here" TextAlignment="Right" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="6" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch3: "  TextAlignment="Left" />
            <TextBlock x:Name="textPlaceHolder3" Text="Show Values 3 Here"  TextAlignment="Right"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="7" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch4: "  TextAlignment="Left"  />
            <TextBlock x:Name="textPlaceHolder4" Text="Show Values 4 Here"  TextAlignment="Right"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="8" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch5: "  TextAlignment="Left" />
            <TextBlock x:Name="textPlaceHolder5" Text="Show Values 5 Here"  TextAlignment="Right"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="9" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch6: "  TextAlignment="Left" />
            <TextBlock x:Name="textPlaceHolder6" Text="Show Values 6 Here"  TextAlignment="Right"  />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="10" HorizontalAlignment="Center">
            <TextBlock Text=" ADC Ch7: "  TextAlignment="Left"  />
            <TextBlock x:Name="textPlaceHolder7" Text="Show Values 7 Here"  TextAlignment="Right"  />
        </StackPanel>
    </Grid>
    </Border>
    </Grid>
</Page>







 

And the code for this project

/*
    Copyright(c) Microsoft Open Technologies, Inc. All rights reserved.
    The MIT License(MIT)
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files(the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions :
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Gpio;
using Windows.Devices.Spi;
using Windows.Devices.Enumeration;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace PotentiometerSensor
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(500);
            timer.Tick += Timer_Tick;
            timer.Start();

            InitSPI();
            InitGpio();
        }

        private async void InitSPI()
        {
            try
            {
                var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE);
                settings.ClockFrequency = 500000;// 10000000;
                settings.Mode = SpiMode.Mode0; //Mode3;


                string spiAqs = SpiDevice.GetDeviceSelector(SPI_CONTROLLER_NAME);
                var deviceInfo = await DeviceInformation.FindAllAsync(spiAqs);
                SpiDisplay = await SpiDevice.FromIdAsync(deviceInfo[0].Id, settings);
            }

            /* If initialization fails, display the exception and stop running */
            catch (Exception ex)
            {
                throw new Exception("SPI Initialization Failed", ex);
            }
        }
        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);

            // Show an error if the pin wasn't initialized properly
            if (pin == null)
            {
                GpioStatus.Text = "There were problems initializing the GPIO pin.";
                return;
            }
            pin.SetDriveMode(GpioPinDriveMode.Output);
            pin.Write(GpioPinValue.High);
            pin.Write(GpioPinValue.Low);
            pin.Write(GpioPinValue.High);

            GpioStatus.Text = "GPIO pin initialized correctly.";
        }
        private void LightLED()
        {
            /*Uncomment if you are using mcp3208/3008*/
            if (res0 > 2048)
            {
                pin.Write(GpioPinValue.Low);
                LED.Fill = grayBrush;
            }
            else
            {
                pin.Write(GpioPinValue.High);
                LED.Fill = redBrush;
            }

            /*Uncomment if you are using mcp3002*/


            //if (res > 1024 / 2)
          // {
          //    pin.Write(GpioPinValue.Low);
          // }
            //else
            //{
            //    pin.Write(GpioPinValue.High);
            //}
        }
        private void Timer_Tick(object sender, object e)
        {
            DisplayTextBoxContents();
            LightLED();
        }

        public void DisplayTextBoxContents()
        {
            writeBuffer[0] = 0x06; // set to channel 1
            writeBuffer[1] = 0x00; // set to channel 1
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res0 = convertToInt(readBuffer);
            writeBuffer[1] = 0x40; // set to channel 1
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res1 = convertToInt(readBuffer);
            writeBuffer[1] = 0x80; // set to channel 2
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res2 = convertToInt(readBuffer);
            writeBuffer[1] = 0xc0; // set to channel 2
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res3 = convertToInt(readBuffer);
            writeBuffer[0] = 0x07; // set to channel 1
            writeBuffer[1] = 0x00; // set to channel 1
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res4 = convertToInt(readBuffer);
            writeBuffer[1] = 0x40; // set to channel 1
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res5 = convertToInt(readBuffer);
            writeBuffer[1] = 0x80; // set to channel 2
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res6 = convertToInt(readBuffer);
            writeBuffer[1] = 0xc0; // set to channel 2
            SpiDisplay.TransferFullDuplex(writeBuffer, readBuffer);
            res7 = convertToInt(readBuffer);
            textPlaceHolder0.Text = res0.ToString();
            textPlaceHolder1.Text = res1.ToString();
            textPlaceHolder2.Text = res2.ToString();
            textPlaceHolder3.Text = res3.ToString();
            textPlaceHolder4.Text = res4.ToString();
            textPlaceHolder5.Text = res5.ToString();
            textPlaceHolder6.Text = res6.ToString();
            textPlaceHolder7.Text = res7.ToString();

        }
        public int convertToInt(byte[] data)
        {
            /*Uncomment if you are using mcp3208/3008 which is 12 bits output */
     
            int result = data[1] & 0x0F;
            result <<= 8;
            result += data[2];
            return result;

            /*Uncomment if you are using mcp3002*/
/*            int result = data[0] & 0x03;
            result <<= 8;
            result += data[1];
            return result;
*/
        }

        private int LEDStatus = 0;
        private const int LED_PIN = 6;
        private GpioPin pin;

        /*RaspBerry Pi2  Parameters*/
        private const string SPI_CONTROLLER_NAME = "SPI0";  /* For Raspberry Pi 2, use SPI0                            */
        private const Int32 SPI_CHIP_SELECT_LINE = 0;      /* Line 0 maps to physical pin number 24 on the Rpi2        */

        /*Uncomment if you are using mcp3208/3008 which is 12 bits output */

        byte[] readBuffer = new byte[3]; /*this is defined to hold the output data*/
        byte[] writeBuffer = new byte[3] { 0x06, 0x00, 0x00 };//00000110 00; // It is SPI port serial input pin, and is used to load channel configuration data into the device

        /*Uncomment if you are using mcp3002*/
        //byte[] readBuffer = new byte[3]; /*this is defined to hold the output data*/
        //byte[] writeBuffer = new byte[3] { 0x68, 0x00, 0x00 };//01101000 00; /* It is SPI port serial input pin, and is used to load channel configuration data into the device*/


        private SpiDevice SpiDisplay;
        private SolidColorBrush redBrush = new SolidColorBrush(Windows.UI.Colors.Red);
        private SolidColorBrush grayBrush = new SolidColorBrush(Windows.UI.Colors.LightGray);

        // create a timer
        private DispatcherTimer timer;
        int res0;
        int res1;
        int res2;
        int res3;
        int res4;
        int res5;
        int res6;
        int res7;
    }
}







this is a list of the other files in the folder

GITHUB Studio 2015 4.png

 

For an explanation of the code, watch the following video

 

So as you will see, it is quite possible to create a full GUI application on the Raspberry PI 2 with Windwos 10 IoT. Now go create your own and share.

 

Oh, a few points to remember,

 

When entering the Remote PI connection details in Visual Studio, dont forget the default is to use a windows authentication but the PI has this OFF by default so you will need to change the setting when entering the PI address.

The programs from GitHub may not work out of the BOX due to some dependencies that fail on compile. Easy way arround this is to copy the contents of MainPage.XML and MainPage.XAML.CS to a new project of the same name

You dont get a GUI COnsole but you do get a GUI for your apps.