Archive

Archive for March, 2012

BeagleBone GPIO Programming

March 31, 2012 3 comments

According to the BeagleBone System Resource Manual (SRM) the board has:

A maximum of 66 GPIO pins are accessible from the expansion header. All of these pins are 3.3V and can be configured as inputs or outputs. Any GPIO can be used as an interrupt and is limited to two interrupts per GPIO Bank for a maximum of eight pins as interrupts.

These pins are distributed across both expansion headers (P8 & P9) and their locations are well documented in the SRM. As described in a previous article, Linux provides a virtual file system called sysfs as a programming interface to system resources such as GPIO. The blink.js script that’s supplied with BeagleBoard’s Ångström’s Linux distribution will blink the User 3 LED and toggle GPIO1_6, which is located on the third pin of expansion header P8, high and low.

This article describes my experience getting an LED to blink using GPIO1_6.

Before I get into my LED project I want to note that I’m a typical software guy. I understand basic circuitry but my knowledge of electronics rapidly diminishes after that. So there are aspects of this journey that I’m discovering for the first time.  Most BeagleBone articles don’t detail the circuitry nor explain the electronics behind it. They assume the audience knows that stuff and focus on the BeagleBone part of things. I’m going to get into those details because I had to learn them before I could get this simple example to work.

LED Circuit

LED Circuit

An LED circuit is about a simple as it gets but still a bit of a learning experience for me.

  1. There are different kinds of LED’s. I picked up a standard red diffused 1 3/4 sized LED.
  2. The resistor is really important. Forget the resistor and you’ve created a short circuit. Not only will be burn out the resistor and your fingers it can damage the BeagleBone. The type of resistor you’ll need will depend on things like voltage and LED type. The resistor can be placed before or after the LED.
  3. An LED will only light with correct electrical polarity. You have to plug it in the right way.
GPIO Output to LED

GPIO Output to LED

I’m going to use GPIO1_6 as the power source for the LED circuit. When I set it high 3.3V will be supplied to the circuit and the LED will blink on. Setting GPIO1_6 low turns off the power the the LED will blink off.

Including a resistor in the circuit is a must. Knowing exactly what kind of resistor takes some testing. If you are in a hurry you can use 1k ohm (1/4 W – 5%) resistor. You’ll get a dim light but you’ll know it is safe.

Calculating the optimal type of resistor requires three values:

  • The source voltage. Since I’m using a GPIO pin it should be 3.3V.
  • The LED voltage. I used a multi-meter to get a value of 1.6V.
  • The LED current. Which after a lot of trial and error using a multi-meter comes in at 20mA.

Now to the formula.  The resistor value, R is given by: R = (VS – VL) / I

VS = supply voltage
VL = LED voltage
I = LED current

In my case this worked out to be 100ohm. There are all sorts of nifty calculators on the Internet. I used this one at LED Center to do the calculation for me.

This shows how I wired the circuit.

BeagleBone LED Circuit

BeagleBone LED Circuit

The red wire is plugged into GPIO1_6. That GPIO pin provides the power when it is set high. I’ve put a 100ohm resistor in front of the red LED. I could have put it after. You need wire the LED’s polarity correctly. If you wire it backwards the LED will not illuminate. The yellow wire runs to an expansion header GND pin and completes the circuit.

On the programming side we toggle GPIO1_6 on and off by using its sysfs interface. If I run blink.js both the User 3 LED and my red LED will blink. I wrote a shell script blink.sh to do the same thing.

#!/bin/sh

echo 38 > /sys/class/gpio/export

while :
do
  echo 1 > /sys/class/leds/beaglebone::usr3/brightness
  echo high > /sys/class/gpio/gpio38/direction
  sleep 1
  echo 0 > /sys/class/leds/beaglebone::usr3/brightness
  echo low > /sys/class/gpio/gpio38/direction
  sleep 1
done

/sys/class/gpio/gpio38 does not exist by default. You create it by writing the GPIO port number to /sys/class/gpio/export. You can remove it by writing the same number to /sys/class/gpio/unexport.

Here’s a video of it in action.

Advertisements
Categories: BeagleBone Tags:

Puppy’s First Month

March 31, 2012 Leave a comment

My BeagleBone, along with some other goodies, arrived about a month ago. March was a busy month and while I did have some time to play with the little guy I didn’t have time to write about it. The few articles cover a variety of things that I experienced so far.

Adafruit Beagle Bone Starter Pack

Adafruit Beagle Bone Starter Pack

I purchased adafruit’s BeagleBone Starter Pack. That turned out to be a good choice. It made things plug and play for a software guy like me. I didn’t have to fuss with finding the right power supply. The puppy and half size breadboard are easily mounted onto a simple plexiglass plate that nicely keeps everything together.

I plugged the power supply and a network cable into the BeagleBone and within a minute I could access it using ssh. Neat! Here are the various access points:

  • ssh (port 22) – for access to a shell
  • bone101 (port 80) – small server written in node.js serving up an intro presentation
  • GateOne (port 443) – access to a shell through Firefox or Chrome
  • Cloud9 IDE (port 3000) – text editor and debugger for node.js applications through Firefox, Chrome or Safari
Being a programmer I really wanted to make the BeagleBone do something. After lots of Goggling I decided to start with blinking an LED. GigaMegaBlog has some very good articles on the BealgeBone. Beaglebone Coding 101: Blinking an LED was a very good starting place. It describes how to use the cloud9 IDE to some fun things with an LED. 

The cloud9 IDE is an online development environment for Javascript and Node.js applications as well as HTML, CSS, PHP, Java, Ruby and 23 other languages. The blink.js script demonstrates how to blink the User 3 LED on the board. That worked all and well but I’m not interested in writing JavaScript and blink.js hides how things work. So I started digging and it turns out that blink.js is using Linux’s sysfs.

sysfs is an implementation of a virtual file system. It exposes system devices to user space using a file system topology model. At the base of the topology are logical device groupings such as bus, class, and devices. Within those groupings there can be more logical groupings. Eventually the topology reaches a node that represents a physical device. Under the physical device node there can be nodes representing sub-devices or actions.

The LED’s on the board can be driven using sysfs:

  • /sys/class/leds provides interfaces to the User LED’s.
  • /sys/class/leds/beaglebone::usr3 represents an instance of the User 3 LED.
  • /sys/class/leds/beaglebone::usr3/brightness represent an action that can be performed on the User 3 LED. In this case you can:
    • Write a value (0, 1) to the file. That will set the LED to on (1) or off (1).
    • Read a value from the file. It will return the brightness (0, 1) of the LED.

The following shell script will blink the User 3 LED.

#!/bin/sh
while :
do
  echo 1 > /sys/class/leds/beaglebone::usr3/brightness
  sleep 1
  echo 0 > /sys/class/leds/beaglebone::usr3/brightness
  sleep 1
done

You’ll notice that blink.js is actually toggling two LED’s (ledPin, ledPin2). This is a bit confusing because only one LED is blinking. In fact both “pins” are set to set high and then low. But only one pin (ledPin2 = bone.USR3) actually has an LED attached to it. The other (ledPin = bone.P8_3) is a General Purpose Input/Output (GPIO) port that’s not connected to anything at this point. Even more interesting is that all the User LED’s are controlled by a GPIO port. But you can’t use the sysfs GPIO interface to control them. If you try you’ll get a “Device or resource busy” error. I suppose that’s because the sysfs-leds driver has grabbed it first.

Here’s how bone.P8_3 maps to sysfs-gpio. P8_3 is pin 3 on expansion header P8. According to the BeagleBone manual this is signal name GPIO1_6. From the signal name we can calculate the GPIO port number. In this case it is 38 (1 x 32 + 6). The first number is an offset of size 32. The second number is an offset from that number. Just multiple the first number by 32 and then add the second number. It’s all kind of confusing and it gets to be more fun when you bring in mux’ing.

Here’s now to access GPIO port 38 using sysfs:

  • /sys/class/gpio provides an interface to GPIO ports.
  • /sys/class/gpio/gpio38 is an instance of GPIO port 38. BeagleBone has 66 of these ports.
  • /sys/class/gpio/gpio38/direction represents an action that can be performed on GPIO port 38. In this case you can write a value (“high”, “low”) to the file. That will set the GPIO port to that value.
  • /sys/class/gpio/gpio38/value represents an action that can be performed on GPIO port 38. In this case you can read a value (“0”, “1”) from the file. It return the GPIO port’s value.

By the way, /sys/class/gpio/gpio38 isn’t there by default. You have to create it by writing the port number to /sys/class/gpio/export. For example:

echo 38 > /sys/class/gpio/export

You can find more on this at:


Categories: BeagleBone Tags: