# Windows IoT Core Application Development: Headless Blinky

## Overview

## Headed and Headless

There are two basic types of Windows IoT Core applications: “headed” and “headless”.

“Headless” apps have no graphical user interface (GUI), and are said to run “in the background”. That is, they continue to run even when you start up a “headed” application. Also, they don’t depend on having a monitor attached to the system.

“Headed” applications have a GUI, so you need a display attached to your system in order to use them.

![](https://cdn-learn.adafruit.com/assets/assets/000/034/469/medium800/projects_CreateBlinkyHeadless.png?1469902049)

## C-Sharp (C#)

Using Visual Studio, you can program your Raspberry Pi in C# or Visual Basic (or even C++). Microsoft has unified the API (Application Programmability Interface) between C# and Visual Basic, so it’s easy to switch between them. We’ll be using C# for this tutorial (just because we like it better, and hey, it’s our tutorial anyway!).

Instructions on the C# and Visual Basic programming languages are wayyy beyond the scope of this tutorial, so we’ll assume you already know the basics.

# Windows IoT Core Application Development: Headless Blinky

## Headless Blinky

Microsoft provides the headless Blinky app as a preconfigured solution (Visual Studio is based on **solutions**. Each **solution** may contain multiple **projects**. You can compile and run each project separately). The Blinky solution contains a single Blinky project.

Rather than simply downloading Blinky and running it, we thought it would be more useful to go through the entire process of creating the Blinky solution.

Note: We'll be changing the wiring of the LED from the Microsoft version of Blinky, but otherwise it's all the same.

## Step 1: Create Solution
![](https://cdn-learn.adafruit.com/assets/assets/000/033/831/medium800/projects_Start_Page.png?1468522301)

- Start a new instance of **Visual Studio 2015**
- The Start Page will appear. Click on **New Project…**
- This will bring up the New Project window

![](https://cdn-learn.adafruit.com/assets/assets/000/033/832/medium800/projects_CreateBlinkyHeadless.png?1468522500)

- In the left-hand panel of the New Project window, navigate to **Templates \> Visual C# \> Windows \> Windows IoT Core**
- Select **Background Application (IoT)**
- Give the project a name (“BlinkyHeadless”).
- Enter a location for the **solution/project** folder. The default location is fine. Make sure the box labeled **Create directory for solution** is checked.
- Give the solution a name (“Blinky”).
- Click **OK**

A new dialog window will open, asking you to choose the target and minimum versions your Blinky app will support. Choose the target and Minimum versions to match the version of Windows IoT you have running on your Raspberry Pi. If you’re not sure, check the main HDMI display or Device Portal to check the installed version.

![](https://cdn-learn.adafruit.com/assets/assets/000/033/833/medium800/projects_Choose_Target.png?1468522640)

Click **OK** and the **Blinky Solution** will open.

In the center of the window, you’ll see the code-editing panel. In the upper right is the **Solution Explorer** panel:

![](https://cdn-learn.adafruit.com/assets/assets/000/033/834/medium800/projects_New_Blinky_Headless.png?1468522733)

The **Solution Explorer** shows that the Blinky solution contains the BlinkyHeadless project. The code window is open to the `StartupTask.cs` program file. Except for the **References** item, you can ignore the other files listed in the **Solution Explorer** for now.

## Step 2: Add IoT framework

Even though we used a Windows IoT Core template for creating our solution, we still need to add the IoT Framework to our BlinkyHeadless project. In the **Solution Explorer** , right click on the line that says **References** , and select **Add Reference…**

![](https://cdn-learn.adafruit.com/assets/assets/000/033/835/medium800/projects_Add_Reference_Menu.png?1468522802)

This will bring up the **References Manager**. In the **References Manager Window** , navigate to **Universal Windows \> Extensions**. In the list, find **Windows IoT Extensions for the UWP**. There may be more than one item with this name. To the right of each item, you’ll see a version number. Select the items that match the **Target** and **Minimum** versions you entered earlier.

When you select an item, a checkbox will appear to the left of the item. Check the box for each item you select.

![](https://cdn-learn.adafruit.com/assets/assets/000/033/836/medium800/projects_Reference_Manager.png?1468522847)

Click **OK** to add the references to your project.

# Windows IoT Core Application Development: Headless Blinky

## Program Architecture

We said we weren’t going to turn this into a C# tutorial, but a few words about the program architecture are appropriate.

Windows IoT Core applications are oriented around _tasks_. If you’re mostly familiar with Arduino or python programming, you probably aren’t too familiar with tasks. Basically, a task is a program than can run at the same time as other programs on the same computer. Arduino only allows one program at a time. Linux supports tasks, but you may not have done any task-oriented programming.

We’re not going to go into the intricacies of tasks here, but it’s worth noting that the fundamental structure of our BlinkyHeadless application is a task. You can see this from the type of the **StartupTask** class – it inherits from the **IBackgroundTask** interface class. To execute BlinkyHeadless, Windows IoT creates a new task object and uses it to call the **Run** function.

The **Run** function is where we’ll put our code.

If you’re curious, you can read more about background tasks here:

[Background Tasks: More Info](http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409)
Info: 

## Timer thread

We’re not quite done with tasks. Tasks may also be referred to as **threads** , particularly when they exist _within_ a task. One of the standard thread objects in Windows is the **Timer**. We will be using a timer to control the blinking of our LED.

If you are familiar with Arduino, you will be accustomed to using `delay()` statements to control things like blinking LEDs. The drawback of this approach is that the Arduino can’t do anything else while it is waiting for the delay to expire.

In Windows, instead of using a delay, we can start a timer thread. Once the thread is started, we can go about doing other useful things, and the timer will alert us when the period has expired. The timer does this through a `Timer Tick` event. All we need to do is to create an event function and associate it with the timer. When it’s time to turn the LED on or off, windows will automatically call our tick event function.

![](https://cdn-learn.adafruit.com/assets/assets/000/033/837/medium800/projects_TimerTick.png?1468523100)

There’s one other thing we need to do. You may have noticed a series of _using_ statements at the top of StartupTask.cs. These are similar to the C _#include_ or python _import_ statements. They identify libraries we want to refer to in our program. We need to add the threading library to the list:

![](https://cdn-learn.adafruit.com/assets/assets/000/033/838/medium800/projects_SystemThreading.png?1468523341)

Don’t worry about the _using_ statements that are grayed out – it just means that there are no references to those libraries in the code yet.

## Task deferral

There is one other thing about tasking in BlinkyHeadless, and this is subtle. When the **Run** function exits, so does our main task. That is, our BlinkyHeadless application terminates. We don’t want this to happen.

In BlinkyHeadless, we really don’t have anything else to do while we’re waiting for the timer tick event. We could add an infinite loop, but that will consume processor resources. Windows provides a better way to do the same thing, and that is a **Task Deferral**.

When we set up a deferral on a background task, such as our main task, the task won’t exit until we explicitly tell it that we’re done, even if it runs out of other things to do.

You can read more about background task deferral here:

[Task Deferral: more info](http://aka.ms/backgroundtaskdeferral)
# Windows IoT Core Application Development: Headless Blinky

## Pin I/O

Digital I/O pin operations are quite simple in Windows 10 IoT Core. Windows provides a GPIO controller object. With this object, we can select a pin, set it for input or output, and read or write the logic state of the pin.

To access a pin, we first need an instance of the _GpioController_ object. As the name suggests, the GpioController is where we go to set up GPIO pins. Once we have a reference to the GpioController, we can get a reference to a pin.

The pin reference allows us to set the pin mode to input or output, and to read or write the state of the pin.

Before we can do this, we need to add another _using_ statement, to say that we’ll be using the Windows.Devices.Gpio library.

Now we can add a little function to set up the pin 5 as an output to blink the LED.

![](https://cdn-learn.adafruit.com/assets/assets/000/033/839/medium800/projects_InitGpio.png?1468523588)

After we get the pin reference, we write the pin value to `HIGH`, and then set the mode to `output`.

The only thing left to do in BlinkyHeadless is to actually toggle the LED in `Timer_Tick.` We’ll keep track of the current state of the pin in a variable, and use that to decide whether to turn the pin to `HIGH` or `LOW`:

![](https://cdn-learn.adafruit.com/assets/assets/000/033/840/medium800/projects_FinishedTimerTick.png?1468523675)

## Pi Setup

Of course, if we want to blink a LED, we need to attach a LED to the Pi. Use something like a red LED. Connect the long leg of the LED to **GPIO 5** on the Pi. Connect a 180 Ohm resistor to the short leg of the LED, and then connect the other end of the resistor to **Ground** on the Pi.

Connected this way, the LED will light when we set the GPIO pin `HIGH`, and it will turn off when we set the GPIO pin `LOW`.

(Note: This is different from the way Microsoft has the LED arranged in their version of Blinky. &nbsp;Microsoft Blinky asks you to wire the LED between 3.3V and the GPIO pin. &nbsp;Wired that way,&nbsp;to turn the LED _on_, you have to set&nbsp;the GPIO pin to&nbsp;_low_. &nbsp;To turn the LED _off_, you have to set the GPIO pin to _high_. There are reasons for doing it this way, but it's&nbsp;kind of logically backwards).

# Windows IoT Core Application Development: Headless Blinky

## BlinkyHeadless Code

The complete `StartupTask.cs` program is shown here. In some of the earlier examples, we made some variables local, just to make it clear that they had to be of a particular type. In reality, we want those variables to be global. The final program reflects that, with `LED_PIN`, `pin`, `pinValue`, and `timer` declared as private global variables.

There are other code modules in the BlinkyHeadless project, but those are all automatically generated. &nbsp;All we need concern ourselves with is the module `StartupTask.cs`:

```auto
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Net.Http;
 using Windows.ApplicationModel.Background;
 using Windows.System.Threading;
 using Windows.Devices.Gpio;
 
 // The Background Application template is documented at http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409
 
 namespace BlinkyHeadless
 {
     public sealed class StartupTask : IBackgroundTask
     {
         BackgroundTaskDeferral _deferral;
         private const int LED_PIN = 5;
         private GpioPin pin;
         private GpioPinValue pinValue;
         private ThreadPoolTimer timer;
 
         public void Run(IBackgroundTaskInstance taskInstance)
         {
             _deferral = taskInstance.GetDeferral();

 		 InitGPIO();

             timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick,
						TimeSpan.FromMilliseconds(500));
         }
 
         private void Timer_Tick(ThreadPoolTimer timer)
         {
             if (GpioPinValue.High == pinValue)
                 pinValue = GpioPinValue.Low;
             else
                 pinValue = GpioPinValue.High;
 
             pin.Write(pinValue);
         }
 
         private void InitGPIO()
         {
             GpioController gpio = GpioController.GetDefault();
             pin = gpio.OpenPin(LED_PIN);
             pinValue = GpioPinValue.High;
             pin.Write(pinValue);
             pin.SetDriveMode(GpioPinDriveMode.Output);
         }
     }
 }

```

# Windows IoT Core Application Development: Headless Blinky

## Running BlinkyHeadless

## Remote Machine

From the Visual Studio standpoint, the Raspberry Pi is a **Remote Machine.** So, we have to make an association between Visual Studio and the remote machine. In the Visual Studio Toolbar, there should be a button labeled **Device**. On the right-hand side of this button is a little down-arrow. Click the down-arrow and a drop-down will open.

![](https://cdn-learn.adafruit.com/assets/assets/000/033/841/medium800/projects_Device.png?1468524470)

Select **Remote Machine** , and another pop-up window will open. This is the place where you find your Raspberry Pi and make the remote-machine association with Visual Studio. The Raspberry Pi should be automatically found. Click on the arrow next to **Auto Detected** to open up the panel, and click **Select**.

![](https://cdn-learn.adafruit.com/assets/assets/000/033/842/medium800/projects_RemoteConnections.png?1468524523)

If you have to do a manual configuration for some reason, enter the name of the Raspberry Pi, and select **Universal** for the **Authentication Mode**.

If you have a problem here, it’s because your Raspberry Pi isn’t visible on the network. Visual Studio can’t see it. Go back and make sure your Pi is configured correctly and is visible to **Device Portal**.

You can also get to this window by going through the **Solution Explorer**. Find the **Properties** entry in your project and double click on it. The **Project Properties** window will open. On the left of the panel, select **Debug**. In **Start Options** , select **Remote Machine** , and then click the **Find…** button.

## Run

To run your app, press the large green arrow in the toolbar in the box labeled **Remote Machine**

![](https://cdn-learn.adafruit.com/assets/assets/000/033/843/medium800/projects_Run.png?1468524601)

The app will be compiled and downloaded to the Raspberry pi, and it should begin to run. The first time you run your app, this process can take a couple of minutes. Subsequently, your app will download and run much quicker.

Click on the **green arrow** – if all goes well, the LED attached to GPIO 5 will begin to blink!

If your code has syntax errors, then the error list will appear in the panel below the main code panel. Click on the tab titled **Error List** to see the error reports. You’ll also see a red underline in the code at the point where the error was detected.

In this example, we forgot to put a semicolon at the end of line 25:

![](https://cdn-learn.adafruit.com/assets/assets/000/033/844/medium800/projects_ErrorList.png?1468524675)

Danger: 

# Windows IoT Core Application Development: Headless Blinky

## Debugging

Debugging is a large topic. We won’t go into in much detail here.

If you are accustomed to Arduino programming, then you have likely used Serial.print statements to add a debugging trace to your sketches. Visual Studio and IoT Core applications do things differently. Instead of print statements, you set _breakpoints_ in your code.

With breakpoints, you tell Visual Studio where to pause in executing your code. Once the code pauses, you can use Visual Studio to look at the values of variables. You can also single-step through your code line-byline, so that you can see the order of operations.

This form of debugging is much quicker and much more effective than using print statements.

Set a breakpoint by clicking in the gray bar to the left of the line you want to pause on:

![](https://cdn-learn.adafruit.com/assets/assets/000/033/845/medium800/projects_Breakpoint.png?1468524953)

Here, we’ve set a breakpoint on the _if_ statement in `Timer_Tick`. Visual Studio will pause the application just before we execute this line. We can then do things like look at the value of the variable `pinValue`, simply by hovering the cursor over the word `pinValue`.

We can also single step, using the debugger toolbar:

![](https://cdn-learn.adafruit.com/assets/assets/000/033/846/medium800/projects_Debugger.png?1468524989)

The stepping icons are to the right of the picture.

- The down arrow over the dot is **step into**. If there is a function call on the line, clicking this button will step into the function and pause again on the first line of the function.
- The curved arrow over the dot is **step over** this will step to the next line in the code, but won’t step into any functions called on the line.
- The up arrow over the dot is **step out**. It causes the code to proceed until the current function is exited. It will then pause again on the first line after the function call.
- Other buttons to note are the green **Continue** button, which resumes normal execution from the breakpoint . The red square will immediately terminate your app. The circular arrow will restart your app from the beginning.

## Next steps

That's pretty much it for our headless application. &nbsp;If all went well, your LED should be merrily blnking away. &nbsp;If not, help is always available in the forums!

Next, we'll go through the _Headed_ version of Blinky

[Headed Blinky](https://learn.adafruit.com/windows-iot-application-development-headed-blinky/overview)
# Windows IoT Core Application Development: Headless Blinky

## FAQ

### 

This error typically happens after you reboot your Pi. For whatever reason, Visual Studio is not longer able to communicate with it. The solution is to simply close and restart Visual Studio. Do this every time you reboot your Pi. &nbsp;


## Related Guides

- [Adafruit IO Basics: Color](https://learn.adafruit.com/adafruit-io-basics-color.md)
- [CircuitPython Libraries on Linux and Google Coral](https://learn.adafruit.com/circuitpython-on-google-coral-linux-blinka.md)
- [Single Channel LoRaWAN Gateway for Raspberry Pi](https://learn.adafruit.com/raspberry-pi-single-channel-lorawan-gateway.md)
- [Raspberry Pi Care and Troubleshooting](https://learn.adafruit.com/raspberry-pi-care-and-troubleshooting.md)
- [Adafruit IO Basics: Analog Output](https://learn.adafruit.com/adafruit-io-basics-analog-output.md)
- [CircuitPython Libraries on Linux and Raspberry Pi](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux.md)
- [Running PyPortal Code on Blinka with Displayio](https://learn.adafruit.com/running-pyportal-code-on-blinka-with-displayio.md)
- [Adafruit IO Basics: Digital Input](https://learn.adafruit.com/adafruit-io-basics-digital-input.md)
- [IoT Temperature Logger with Analog Devices ADT7410, Raspberry Pi, and Adafruit IO](https://learn.adafruit.com/iot-temperature-logger-with-python-and-adafruit-io.md)
- [CircuitPython Libraries on Linux and Orange Pi](https://learn.adafruit.com/circuitpython-on-orangepi-linux.md)
- [Adafruit IO Basics: Digital Output](https://learn.adafruit.com/adafruit-io-basics-digital-output.md)
- [LoRa and LoRaWAN Radio for Raspberry Pi](https://learn.adafruit.com/lora-and-lorawan-radio-for-raspberry-pi.md)
- [CircuitPython Libraries on Linux and the NVIDIA Jetson Nano](https://learn.adafruit.com/circuitpython-libraries-on-linux-and-the-nvidia-jetson-nano.md)
- [Adafruit IO Basics: Temperature & Humidity](https://learn.adafruit.com/adafruit-io-basics-temperature-and-humidity.md)
- [Adafruit AMG8833 8x8 Thermal Camera Sensor](https://learn.adafruit.com/adafruit-amg8833-8x8-thermal-camera-sensor.md)
