Raspberry Pi – PHP GPIO Model

 

I finally have the php Raspberry Pi GPIO Model in a decent state and I though I would share.  eLinux.org has a simple example using bash that I was able to use to build the php model. I replaced the shell commands with direct php writes for the pins and it runs much faster.

File: gpio_model.php

<?php
/*
 * GPIO Model.
 *
 * This file has all the methods required for accessing GPIO pins for the Raspberry Pi
 *
 * PHP 5
 * Copyright 2012, J.C. Highlight Productions (http://jchighlightpro.com)
 *
 * Licensed under The GNU GPL
 * This  program  is  free  software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the  Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version. This program is distributed in the hope that it
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * @copyright     Copyright 2012, J.C. Highlight Productions (http://jchighlightpro.com)
 * @link          http://www.jchighlightpro.com/home-automation/
 * @license       GNU GPL License (http://www.gnu.org/licenses/gpl.html)
*/

class gpio_model{

	private $_base_path;
	private $_mapped_pins;
	private $_write_delay; // for usleep functions, No longer used.

	/**
	 * Construct that sets up the gpio interface. Uses mapped pins and executes exports through cli.
	 * @param array $mPins map of pins to direction example:$mPins = array(22=>"in",17=>"out",4=>"out");
	 * @param string $path path to the gpio file structure "/sys/class/gpio"
	 */
	public function __construct($mPins = false, $path = "/sys/class/gpio"){
		if($mPins!=false){
			$this->_base_path  = $path;
			$this->_mapped_pins = $mPins;
			$this->_write_delay = 500; 

			foreach($this->_mapped_pins as $pin => $direction){
				$this->activate_pin($pin);				//activate each of the pins we are setting up
				$this->set_direction($pin,$direction);	//set initial direction
			}
		}

	}

	/**
	 * Returns an array of active pins
	 * @return array:
	 */
	public function get_pins(){
		return $this->_mapped_pins;
	}

	/**
	 * Activates specific pin
	 * @param int $pin actual pin number
	 */
	public function activate_pin($pin){
		$this->write($this->_base_path."/export", $pin);//export sets up the directories
	}

	/**
	 * set_direction writes the appropriate direction to the GPIO file path
	 * @param string $direction "in" or "out"
	 */
	public function set_direction($pin, $direction){
		$this->write($this->_base_path."/gpio".$pin."/direction", $direction);
	}

	/**
	 * Set the pin to the specific value. Value is defined as HIGH, LOW
	 * @param int $pin
	 * @param constant $value HIGH or LOW
	 */
	public function set_value($pin, $value = LOW){
		$this->write($this->_base_path."/gpio".$pin."/value", $value);
		//usleep($this->_write_delay);
	}

	/**
	 * Removes the directory structure for the specific pins
	 * @param int $pin
	 */
	public function remove_pin($pin){
		$this->write($this->_base_path."/unexport", $pin);//export sets up the directories
	}

	/**
	 * Get the current value of the pin specified
	 * @param int $pin
	 * @return number
	 */
	public function get_value($pin){
		return $this->read($this->_base_path."/gpio".$pin."/value"); // do we need to flip the bit? Should we look HIGH or LOW
	}

	/**
	 * Get status from all predefined pins in the $this->_mapped_pins array
	 * @param string $type Can be json or array
	 * @return string/array
	 */
	public function get_status_all($type="array")
	{
		$data = array();

		foreach($this->_mapped_pins as $pin => $value)
			$data[$pin] = $this->get_status($pin);

		if($type=="json"){
			return json_encode($data);
		}
		elseif($type=="array"){
			return $data;
		}
	}

	/**
	 * Loops through each of the mappedPins and unexports them.
	 */
	function __destruct() {
		foreach($this->_mapped_pins as $pin => $direction){
			$this->remove_pin($pin);				//unexport the gpio directories
		}
	}

	////////////////////// Lower level functions /////////////////////////////

	public function read($path)
	{
		//read the contents of the file
		return file_get_contents ($path);
	}

	public function write($path, $value)
	{
		// Write the contents back to the file
		file_put_contents($path, $value);
	}

	////////////////////////// Test Functions ///////////////////////////////
	public function all_on()
	{
		foreach ($this->_mapped_pins as $pin => $value){
			$this->set_value($pin, HIGH);
		}
	}

	public function all_off()
	{
		foreach ($this->_mapped_pins as $pin => $value){
			$this->set_value($pin, LOW);
		}
	}

	public function test($delay = 1)
	{
		foreach ($this->_mapped_pins as $pin => $value)
		{
			$this->set_value($pin, HIGH);
			sleep(1);
			$this->set_value($pin, LOW);
		}

	}
}
?>

Now we just need to test it out. Using PHP CLI as root:

File: test.php

#!/usr/bin/php -q
'out',17=>'out',21=>'out',24=>'in');

$gpio = new gpio_model($pins);

//Write to individual pin
$gpio->set_value(4,HIGH);

//Read Pin
$pin_24_value = $gpio->get_value(24);

//loop through pins
for($i=0;$i<100;$i++){ 	
	foreach($pins as $key => $value){
		$gpio->set_value($key,HIGH);
		sleep(1);
	}
	foreach($pins as $key => $value){
		$gpio->set_value($key,LOW);
		sleep(1);
	}
}

?>

I’d like to find a way to use this without being root. If anyone has any ideas, please let me know.

I hope someone will find this useful. Let me know what you think.

Leave a Reply

Your email address will not be published. Required fields are marked *


1 + = five

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>