Skip to content

Instantly share code, notes, and snippets.

@duanebester
Created April 22, 2024 20:44
Show Gist options
  • Save duanebester/e7de83e7177ccfc3c57e3a54cc1e5122 to your computer and use it in GitHub Desktop.
Save duanebester/e7de83e7177ccfc3c57e3a54cc1e5122 to your computer and use it in GitHub Desktop.
A class to control GPIO pins using the sysfs interface
import 'dart:io';
const String _gpioExport = '/sys/class/gpio/export';
const String _gpioUnexport = '/sys/class/gpio/unexport';
const String _gpioPath = '/sys/class/gpio/gpio%d';
const String _gpioDirection = '/sys/class/gpio/gpio%d/direction';
const String _gpioValue = '/sys/class/gpio/gpio%d/value';
const String _gpioActiveLow = '/sys/class/gpio/gpio%d/active_low';
enum Direction { input, output, low, high }
extension Enum on Direction {
String get value {
switch (this) {
case Direction.input:
return 'in';
case Direction.output:
return 'out';
case Direction.low:
return 'low';
case Direction.high:
return 'high';
}
}
}
/// A class to control GPIO pins using the sysfs interface.
class GPIOSysfs {
int pinNumber;
Direction direction;
GPIOSysfs(this.pinNumber, this.direction);
factory GPIOSysfs.fromPin(int pinNumber, Direction direction) {
var path = _gpioPath.replaceAll('%d', pinNumber.toString());
if (!Directory(path).existsSync()) {
// Export the pin
File file = File(_gpioExport);
RandomAccessFile raf = file.openSync(mode: FileMode.writeOnly);
raf.writeStringSync(pinNumber.toString());
// Wait for the pin to be exported
var count = 0;
while (!Directory(path).existsSync()) {
sleep(Duration(milliseconds: 50));
count++;
if (count > 10) {
throw Exception('Failed to export pin $pinNumber');
}
}
}
// Set the direction
File file = File(_gpioDirection.replaceAll('%d', pinNumber.toString()));
file.writeAsStringSync(direction.value);
return GPIOSysfs(pinNumber, direction);
}
void exportPin() {
File file = File(_gpioExport);
RandomAccessFile raf = file.openSync(mode: FileMode.writeOnly);
raf.writeStringSync(pinNumber.toString());
}
void unexportPin() {
File file = File(_gpioUnexport);
RandomAccessFile raf = file.openSync(mode: FileMode.writeOnly);
raf.writeStringSync(pinNumber.toString());
}
void setValue(int value) {
File file = File(_gpioValue.replaceAll('%d', pinNumber.toString()));
file.writeAsStringSync(value.toString());
}
int getValue() {
File file = File(_gpioValue.replaceAll('%d', pinNumber.toString()));
return int.parse(file.readAsStringSync());
}
void setDirection(Direction direction) {
File file = File(_gpioDirection.replaceAll('%d', pinNumber.toString()));
file.writeAsStringSync(direction.value);
}
Direction getDirection() {
File file = File(_gpioDirection.replaceAll('%d', pinNumber.toString()));
return Direction.values
.firstWhere((e) => e.value == file.readAsStringSync());
}
// This inverts the meaning of 0 and 1 in /sys/class/gpio/gpio*/value
void setActiveLow(bool activeLow) {
File file = File(_gpioActiveLow.replaceAll('%d', pinNumber.toString()));
file.writeAsStringSync(activeLow ? '1' : '0');
}
void clearPin(int pin) {
unexportPin();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment