Blinking an LED with Raspberry Pi 2 and C# Mono

This should work with either a Raspberry Pi B+ or a Raspberry Pi 2.  The B+ and 2 identical, save for the faster processor and increased RAM on the Pi 2.  I’m assuming you’ve gone through the setup and can boot to a command prompt or the GUI, and are using the Raspbian distro.  For most of this post, you’ll need the command line to install the different libraries, although Monodevelop is a graphical IDE.  We have to use an older version of Monodevelop (3.x), but it’s all good enough.

I have a CanaKit Raspberry Pi 2 Ultimate Starter Kit, which includes a nice breadboard and pinout connector, but greatly lacks for manuals.  This made it really tough for me to get started.  As I found out later, the pinouts are the same as other connectors, so their examples will work also.  The CanaKit does have the nice extra sets of 3.3V and 5V pinouts, which should come in handy for some uses.  Overall it’s a great kit, and I’m glad I bought it, and I hope this post helps others in the same situation.

The flashing LED is the Hello, world of GPIO (General Purpose Input Output), but it’s still pretty exciting the first time the light flashes.  Here’s how I got the LED to flash with C# and Mono.

Step 1: Install Mono and Monodevelop

At the command line, issue the following commands

sudo apt-get update

sudo apt-get upgrade

sudo apt-get install mono-complete

sudo apt-get install monodevelop

Update is used to update all of the package sources for Raspbian, and upgrade brings all your installed packages to their latest versions.  The  first install command installs just the mono runtime, and the second one installs the actual IDE.  You can develop Mono without Monodevelop, but the IDE makes life easier.  Collectively these commands install a lot of stuff, so this all could take several minutes to run. Apt-get is an application/package manager, and is part of the inspiration for nuget and chocolatey.

Once this is done, open Monodevelop and make sure it starts.

Step 2: add nuget to Monodevelop

Nuget, if you don’t know already, is a package manager for .NET.  It makes adding and maintaining dependencies much easier.  The dependencies we need are hosted on nuget.org.  The API which Monodevelop will use to search and retrieve packages is HTTPS, so we need to update the certificate store.

mozroots –import “sync

Next, install the nuget add-in by following the instructions at https://github.com/mrward/monodevelop-nuget-addin for Monodevelop 3.0.  This will now allow you to add nuget references for solutions.

Step 3: Write the program

Start by opening Monodevelop and creating a new project.  If you’re familiar with Visual Studio, this will seem very familiar.  Name your project whatever you want.

In order to access the GPIO pins of the Raspberry Pi in C#, we’ll use the Raspberry.IO.GeneralPurpose library.  We’ll reference this package from nuget by right-clicking the References node, and choosing Manage Nuget Packages (see below; if you don’t see this option, something went wrong in Step 2, look back and make sure you followed the installation completely).

image

In the Manage Packages window, search for Raspberry, select Raspberry.IO.GeneralPurpose and click Add.

image

The code sample we’ll use is based on the example at https://github.com/raspberry-sharp/raspberry-sharp-io/wiki/Raspberry.IO.GeneralPurpose.  Since there are two ways to number the GPIO pins (physical numbering, and CPU address), and since only some pins are actual i/o, it can be a little confusing when coding and wiring.  Sticking to the physical pins numbering is probably easiest, and your connector board should  have shipped with a decoder card which shows the pins.  If not, most boards have the same numbering, so anyone’s should do.  For more details, see Appendex 1 at http://www.raspberrypi.org/documentation/usage/gpio/.  Raspberry.IO.GeneralPurpose limits us to addressing only the i/o pins, so that can be a useful guide, too.

Below is the complete main.cs for our project.  If you’re copying and pasting, don’t forget to change the namespace to match your solution.

using System;
using Raspberry.IO.GeneralPurpose;
using Raspberry.IO.GeneralPurpose.Behaviors;

namespace blinky
{
	class MainClass
	{
		public static void Main (string[] args)
		{

		// Here we create a variable to address a specific pin for output
		// There are two different ways of numbering pins--the physical numbering, and the CPU number
		// "P1Pinxx" refers to the physical numbering, and ranges from P1Pin01-P1Pin40
		var led1 = ConnectorPin.P1Pin07.Output();

		// Here we create a connection to the pin we instantiated above
		var connection = new GpioConnection(led1);

		for (var i = 0; i<100; i++) {
			// Toggle() switches the high/low (on/off) status of the pin
			connection.Toggle(led1);
			System.Threading.Thread.Sleep(250);
		}

		connection.Close();

	}
	}
}

Step 4: Wire the breadboard

Do this part with your I turned off and power disconnected!  Also, touch some metal and try to get rid of any static electricity you’ve built up.  Here’s what you’ll need:

  • LED
  • 220-ish Ohm resistor
  • Two jumper wires, preferably different colors

The resistor is needed as a precaution, so we don’t accidentally burn out a pin.  A Raspberry Pi is capable of producing output currents greater than its inputs can handle.  Normally, a bunch of things like LEDs and other peripherals wired together will use enough current that it won’t matter, but for this simple task it’s better to be safe than sorry.  My kit has 220 Ohm resistors, yours may have different ones, just as long as you have something in the same range.  For a great explanation and refresher on resistors, watch https://www.youtube.com/watch?v=UApKArED3JU.   The while video is 3:23 but explains what I’ve just said even better and shows you how to calculate and read a resistor.  My Canakit also included a nice decoder card for reading resistor codes.  If you don’t have a card, check out http://en.wikipedia.org/wiki/Electronic_color_code.

The jumper wires are so you can move the stuff to a different part of the breadboard.  You can probably bend and twist the LED and resistor so you can directly wire the components, but using jumpers allows you to spread out a little more on another part of the board.  If you want a little background about a breadboards, here’s a 6 minute video: https://www.youtube.com/watch?v=q_Q5s9AhCR0.

Here’s a photo of my board, and the wiring steps.  Do this while the board is not connected to the Pi.

  1. The red wire runs from Pin 7 (GPIO 4) to an empty row on the breadboard
  2. The resistor connects the red row to another empty row.  Make sure to orient the resistor correctly.
  3. The long end of the LED is in the same row as the output end of the resistor.  The short end of the LED is in yet another empty row.
  4. The white wire connects the end of the LED to Pin 6 (GPIO GND), but you can use any GND.

20150316_201106643_iOS

Step 5: Run the program!

Connect the breadboard to the Pi, boot up to a command prompt, and change directories until you’re in the same folder as your .EXE (remember Linux paths are case sensitive).  Access to the GPIO pins requires superuser level, so you’ll need to run the binaries from the command line, using sudo:

sudo ./blinky.exe

You should be good to go!

 

References

A book I found to be very helpful is Make: Getting Started with Raspberry Pi.  Highly recommended if you don’t have a book already.

I owe a huge debt of gratitude to the authors of the blog posts listed below, in addition to any links above.  I am very lucky people more knowledgeable than I am are paving the way for my curiosity.

http://www.maketecheasier.com/write-c-sharp-programs-raspberry-pi/

http://logicalgenetics.com/raspberry-pi-and-mono-hello-world/

http://blogs.msdn.com/b/brunoterkaly/archive/2014/06/11/mono-how-to-install-on-a-raspberry-pi.aspx

https://github.com/mrward/monodevelop-nuget-addin

https://monomvc.wordpress.com/2012/03/06/nuget-on-mono/

6 thoughts on “Blinking an LED with Raspberry Pi 2 and C# Mono”

  1. Hi, when I try to run the code I get an exception error thrown:

    Exception of type ‘Raspberry.IO.Interop.MemoryMapFailedException’ was thrown.
    Raspberry.IO.Interop.MemoryMapFailedException: Exception of type ‘Raspberry.IO.Interop.MemoryMapFailedException’ was thrown.
    at Raspberry.IO.Interop.MemoryMap.ThrowOnError[MemoryMapFailedException] (IntPtr result) [0x00000] in :0
    at Raspberry.IO.Interop.MemoryMap.Create (IntPtr address, UInt32 size, MemoryProtection protection, MemoryFlags memoryflags, Int32 fileDescriptor, UInt32 offset) [0x00000] in :0
    at Raspberry.IO.GeneralPurpose.GpioConnectionDriver..ctor () [0x00000] in :0
    at Raspberry.IO.GeneralPurpose.GpioConnectionSettings.GetBestDriver (GpioConnectionDriverCapabilities capabilities) [0x00000] in :0
    at Raspberry.IO.GeneralPurpose.GpioConnectionSettings.get_DefaultDriver () [0x00000] in :0
    at Raspberry.IO.GeneralPurpose.GpioConnectionSettings..ctor () [0x00000] in :0
    at Raspberry.IO.GeneralPurpose.GpioConnection..ctor (Raspberry.IO.GeneralPurpose.GpioConnectionSettings settings, IEnumerable`1 pins) [0x00000] in :0
    at Raspberry.IO.GeneralPurpose.GpioConnection..ctor (Raspberry.IO.GeneralPurpose.PinConfiguration[] pins) [0x00000] in :0
    at led1.MainClass.Main (System.String[] args) [0x00012] in /home/pi/led1/led1/main.cs:18

    Any idea how to fix it?

    1. I haven’t seen that one. How are you running the application? I’ll try and reproduce if I can.

      1. I got that error when I ran it straight through the compiler, but when I followed the directions for the command prompt, I typed this:

        pi@raspberrypi ~ $ cd /home/pi/led1/led1/bin/Debug
        pi@raspberrypi ~/led1/led1/bin/Debug $ sudo ./led1.exe

        And nothing happened, so I presume the error is still being thrown

        1. OK, yes, that is the exception which gets thrown because you’re not running as a superuser. Accessing the GPIO requires superuser level, so you need to execute from the command line as sudo.

          You can replicate this error by executing ./led1.exe (leave out sudo). You’ll get the same error.

          When you run from the command line as sudo and you don’t see an error, and your LED isn’t blinking, it’s probably in the wiring. Maybe the LED is in there backwards? Or the resistor is backwards?

  2. How can i run the application as superuser within MonoDevelop IDE?
    Executing example from command prompt works fine (sudo …). But from Monodevelop IDE exception is thrown.

    Thank you
    René

    1. I don’t know if you can. I’ve had the same problem, and I thin you need to run from the command line. Although you can launch MonoDevelop as a superuser, I don’t think MonoDevelop launches child processes as superuser.

Comments are closed.