BBBCSIO

OutputPort Example Code

 

About the OutputPort Classes

The OutputPort classes are designed to set the state (high or low) of a GPIO pin on the Beaglebone Black. In the Linux operating system there are two ways of accessing the GPIO pins. The first, called the SYSFS method, is the standard and approved Linux technique. During SYSFS accesses each GPIO is exposed as a file in the filesystem and the GPIO is manipulated as if it were a file. The second method, called Memory Mapped access, treats the Beaglebone Black's RAM memory as if it were a file and the GPIO state is manipulated as if it were a bit at an offset in a virtual file.

The major difference between the two techniques is that the SYSFS method is considerably slower than Memory Mapped access. For example, a maximum write frequency of about 1KHz is obtainable with SYSFS whereas something in the order of 1.8MHz (yes, mega Hertz) is obtainable with the Memory Mapped technique. SYSFS is the approved "Linux Way". However, if you need the speed, Memory Mapped access is the way to go.

The BBBCSIO library provides classes for both SYSFS and Memory Mapped access. The classes can be differentiated by the corresponding FS and MM appended to their names. The OutputPortFS class provides SYSFS access to the GPIO and the OutputPortMM class provides Memory Mapped access.

When should you use SYSFS or Memory Mapped access? Well, in testing, both seemed pretty robust and trouble free. If you need a write frequency greater than about 1KHz you'll definitely want to use the OutputPortMM class - otherwise the OutputPortFS class will probably suffice. Both classes are used in exactly the same way and have exactly identical public members.

Warnings - READ THIS!!!

The example code below uses a GPIO value of 48 which is exposed as pin 15 on the P9 header. You CAN NOT assume that this pin is available as a GPIO on your Beaglebone Black and even if it is a GPIO you still cannot assume it is set as a GPIO output (as opposed to being an input). Any one GPIO can be used for any of about half a dozen different peripherals (UART, SPI bus, PWM, A/D, HDMI, EMMC etc) and it is not a given that a GPIO used in these examples or any specific GPIO is available. The GPIO's used in these examples may be used for other things on your Beaglebone Black.

Before using any OutputPort class on a GPIO you will need to ensure that the GPIO is configured as an input. There is no code you can call in the BBBCSIO library which does this. You MUST configure the GPIO externally prior to running your executable - usually this is done by editing the device tree.

Always be aware that the armhf Linux running on the Beaglebone Black is not a real-time operating system. This means, for example, although you might set up an OutputPort() object to write at 10000 times a second, the actual width of some of the pulses may vary (and there may be lengthy gaps) as the process is pre-emptively swapped in and out by the kernel.

Note that the output current of the Beaglebone Black is extremely limited. You cannot, for example, directly drive a light emitting diode (LED) with it. If you try to directly control a LED you will have effectively just shorted the output to ground which is not good for the output port. The LED will not light either since there is nowhere near enough current available. To interface with anything other than another 3.3v high impedance device input you need to set up some external circuitry. This page discusses how to set up a transistor so that a GPIO output can control a LED.

An Example of the OutputPort Usage

The code below illustrates how to use the OutputPortMM class to read the state of a GPIO pin and output that state to the console. You could use the SYSFS version by replacing each OutputPortMM with an OutputPortFS.

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Produces a series of 1 sec pulses on a GPIO port. Memory mapped version
        /// 
        /// NOTE: 
        ///   This code assumes that the port associated with the gpioID has been 
        ///   properly configured in the device tree as an output. If it is not
        ///   then the output may not work correctly. See the associated documentation
        /// 
        /// NOTE:
        ///    Be aware of the BBB output voltage and max output current. In general
        ///    you cannot directly switch any meaningful output device. You have to
        ///    run it through a transistor or some other current/voltage amplifier.
        /// 
        /// </summary>
        /// <param name="gpioID">The gpioID</param>
        /// <history>
        ///    28 Aug 14  Cynic - Originally written
        /// </history>
        public void SimplePulsePortMM(GpioEnum gpioID)
        {
            // open the port
            OutputPortMM outPort = new OutputPortMM (gpioID);

            // run until we have a keypress on the console
            while (Console.KeyAvailable == false)
            {
                // put the port low
                outPort.Write(false);
                // sleep for half a second
                Thread.Sleep(500);
                // put the port high
                outPort.Write(true);
                // sleep for half a second
                Thread.Sleep(500);
            }
            // close the port
            outPort.ClosePort();
            outPort.Dispose();
        }
In the above code, the gpioID is passed in when the function was called. This value is a member of the GpioEnum class which lists all possible GPIO's which can be present on the Beaglebone Black. The above code is called via a line which looks like:
SimplePulsePortMM(GpioEnum.GPIO_48);