{{announcement.body}}
{{announcement.title}}

Building an ASP.NET Core ''Hello, Blinky'' IoT Application

DZone 's Guide to

Building an ASP.NET Core ''Hello, Blinky'' IoT Application

Learn more about building an ASP.NET Core IoT application with Blinky!

· IoT Zone ·
Free Resource

After installing ASP.NET Core 3.0 on Windows 10 IoT Core and getting my ASP.NET Core 3.0 LED controlling application to work, I wanted to finish this journey with some classics — Hello, Blinky application.

Source code for ASP.NET Core "Hello, Blinky" is available in my GitHub repository gpeipman/AspNetCoreHelloBlinky. Feel free to explore the code and make it work on your board.

Controlling LED With ASP.NET Core 3.0

Turning LED on and off was actually a simple thing to do. I took the code from the LED blink example of .NET Core IoT libraries and made it work with ASP.NET Core 3.0.

The wiring is shown here. It's same as for .NET Core IoT libraries samples and credits for diagram go to their guys.

Here's my LED controlling client.

public class LedClient : IDisposable
{
    private const int LedPin = 17;
 
    private GpioController _controller = new GpioController();
    private bool disposedValue = false;
    private object _locker = new object();
 
    public LedClient()
    {
        _controller.OpenPin(LedPin, PinMode.Output);
        _controller.Write(LedPin, PinValue.Low);
 
        IsLedOn = false;
    }
 
    public bool IsLedOn { get; private set; }
 
    public void LedOn()
    {
        lock (_locker)
        {
            _controller.Write(LedPin, PinValue.High);
 
            IsLedOn = true;
        }
    }
 
    public void LedOff()
    {
        lock (_locker)
        {
            _controller.Write(LedPin, PinValue.Low);
 
            IsLedOn = false;
        }
    }       
        
    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                _controller.Dispose();
            }
 
            disposedValue = true;
        }
    }
 
    public void Dispose()
    {
        Dispose(true);
    }
}


It's a small class that is injected into ASP.NET Core controllers as a singleton. It holds an internal instance of GpioControllerLedOn() and LedOff() methods switch the LED on or off.

Getting ASP.NET Core "Hello, Blinky" Alive

Blinking LED was a little bit more challenging of a task because I needed to wind up some code that blinks LED automatically while the control goes back to the ASP.NET Core web application.

I decided to write client class for "Hello, Blinky" and use Task to keep LED blinking.

public class LedBlinkClient : IDisposable
{
    private const int LedPin = 17;
    private const int LightTimeInMilliseconds = 1000;
    private const int DimTimeInMilliseconds = 200;
 
    private bool disposedValue = false;
    private object _locker = new object();
    private bool _isBlinking = false;
 
    private Task _blinkTask;
    private CancellationTokenSource _tokenSource;
    private CancellationToken _token;
 
    public void StartBlinking()
    {
        if(_blinkTask != null)
        {
            return;
        }
 
        lock (_locker)
        {
            if(_blinkTask != null)
            {
                return;
            }
 
            _tokenSource = new CancellationTokenSource();
            _token = _tokenSource.Token;
 
            _blinkTask = new Task(() =>
            {
                using (var controller = new GpioController())
                {
                    controller.OpenPin(LedPin, PinMode.Output);
 
                    _isBlinking = true;
 
                    while (true)
                    {
                        if (_token.IsCancellationRequested)
                        {
                            break;
                        }
 
                        controller.Write(LedPin, PinValue.High);
                        Thread.Sleep(LightTimeInMilliseconds);
                        controller.Write(LedPin, PinValue.Low);
                        Thread.Sleep(DimTimeInMilliseconds);
                    }
 
                    _isBlinking = false;
                }
            });
            _blinkTask.Start();                
        }
    }
 
    public void StopBlinking()
    {
        if(_blinkTask == null)
        {
            return;
        }
 
        lock (_locker)
        {
            if(_blinkTask == null)
            {
                return;
            }
 
            _tokenSource.Cancel();
            _blinkTask.Wait();
            _isBlinking = false;
 
            _tokenSource.Dispose();
            _blinkTask.Dispose();
 
            _tokenSource = null;
            _blinkTask = null;
        }
    }
 
    public bool IsBlinking
    {
        get { return _isBlinking; }
    }
 
    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                StopBlinking();                    
            }
 
            disposedValue = true;
        }
    }
 
    public void Dispose()
    {
        Dispose(true);
    }
}


Before we can try out "Hello, Blinky," we have to make some changes to the web application.

In ConfigureServices() of the Startup class, we have to register LedBlinkClient as a singleton.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
 
    services.AddSingleton<LedBlinkClient>();
}


We need to inject LedBlinkClient to HomeController and create actions to start and stop blinking.

public class HomeController : Controller
{
    private readonly LedBlinkClient _blinkClient;
 
    public HomeController(LedBlinkClient blinkClient)
    {
        _blinkClient = blinkClient;
    }
 
    public IActionResult Index()
    {
        ViewBag.BlinkState = _blinkClient.IsBlinking ? "Blinking" : "Not blinking";
 
        return View();
    }
 
    public IActionResult StartBlinking()
    {
        _blinkClient.StartBlinking();
 
        return RedirectToAction(nameof(Index));
    }
 
    public IActionResult StopBlinking()
    {
        _blinkClient.StopBlinking();
 
        return RedirectToAction(nameof(Index));
    }
 
    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel
        {
            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
        });
    }
}


Index view of HomeController will display the blinking state of LED and links to start and stop blinking.

@{
    ViewData["Title"] = "Home Page";
}
 
<div class="text-center">
    <h1 class="display-4">Hello, blinky!</h1>
    <p>Learn about 
        <a href="https://gunnarpeipman.com/aspnet/aspnet-core-hello-blinky">
            how to blink LED with ASP.NET Core
        </a>.
    </p>
    <p>Led is <strong>@ViewBag.BlinkState</strong></p>
    <p>
        <a asp-action="StartBlinking">Start blinking</a> | <a asp-action="StopBlinking">Stop blinking</a>
    </p>
</div>


With this, our work is done. Open PowerShell, log in to your Raspberry Pi, and run the web application.

Wrapping Up

Using ASP.NET Core 3.0 and .NET Core IoT libraries on RaspberryPi enables us to write a code that communicates with sensors and other devices connected to the board. ASP.NET Core 3.0 may not be an ideal host for this task, but if we need a browser-based UI to control something, then this is the way to go in my opinion. Getting "Hello, Blinky" to work wasn't a complex task, and "Hello, Blinky" has been stable thus far on my board.

Topics:
iot ,blinky ,led ,application ,hello world ,tutorial ,asp.net core

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}