Improved sysfs file access code
This commit is contained in:
parent
2304372129
commit
b53cabec90
@ -15,28 +15,16 @@ try {
|
|||||||
$gpio->setMapper( new WiringPiMapper(2) );
|
$gpio->setMapper( new WiringPiMapper(2) );
|
||||||
|
|
||||||
// Access logical pin 0, since we got a mapper assigned. Otherwise this would
|
// Access logical pin 0, since we got a mapper assigned. Otherwise this would
|
||||||
// be the actual GPIO0 pin.
|
// be the actual GPIO0 pin.
|
||||||
$led = $gpio[0]
|
$led = $gpio[0]
|
||||||
->export()
|
->export()
|
||||||
->setDirection("output")
|
->setDirection("output")
|
||||||
->setValue(0)
|
->setValue(0)
|
||||||
->setLabel("red led")
|
|
||||||
->dumpStatus(true);
|
->dumpStatus(true);
|
||||||
|
|
||||||
$btn1 = $gpio[1]
|
$x = 0;
|
||||||
->setDirection("input")
|
while(true) {
|
||||||
->setValue(0)
|
$x = (int)(!$x);
|
||||||
->setEdge("rising")
|
$led->setValue($x);
|
||||||
->setHandler(function() { echo "INTERRUPT!\n"; })
|
usleep(500000);
|
||||||
->setLabel("button 1")
|
}
|
||||||
->dumpStatus(true);
|
|
||||||
|
|
||||||
$btn2 = $gpio[2]
|
|
||||||
->setDirection("input")
|
|
||||||
->setValue(0)
|
|
||||||
->setEdge("rising")
|
|
||||||
->setHandler(function() { echo "INTERRUPT!\n"; })
|
|
||||||
->setLabel("button 2")
|
|
||||||
->dumpStatus(true);
|
|
||||||
|
|
||||||
|
|
||||||
|
42
examples/buttons.php
Normal file
42
examples/buttons.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
use NoccyLabs\Gpio\Gpio;
|
||||||
|
use NoccyLabs\Gpio\GpioMapper\WiringPiMapper;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$gpio = new Gpio();
|
||||||
|
} catch (Gpio\Exception $e) {
|
||||||
|
error_log("Error: {$e}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// The mapper translates GPIO to logical pins and vice versa
|
||||||
|
$gpio->setMapper( new WiringPiMapper(2) );
|
||||||
|
|
||||||
|
// Access logical pin 0, since we got a mapper assigned. Otherwise this would
|
||||||
|
// be the actual GPIO0 pin.
|
||||||
|
$led = $gpio[0]
|
||||||
|
->export()
|
||||||
|
->setDirection("output")
|
||||||
|
->setValue(0)
|
||||||
|
->setLabel("red led")
|
||||||
|
->dumpStatus(true);
|
||||||
|
|
||||||
|
$btn1 = $gpio[1]
|
||||||
|
->setDirection("input")
|
||||||
|
->setValue(0)
|
||||||
|
->setEdge("rising")
|
||||||
|
->setHandler(function() { echo "INTERRUPT!\n"; })
|
||||||
|
->setLabel("button 1")
|
||||||
|
->dumpStatus(true);
|
||||||
|
|
||||||
|
$btn2 = $gpio[2]
|
||||||
|
->setDirection("input")
|
||||||
|
->setValue(0)
|
||||||
|
->setEdge("rising")
|
||||||
|
->setHandler(function() { echo "INTERRUPT!\n"; })
|
||||||
|
->setLabel("button 2")
|
||||||
|
->dumpStatus(true);
|
||||||
|
|
||||||
|
|
@ -2,6 +2,21 @@
|
|||||||
|
|
||||||
require_once __DIR__."/../vendor/autoload.php";
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This example demonstrates using a 4-button wireless remote control with the
|
||||||
|
* GPIO, in this case with the pins mapped against WiringPi for a Rev2 board.
|
||||||
|
* If you are using this code with any other hardware, please update the mapper
|
||||||
|
* below.
|
||||||
|
*
|
||||||
|
* It is assumed that Pin 0 is the interrupt pin (VT) to signal when a button
|
||||||
|
* press has been received, and Pin 1-4 are connected to the pins for button
|
||||||
|
* A to D on the remote control.
|
||||||
|
*
|
||||||
|
* Note that the Raspberry Pi GPIO is not 5V tolerant, so use an optoisolator
|
||||||
|
* or transistors to ensure that you don't zap your preciouos hardware.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
use NoccyLabs\Gpio\Gpio;
|
use NoccyLabs\Gpio\Gpio;
|
||||||
use NoccyLabs\Gpio\GpioMapper\WiringPiMapper;
|
use NoccyLabs\Gpio\GpioMapper\WiringPiMapper;
|
||||||
|
|
||||||
@ -21,7 +36,12 @@ $led = $gpio[0]
|
|||||||
->setDirection("input")
|
->setDirection("input")
|
||||||
->setEdge("rising")
|
->setEdge("rising")
|
||||||
->setHandler(function($e) use($gpio) {
|
->setHandler(function($e) use($gpio) {
|
||||||
|
if ($gpio[1]->getValue()) { echo "A"; }
|
||||||
|
elseif ($gpio[2]->getValue()) { echo "B"; }
|
||||||
|
elseif ($gpio[3]->getValue()) { echo "C"; }
|
||||||
|
elseif ($gpio[4]->getValue()) { echo "D"; }
|
||||||
|
else { echo "None"; }
|
||||||
|
echo "\n";
|
||||||
})
|
})
|
||||||
->setLabel("rfint")
|
->setLabel("rfint")
|
||||||
->dumpStatus(true);
|
->dumpStatus(true);
|
||||||
@ -33,3 +53,7 @@ for($n = 1; $n < 5; $n++) {
|
|||||||
->dumpStatus(true);
|
->dumpStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
$gpio->refresh();
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
36
lib/Gpio.php
36
lib/Gpio.php
@ -23,6 +23,18 @@ use NoccyLabs\Gpio\Exception\HardwareException;
|
|||||||
|
|
||||||
class Gpio implements \ArrayAccess
|
class Gpio implements \ArrayAccess
|
||||||
{
|
{
|
||||||
|
// Direction
|
||||||
|
const DIR_IN = "in";
|
||||||
|
const DIR_OUT = "out";
|
||||||
|
// Values
|
||||||
|
const VAL_HIGH = 1;
|
||||||
|
const VAL_LOW = 0;
|
||||||
|
// Edges
|
||||||
|
const EDGE_NONE = "none";
|
||||||
|
const EDGE_RISING = "rising";
|
||||||
|
const EDGE_FALLING = "faling";
|
||||||
|
const EDGE_BOTH = "both";
|
||||||
|
|
||||||
protected $gpio = array();
|
protected $gpio = array();
|
||||||
|
|
||||||
/** @var NoccyLabs\Gpio\GpioMapperInterface */
|
/** @var NoccyLabs\Gpio\GpioMapperInterface */
|
||||||
@ -51,7 +63,29 @@ class Gpio implements \ArrayAccess
|
|||||||
$pin->doInterrupt();
|
$pin->doInterrupt();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPinFromFd($fd)
|
||||||
|
{
|
||||||
|
foreach($this->fd_pins as $pinfd=>$pin) {
|
||||||
|
if ($pinfd == $fd) { return $pin; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $fd_gpio = array();
|
||||||
|
protected $fd_pins = array();
|
||||||
|
|
||||||
|
public function enableInterrupt(GpioPin $pin, $fd)
|
||||||
|
{
|
||||||
|
$this->fd_gpio[] = $fd;
|
||||||
|
|
||||||
|
$this->fd_pins[$fd] = $pin;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableInterrupt(GpioPin $pin)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMapper(GpioMapperInterface $mapper=null)
|
public function setMapper(GpioMapperInterface $mapper=null)
|
||||||
@ -64,7 +98,7 @@ class Gpio implements \ArrayAccess
|
|||||||
{
|
{
|
||||||
if ($this->mapper) { $index = $this->mapper->mapLogicalToGpioPin($index); }
|
if ($this->mapper) { $index = $this->mapper->mapLogicalToGpioPin($index); }
|
||||||
if (empty($this->gpio[$index])) {
|
if (empty($this->gpio[$index])) {
|
||||||
$this->gpio[$index] = new GpioPin($index);
|
$this->gpio[$index] = new GpioPin($index, $this);
|
||||||
}
|
}
|
||||||
return $this->gpio[$index];
|
return $this->gpio[$index];
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
namespace NoccyLabs\Gpio;
|
namespace NoccyLabs\Gpio;
|
||||||
|
|
||||||
|
use NoccyLabs\Gpio\Exception\HardwareException;
|
||||||
|
|
||||||
use NoccyLabs\Sansi\Charset as CS;
|
use NoccyLabs\Sansi\Charset as CS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,10 +43,13 @@ class GpioPin
|
|||||||
protected $handler;
|
protected $handler;
|
||||||
|
|
||||||
protected $label;
|
protected $label;
|
||||||
|
|
||||||
|
protected $gpio;
|
||||||
|
|
||||||
public function __construct($pin)
|
public function __construct($pin, Gpio $gpio)
|
||||||
{
|
{
|
||||||
$this->pin = (int)$pin;
|
$this->pin = (int)$pin;
|
||||||
|
$this->gpio = $gpio;
|
||||||
$this->export();
|
$this->export();
|
||||||
$this->fd = fopen("/sys/class/gpio/gpio{$pin}/value", "rb");
|
$this->fd = fopen("/sys/class/gpio/gpio{$pin}/value", "rb");
|
||||||
}
|
}
|
||||||
@ -80,13 +85,24 @@ class GpioPin
|
|||||||
{
|
{
|
||||||
return $this->value;
|
return $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a descriptive label for the pin, used for debugging and troubleshooting.
|
||||||
|
*
|
||||||
|
* @param string $label
|
||||||
|
* @return NoccyLabs\Gpio\GpioPin
|
||||||
|
*/
|
||||||
public function setLabel($label)
|
public function setLabel($label)
|
||||||
{
|
{
|
||||||
$this->label = (string)$label;
|
$this->label = (string)$label;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the assigned label for this pin.
|
||||||
|
*
|
||||||
|
* @return string The label
|
||||||
|
*/
|
||||||
public function getLabel()
|
public function getLabel()
|
||||||
{
|
{
|
||||||
return $this->label;
|
return $this->label;
|
||||||
@ -94,9 +110,9 @@ class GpioPin
|
|||||||
|
|
||||||
public function export()
|
public function export()
|
||||||
{
|
{
|
||||||
@file_put_contents("/sys/class/gpio/export", $this->pin);
|
$this->sysfsWrite(null, "export", $this->pin);
|
||||||
if (!file_exists("/sys/class/gpio/gpio{$this->pin}")) {
|
if (!file_exists("/sys/class/gpio/gpio{$this->pin}")) {
|
||||||
throw new \Exception();
|
throw new HardwareException("Unable to export pin {$this->pin}");
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -107,23 +123,54 @@ class GpioPin
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sysfsWrite($pin, $file, $value)
|
||||||
|
{
|
||||||
|
if ($pin) {
|
||||||
|
$path = "/sys/class/gpio/gpio{$pin}/{$file}";
|
||||||
|
} else {
|
||||||
|
$path = "/sys/class/gpio/{$file}";
|
||||||
|
}
|
||||||
|
if (!is_writable($path)) {
|
||||||
|
throw new HardwareException("Sysfs file {$path} not writable");
|
||||||
|
}
|
||||||
|
$f = fopen($path,"w+");
|
||||||
|
if (!is_resource($f)) {
|
||||||
|
throw new HardwareException("Unable to write to sysfs file {$path}");
|
||||||
|
}
|
||||||
|
fwrite($f,$value);
|
||||||
|
fclose($f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sysfsRead($pin, $file)
|
||||||
|
{
|
||||||
|
$path = "/sys/class/gpio/gpio{$pin}/{$file}";
|
||||||
|
$f = fopen($path,"r");
|
||||||
|
if (!is_resource($f)) {
|
||||||
|
throw new HardwareException("Unable to read from sysfs file {$path}");
|
||||||
|
}
|
||||||
|
$ret = fgets($f);
|
||||||
|
fclose($f);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
public function setEdge($edge)
|
public function setEdge($edge)
|
||||||
{
|
{
|
||||||
if (!in_array($edge, array("rising", "falling", "both", "none"))) {
|
if (!in_array($edge, array("rising", "falling", "both", "none"))) {
|
||||||
throw new \Exception;
|
throw new \Exception;
|
||||||
}
|
}
|
||||||
$this->edge = $edge;
|
$this->edge = $edge;
|
||||||
@file_put_contents("/sys/class/gpio/gpio{$this->pin}/edge", $edge);
|
$this->sysfsWrite($this->pin, "edge", $edge);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEdge()
|
public function getEdge()
|
||||||
{
|
{
|
||||||
return $this->edge;
|
return $this->sysfsRead($this->pin, "edge");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setHandler(callable $handler=null)
|
public function setHandler(callable $handler=null)
|
||||||
{
|
{
|
||||||
|
$this->gpio->setInterruptHandler($this->pin, $this->fd);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user