Coding GPIO on Beaglebone Black and Arduino

The Beaglebone Black has a C++ compiler called ‘g++’. I wrote a C++ class library to control the GPIO pins of the Beaglebone Black, and compiled the library (together with a test routine) using g++. The code was written using Leafpad on the Beaglebone Black, using VNC to show the BeagleBone Black desktop on my Windows 8 PC.

The class library contains a constructor, GPIO::GPIO, which create (exports) a file system for the required GPIO pin, and a destructor GPIO::~GPIO, which removes (unexports) the file system again.

The direction and value of the pin can be set using SetDir and SetValue. The value of the pin is set by opening the file-system, writing the value, and closing the file-system again. This is quite slow, and so a faster method is to keep the file-system open during writes, with streamOpen – streamWrite – streamClose.

// Class for controlling GPIO

#include
#include
#include
#include
using std::string;
using std::ofstream;
using std::ostringstream;
using std::cout;
using std::endl;
# define GPIO_PATH “/sys/class/gpio”

class GPIO {
public:
GPIO(int group,int pin);
virtual ~GPIO();
void debug(void);// slow control of pins
virtual void SetValue(int value);
virtual void SetDir(string pindir);// fast control of pins;
virtual int streamOpen();
virtual int streamWrite(int value);
virtual int streamClose();

private:

int internal_gpio;
string gpio_path;
string export_path;
string value_path;
string dir_path;
string Int2String(int a);
ofstream gpio_stream;
};

string GPIO::Int2String(int a)
{
ostringstream temp;
temp << a;
return string(temp.str());
}

GPIO::GPIO(int group,int pin) // so GPIO 1_17 would be GPIO(1,17)
{
ofstream fs;// figure out where we are
internal_gpio=group*32+pin;
gpio_path=string(GPIO_PATH)+”/gpio”;
gpio_path=gpio_path+Int2String(internal_gpio);
value_path=gpio_path+”/value”;
dir_path=gpio_path+”/direction”;// export pin
export_path=string(GPIO_PATH)+”/export”;
fs.open(export_path.c_str());
fs << Int2String(internal_gpio);
fs.close();
}

void GPIO::debug(void)
{
// debug code
cout << “Internal no. ” << internal_gpio << endl;
cout << “Export path: ” << export_path << endl;
cout << “GPIO path: ” << gpio_path << endl;
cout << “Direction: ” << dir_path << endl;
cout << “Value path: ” << value_path << endl;
}

GPIO::~GPIO()
{
ofstream fs;// unexport pin
export_path=string(GPIO_PATH)+”/unexport”;
fs.open(export_path.c_str());
fs << internal_gpio;
fs.close();
}

void GPIO::SetDir(string pindir)
{
ofstream fs;// set value, by writing to ‘value’
fs.open(dir_path.c_str());
fs << pindir;
fs.close();
}

void GPIO::SetValue(int value)
{
ofstream fs;// set value, by writing to ‘value’
fs.open(value_path.c_str());
fs << value;
fs.close();
}

int GPIO::streamOpen()
{
gpio_stream.open(value_path.c_str());
}

int GPIO::streamWrite(int value)
{
gpio_stream << value << std::flush;
}

int GPIO::streamClose()
{
gpio_stream.close();
}

main()
{
long ll;GPIO newpin(1,17);
newpin.SetDir(“out”);
newpin.streamOpen();

for (ll=0;ll<10000000;ll++)
{
newpin.streamWrite(0);
newpin.streamWrite(1);
//newpin.SetValue(0);
//newpin.SetValue(1);
}

newpin.streamClose();
}

The LED board was connected again to the BeagleBone Black, together with the Digilent Analog Discovery oscilloscope.

BeagleBone Black, LED board, and Digilent Analog Discovery

BeagleBone Black, LED board, and Digilent Analog Discovery

Using ‘SetValue’, an output rate of 5 KHz is achievable. Opening and closing the file-system is very slow.

Slow BBB output

Individual write output

Using ‘streamWrite’, an output rate of 110 KHz is achievable. Keeping the file-system open makes for a much faster data transfer.

waveform

Stream write waveform

By way of comparison, the same experiment was done for the Arduino Nano. The Arduino Nano was inserted into a breadboard, so that my male-male connectors could be used. The blue cable was plugged into ground (GND), the orange wire into +5V (5V), and the green wire into GPIO pin 8 (D8).

Arduino Nano in breadboard

Arduino Nano in breadboard

The Arduino was connected to the LED board.

Arduino, LED board and Digilent Analog Discovery

Arduino, LED board and Digilent Analog Discovery

A simple program was downloaded to the Arduino, which turns the LED on and off as quickly as possible. The ‘Blink’ program was used as the basis for this, but now using pin 8 instead of the onboard pin 13 and LED.

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 8 as an output.
pinMode(8, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(8, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(8, LOW); // turn the LED off by making the voltage LOW
}

The resultant output runs at 95 KHz. This is quite slow for a 16MHz processor, but is similar to the BeagleBone Black which is a more advanced processor running at 1 GHz (1000 MHz). This shows just how expensive it is to run Linux on an embedded system.

Arduino

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s