Getting GPIO input with libpigpio

I promised that I'd report back when I had gotten round to testing the input capability of libpigpio. Well I now have something to report, here goes:

I've written a small test program in C to check that it works OK (and added the necessary electronics). When I press a button (which is connected to the GPIO) then the LED comes on. This is all done through software. As you can see from the picture above, it works fine. I also have the same program outputting the GPIO input values to the console, like this:

So now that I have tested it in C, I can also try the same thing in C# with mono, but it should work fine.

Using libpigpio in Mono with C#

UPDATE: you'll probably need to recompile the library from source, read here for instructions.

So, here are some instructions for using libpigpio, the shared GPIO library for the Raspberry Pi in a C# program. First, get libpigpio by downloading it from here.

Unzip it and copy the file called libpigpio.so to the /lib folder on your Raspberry Pi. You'll need elevated privileges to do that, so you'll probably type something like:

sudo cp libpigpio.so /lib.

Alternatively, you could compile the library yourself by copying the libpigpio.c file to the Raspberry Pi and using the commands listed inside the file to compile and copy it to /lib.

Once libpigpio.so is in the /lib folder the library is installed and ready to use. We can now begin programming in C#. I'm using MonoDevelop on another machine, I expect you'd probably do something similar. Create your new C# project, and add the RpiGpio class found in RpiGpio.cs or just copy and paste the code from my previous blog entry. This is the wrapper that allows the shared library to be used in C#. Now we can write some C# code to access the GPIO.

This is an example test program:

using System;
using System.Threading;
 
using LibPiGpio;
 
namespace RPiBlinky
{
    class Program
    {
        static void Main(string[] args)
        {
            int inc = 1, t = 7, last = 0;
            RpiGpio.SetOutputPins(new[] { 7, 8, 9, 10, 11 });
 
            while (!Console.KeyAvailable)
            {
                if (last != 0)
                {
                    t = t + inc;
                    if (t >= 11 || t <= 7) inc *= -1;
                    RpiGpio.Pins[last] = false;
                }
                RpiGpio.Pins[t] = true;
                last = t;
                Thread.Sleep(250);
            }
            Console.ReadKey();
        }
    }
}

If you want to test your code, you can uncomment the #define NOPI in RpiGpio.cs, which will allow you to run the code on something other than a Raspberry Pi. For example, here is the test program running like that on my virtual machine:

When you're happy with your code (making sure that you've re-commented the #define in RpiGpio.cs) simply copy the compiled C# executable to your Raspberry Pi and run it like this:

sudo mono GPIOtest.exe.

But replace GPIOtest.exe with the name of your Mono executable. You'll need to use sudo for the program to have enough permission to access the GPIO. That's it! It's quite a simple process really.

Please check everything I've said, you can't hold me responsible if you break your own stuff. Always double check your electronic connections, that will help you not to break stuff too. It's always best to check the source code and compile it yourself before you use it. But have fun, it's good to build stuff.

Raspberry Pi C# Mono example using libpigpio

So, after posting the libpigpio library which is a shared library written in C to give GPIO access on the Raspberry Pi, here is a C# wrapper that makes it possible to use it in C#/Mono. It's quite a simple version, but it should allow me to mess about turning things on and off from the Raspberry Pi. Here's the code:

// uncomment the line below to test without libgpio installed
//#define NOPI
using System;
using System.Runtime.InteropServices;
 
namespace LibPiGpio
{
    /*  A basic wrapper for "libpigpio" - a shared library for GPIO access on the Raspberry Pi
     *  To get libpigpio, visit my blog entry here:
     *  http://www.codehosting.net/blog/BlogEngine/post/Raspberry-Pi-Shared-Library-for-GPIO.aspx
    */
 
    public static class RpiGpio
    {
        public static PinSetter Pins { getset; }
 
#if !NOPI
        [DllImport("libpigpio.so")]
        static extern void setup_io();
        [DllImport("libpigpio.so")]
        static extern void switch_gpio(int val, int pin);
        [DllImport("libpigpio.so")]
        static extern int check_gpio(int pin);
        [DllImport("libpigpio.so")]
        static extern void set_in(int gpio);
        [DllImport("libpigpio.so")]
        static extern void set_out(int gpio);
#else
#region stubs to test without libpigpio
        static void setup_io() { Console.WriteLine("Setup"); }
        static void switch_gpio(int val, int pin) { Console.WriteLine("GPIO{0} set to {1}",pin,val); }
        static int check_gpio(int pin) { Console.WriteLine("GPIO{0} returned 0", pin); return 0; }
        static void set_in(int pin) { Console.WriteLine("GPIO{0} is input", pin); }
        static void set_out(int pin) { Console.WriteLine("GPIO{0} is output", pin); }
#endregion
#endif
 
        static RpiGpio()
        {
            Pins = new PinSetter();
            setup_io();
        }
 
        public static void SetOutputPins(int[] outputs)
        {
            if (outputs == null || outputs.Length == 0) return;
            foreach (int output in outputs)
                set_out(output);
        }
 
        public static void SetInputPins(int[] inputs)
        {
            if (inputs == null || inputs.Length == 0) return;
            foreach (int input in inputs)
                set_in(input);
        }
 
        public class PinSetter
        {
            public bool this[int GpioPin]
            {
                set { switch_gpio(value ? 1 : 0, GpioPin); }
                get { return check_gpio(GpioPin) == 1; }
            }
        }
    }
}

I have not tried out the library's ability to get the GPIO pin values yet, mainly because I have not gotten round to wiring up my breadboard with a suitable switch. When I have chucked the necessary electronic components onto the breadboard I'll be sure to give it a try. And then I'll report back of course. Until then, be warned that I've only tested the setting of GPIO pins. Use appropriate caution if you're using the library. You can't hold me responsible if you break your stuff, use it at your own risk.

...and if you're interested in knowing more about the Raspberry Pi GPIO, you might want to watch the tutorial posted on the Raspberry Pi main site. I'm still confused that the GPIO pins are given different numbers in different places. But I know that with this library the GPIO pin numbers match the Pin Name column on the Header Pinout tables on this wiki page.

My next little task is to use this library with my simple C# web server so that I can access the GPIO pins from a web page. Then I will be able to turn stuff on and off from the web, awesome. I have no idea what I'm going to switch on and off yet, but I suppose there can up to 17 of them. But I will also post some sample code showing this C# wrapper in action, in case you'd like to see example code.

Raspberry Pi Shared Library for GPIO

UPDATE: you'll probably need to recompile the library from source, read here for instructions.

So, here is the Raspberry Pi GPIO shared library that I have been working on. When you look at the code, you'll see that I can't really take the credit, the bulk of the code is the same as shown here on the Raspberry Pi wiki. What I have done is fiddle with some compiler options and done some minor tinkering in the code to suit my purposes and style. And it seems to work OK, I'm mainly using it from Mono. It's not the only way to get GPIO access using Mono (another approach is demonstrated here for example), but it's the approach that I've chosen. It means that I can carry on tinkering with the C library without recompiling my Mono code. You could also build versions of the same library for other hardware and then run the same Mono code on different machines. I've made a stub version of the library which allows me to test Mono code on the vitual machine I've set up to run Debian.

The source code for the library is in this zip file. You can recompile from source on the Raspberry Pi (instructions are in the C code) or you can just copy the libpigpio.so file to your /lib folder. You can't hold me responsible if you blow up your own Raspberry Pi though! I have not yet tested the code that gets values from the GPIO, I've only tested the setting of pins at this point. You have been warned.

Of course, you don't have to use this library in Mono, you can use it in C programs too (as well as any other language that supports calling shared libraries). But I've only tested calling it from C and Mono.

Anyway, I hope that it's useful to somebody ... or maybe just interesting. At some point I'll post an example C#/Mono program that uses the library. Have fun!

Who's got a blinking Pi?

So, one of the things that I wanted to do with the Raspberry Pi was to control the GPIO pins from C# (Mono). What I decided to do was to write a shared library in C and then use native library interop from Mono to call the C code.

Anyway, the first step was to write the library in C and then call it from another C program. What I have done is basically copy the example from here, but write the actual GPIO access as a shared library. Currently, I'm simply copying the resulting .so file into /lib.

It wasn't that hard to do, I was quite surprised. Here is the working library running on a Raspberry Pi:

When I've had a bit more time to play with it and tidy up some things I will post the source code, probably in a few day time I expect. But the next step is to check that it works from Mono, but I don't see any reason why it shouldn't.

Raspberry Pi low-res fractal in C

Of course, it wouldn't be me unless I tried drawing a mandelbrot on the Raspberry Pi. Here is the traditional ASCII character version, but with some low-res colours.

Raspberry Pi Mandelbrot in C

I have to admit that the colour idea was inspired by somebody called Paulo Lellis, who had read some of my previous posts and adapted my code to include colour codes. It was very kind of Paulo to show me what he had done. I've simply tweaked it some more.

Anyway, if you'd like to try it, here is the source code:

#include <stdio.h>

/*
   Compile like this:
   gcc mandel.c

   Then run the code, like this
   /.a.out
*/

main()
{
   float b,e,r,n,d;
   int h;
	
   for(e=1.1; e>-1.2; e-=.1)
   {
      for(b=-2; b<1; b+=.04)
      {
         // see: http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
         printf("\033[1;4%dm%c\033[0m",(h%8),32);
				
         n=0;
         h=127;
         for(r=0; r*r+n*n<4 && --h>32; d=r)
         {
            r = r*r-n*n+b;
            n = 2*d*n+e;
         }
      }
      printf("\r\n");
   }
}

Well, I had to try the C compiler on the Raspberry Pi at some point.

Remoting into a Raspberry Pi

The little LCD TV I tested the Raspberry Pi with wasn't very good, so I wondered if it was possible to remote into the Raspberry Pi from another machine. I found that this is no problem when I looked here. So I tried the following commands:

sudo apt-get install tightvncserver
tightvncserver

...on the Raspberry Pi and it worked perfectly. Then with a copy of the TightVNC client running on my windows machine, I can access the Raspberry Pi remotely. This is awesome.

I used that approach to do more testing of my simple C# webserver, so here I am testing the webserver in TightVNC ... and also checking that the page is being served over my network to the PC in internet explorer:

...and finally, here is the Raspberry Pi serving the same test page to my iPhone:

OK, that all seems to work. I've just got to figure out what to do next now.

Unexpected Pi

A very kind colleague of mine has lent me his Raspberry Pi, so that I can have a little play with it. Here it is being hooked up on my workbench:

I used the standard Debian 'squeeze' image, since that's what I've been messing about with recently. After checking that I had internet access, I went off and installed the mono runtime, like this:

sudo apt-get update
sudo apt-get install mono-runtime

...after doing that I ran the C# webserver example that I had already written - and it works a treat! I didn't compile the code on the Raspberry Pi, I simply copied the exe file over and ran it with the mono command. The code was compiled in monodevelop running on Debian in VirtualBox.

Anyway, here is another photo, taken when I was first cheking that I could get online. Umm, I need to tidy up in here again.

More reports will follow I'm sure...