Skip to content

Instantly share code, notes, and snippets.

@curtmack
Last active May 12, 2017 18:13
Show Gist options
  • Save curtmack/4159aa4ab9d743a8e284 to your computer and use it in GitHub Desktop.
Save curtmack/4159aa4ab9d743a8e284 to your computer and use it in GitHub Desktop.
An old C++ library for the Raspberry Pi Revision 2 (please note: Raspberry Pi 1, revision 2, *not* Raspberry Pi 2) GPIO pins, using the standard /sys/class/gpio driver. It's probably outdated for newer Pi models, so beware. Also I don't think I ever actually tested input.
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include "gpio.hpp"
using namespace std;
namespace GPIO {
Connection::Connection() : Connection{Pin::GPIO4} {} //because why not default to 4
Connection::Connection(Pin pin) : Connection{pin, Direction::UnInit} {}
Connection::Connection(Pin pin, Direction direct) : pin(pin), direct(direct)
{
this->exportPin();
if (this->direct != Direction::UnInit)
{
this->setDirection(this->direct);
}
}
Connection::~Connection()
{
this->unexportPin();
}
int Connection::exportPin()
{
string export_str = "/sys/class/gpio/export";
ofstream exportgpio(export_str.c_str()); // Open "export" file. Convert C++ string to C string. Required for all Linux pathnames
if (exportgpio < 0){
cerr << " OPERATION FAILED: Unable to export GPIO"<< static_cast<int>(this->pin) << endl;
return -1;
}
exportgpio << static_cast<int>(this->pin) ; //write GPIO number to export
exportgpio.close(); //close export file
return 0;
}
int Connection::unexportPin()
{
string unexport_str = "/sys/class/gpio/unexport";
ofstream unexportgpio(unexport_str.c_str()); //Open unexport file
if (unexportgpio < 0){
cerr << " OPERATION FAILED: Unable to unexport GPIO"<< static_cast<int>(this->pin) << endl;
return -1;
}
unexportgpio << static_cast<int>(this->pin); //write GPIO number to unexport
unexportgpio.close(); //close unexport file
return 0;
}
int Connection::setDirection(Direction direct)
{
if (direct == Direction::UnInit) {
cerr << " OPERATION FAILED: Can't set the direction of a GPIO connection to Direction::UnInit" << endl;
return -1;
}
stringstream sstr;
sstr << "/sys/class/gpio/gpio" << static_cast<int>(this->pin) << "/direction";
ofstream setdirgpio(sstr.str().c_str()); // open direction file for gpio
if (setdirgpio < 0){
cerr << " OPERATION FAILED: Unable to set direction of GPIO"<< static_cast<int>(this->pin) << endl;
return -1;
}
setdirgpio << (direct == Direction::In ? "in" : "out"); //write direction to direction file
setdirgpio.close(); // close direction file
this->direct = direct;
return 0;
}
int Connection::setValue(bool val)
{
if (this->direct != Direction::Out) {
cerr << " OPERATION FAILED: Can't set the value of an input GPIO connection" << endl;
return -1;
}
stringstream sstr;
sstr << "/sys/class/gpio/gpio" << static_cast<int>(this->pin) << "/value";
ofstream setvalgpio(sstr.str().c_str()); // open value file for gpio
if (setvalgpio < 0){
cerr << " OPERATION FAILED: Unable to set the value of GPIO"<< static_cast<int>(this->pin) << endl;
return -1;
}
setvalgpio << val ;//write value to value file
setvalgpio.close();// close value file
return 0;
}
int Connection::getValue(bool& val)
{
if (this->direct != Direction::In) {
cerr << " OPERATION FAILED: Can't get the value of an output GPIO connection" << endl;
return -1;
}
stringstream sstr;
sstr << "/sys/class/gpio/gpio" << static_cast<int>(this->pin) << "/value";
ifstream getvalgpio(sstr.str().c_str()); // open value file for gpio
if (getvalgpio < 0){
cerr << " OPERATION FAILED: Unable to get value of GPIO"<< static_cast<int>(this->pin) << endl;
return -1;
}
string tmp;
getvalgpio >> tmp; //read gpio value
// nonzero is on, zero is off
val = (tmp != "0");
getvalgpio.close(); //close the value file
return 0;
}
} // namespace GPIO
#ifndef GPIO_H
#define GPIO_H
namespace GPIO
{
// Directions in which a pin can be set
enum class Direction {
UnInit,
In,
Out
};
// Valid GPIO pin numbers on Revision 2 Raspberry Pi
enum class Pin : int {
GPIO2 = 2,
GPIO3 = 3,
GPIO4 = 4,
GPIO7 = 7,
GPIO8 = 8,
GPIO9 = 9,
GPIO10 = 10,
GPIO11 = 11,
GPIO14 = 14,
GPIO15 = 15,
GPIO17 = 17,
GPIO18 = 18,
GPIO22 = 22,
GPIO23 = 23,
GPIO24 = 24,
GPIO25 = 25,
GPIO27 = 27
};
class Connection
{
public:
Connection();
Connection(Pin pin);
Connection(Pin pin, Direction direction);
~Connection();
int setDirection(Direction direction);
int setValue(bool value);
int getValue(bool& value);
private:
int exportPin();
int unexportPin();
Pin pin;
Direction direct;
};
} // namespace GPIO
#endif // !def GPIO_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment