Thursday, June 11, 2015

Win 10 IoT on RPi 2: Simple C++ Code to Control an LED via a RadioButton

Microsoft's sample documentation for Windows IoT on the Raspberry Pi 2 includes a C# example that shows how to use a timer to blink an LED (called Blinky).  To get started with Windows 10 IoT Core and Windows Universal applications, I wanted to try something even simpler. I also wanted to use C++.  Below is a very minimal example that shows how to use a XAML RadioButton to turn an LED off and on.

This example assumes that you have Windows 10 IoT Core set up already and have configured Visual Studio to work with your device. This is covered in the MS getting started documentation.  For what it's worth, I'm using the preview version of Visual Studio 2015 installed on a Windows 10 preview VM running under Parallels on my Mac.

Connections


For this example, connect the LED's anode (positive pin/longer pin) with an appropriate resister to the RPi's 3.3V and the cathode (negative/shorter pin) to the the RPi 2's GPIO 5 pin. Setting pin 5 to high will turn off the LED and setting it to low will turn it on.

Add Reference to Visual Studio Project


You will need to add the reference to the Windows IoT Extension SDK to be able to use GPIO.  In the Solution Explorer,  right click on References and select "Add Reference."  Under Windows Universal, click on "Extensions."  Check the box for the "Windows IoT Extension SDK."  Note that you have to mouse over the entry in the list to see the checkbox.

All of the code below assumes a project named LEDOnOff.  


XAML File (MainPage.xaml)


<Page
    x:Class="LEDOnOff.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:LEDOnOff"
    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 Width="200" Height="200">
            <RadioButton x:Name="OnRadioBtn" GroupName="OnOffRadioBtnGroup" 
                         FontSize="21" FontWeight="Bold" Content="On" 
                         Click="OnRadioBtn_Checked">
            </RadioButton>
            <!-- Off button is selected to start -->
            <RadioButton x:Name="OffRadioBtn" GroupName="OnOffRadioBtnGroup" 
                         FontSize="21" FontWeight="Bold" Content="Off"
                         IsChecked="True" Click="OffRadioBtn_Checked"> 
            </RadioButton>
            <TextBlock x:Name="SwitchStatus" FontSize="27"  Margin="3" />
        </StackPanel>
    </Grid>
</Page>   


Header File (MainPage.xaml.h)


#include "MainPage.g.h"


namespace LEDOnOff
{
  public ref class MainPage sealed
  {
    public:
      MainPage();

    private:
      Windows::Devices::Gpio::GpioPinValue pinValue;
      // Connect LED cathode/ground to RPi GPIO pin 5
      const int LED_PIN = 5;
      // Handle providing access to pin
      Windows::Devices::Gpio::GpioPin^ pin;

      void MainPage::InitGPIO();
      // Event handlers called when on/off radio button is checked
      void OnRadioBtn_Checked(Platform::Object^ sender,
           Windows::UI::Xaml::RoutedEventArgs^ e);
      void OffRadioBtn_Checked(Platform::Object^ sender,
           Windows::UI::Xaml::RoutedEventArgs^ e);
  };

}

C++ Code File (MainPage.xaml.cpp)


#include "pch.h"
#include "MainPage.xaml.h"

using namespace LEDOnOff;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::Devices::Enumeration;
using namespace Windows::Devices::Gpio;

MainPage::MainPage()
{
  InitializeComponent();
  InitGPIO();
}

void MainPage::InitGPIO()
{
  auto gpio = GpioController::GetDefault();

  if(gpio == nullptr)
  {
    pin = nullptr;
    SwitchStatus->Text = "No GPIO controller on this device.";
    return;
  }
  // I have dropped the trailing _ on member var pin
  pin = gpio->OpenPin(LED_PIN);
  // Set pin direction to output
  pin->SetDriveMode(GpioPinDriveMode::Output);
  // Set pin to High to turn LED off to start.
  pin->Write(GpioPinValue::High);
  // Set status message
  SwitchStatus->Text = "Switch is Off.";
}

// Event handler to turn LED on when On is clicked
void LEDOnOff::MainPage::OnRadioBtn_Checked(Platform::Object^ sender
  Windows::UI::Xaml::RoutedEventArgs^ e)
{
  // Shows how to access button content
  SwitchStatus->Text = "Switch is " + OnRadioBtn->Content + ".";
  // Setting GPIO 5 to low allows current through
  pin->Write(GpioPinValue::Low);
}

void LEDOnOff::MainPage::OffRadioBtn_Checked(Platform::Object^ sender,
  Windows::UI::Xaml::RoutedEventArgs^ e)
{
  SwitchStatus->Text = "Switch is " + OffRadioBtn->Content;
  // Setting GPIO 5 to high blocks current
  pin->Write(GpioPinValue::High);
}


Additional Notes:


  • Remember to set architecture to ARM via the dropdown near the top of the Visual Studio window.  
  • You won't be able to test/debug a program that uses GPIO on your local development computer.
  • You may need to set the computer name for your RPi running Win 10 IoT in the Debugging section of the project's properties. This should match the device name that shows on the screen for your RPi after it boots. 
  • Make sure that authentication is turned off in the project's debugger settings.
  • So far, I have only run the code via the debugger. I haven't deployed the application as the starter on my RPi 2. 


Tuesday, April 7, 2015

gcc-4.9 & g++-4.9 for the Raspberry Pi (C/C++ 11 & 14 Support)

I haven't done any posting here for a while, but I found information good information about installing newer versions of the GCC compilers with support for C11/C++11 and C++14:

Solarian Programmer -Raspberry Pi - Install GCC 4.9 and compile C++14 programs  (posted by Sol on 01/13/2015).