2013-06-20

Basics: Using Arduino From PHP

Own Protocol Inside A PHP Page.

This is the version mostly described on the net. For example on Instructables. Basically you write an Arduino Scetch that listens and send plain text data on the serial port. A PHP Script triggered by a webserver request opens the port communicates with the Arduino board an outputs some HTML.

The major downside of this approach is that many Arduino boards reset if the serial port is opened. So the startup and configuration has to be done any time the PHP scripts reads some data or triggers an action. Because the PHP script stops after the page request any data has to be stored in a database, cache or file.

Firmata

Firmata is a generic sketch for Arduino boards that implements an MIDI based protocol. Here are client libraries for several languages. For example Johnny Five for Javascript (Node.js) implements abstraction not only for the communication but for hardware elements. For example you get an led object with blink() and fade() methods.

Firmata Inside A PHP Page. 

Well, It is possible but you don't want to do that. Firmata has a little more complex startup process that takes about two seconds. To much to use it in a web request.

Firmata Over TCP

The official version of Firmata uses the serial port. But here are forks that can use TCP. You need an compatible network shield for your Arduino board and the version may be a little behind the offical one.

Non-Blocking I/O

Node.js uses an concept called Non-blocking I/O or Asynchronous I/O. Basically it means that you add actions to an event loop, trigger events from you objects that execute attached callbacks. Doesn't sound familiar? If you ever programmed some Javascript for your web pages, you used this concept. Each browser window has an event loop. Functions like "window.setTimeout()" add event to the loop. The browser fires event on the page elements that execute callbacks, if you attached them, too.

So using this concept you describe what should happen if an events is triggered and a certain conditions are meet. In classic PHP you work with the current state. In Non-Blocking I/O the result has yet to be calculate at a future time.

Procedual Programming:
If the result of action x is value y now do that.
Non-Blocking I/O
If the result of action x will be y you will have to do that.

Thinking like this is much better suited to hardware control, at the moment you are programming you do not now if somebody will ever press the button on your Arduino device or which values the sensor your connected will send.

Non-Blocking I/O in PHP

PHP has no default event loop implemented but here are several possibilities for it. First it whould be possible just using an while loop and usleep(). This would not be very efficient. Better is an combination of this with stream_select(). The "stream_select()" function  is like a usleep() that monitors streams and return imminently if a stream is changed. It even says which stream is changed how, so it is possible to trigger the exact events for this stream.

Event more efficient is using libevent. PHP has an extension for this event loop implementation. It is used inside the Chrome browser browser and Node.js, too.

Libraries For PHP

Here are libraries in PHP that implement event loops.

ReactPHP
ReactPHP is the most mature project implementing Non-Blocking I/O for PHP. It a general purpose library and has additional components. You can read more about it on reactphp.org.

Carica Io
Caica Io is an implementation I created as a base for Carica Firmata, a client library for the Firmata protocol. It can used separately if you're going to implement your own protocol, too. Here is an basic example with timers:


The event loop uses the API not unlike the Browser. The main difference to Javascript in the Browser or Node.js is that you have to run the event loop explicitly.

Carica Firmata

The Firmata test application
in Carica Firmata
Based on Carica Io, it allows you to create programs that control the Arduino board. They run without an webserver (like Apache HTTP, Nginx, ...). They can even contain an (simple) webserver to control the script from a browser. The php program is started from the command line and runs continuously until you stop it (or it crashes :-) ). The serial connection to the board is opened only once, no reset happens and the start up time is not an issue.

Blink

The "Hello World" for an Arduino is an blinking led. Wait for the board to activate, and add an interval (repeated timer) that switches it on and off.


Dimmer

Carica Firmata can read data, too. Simple attach an callback to the board. On the analog pin this could be a potentiometer dimming an led. The examples uses an OOP api for the pins. The main difference to calling the methods on the board object directly is that values and the mode are only send if the are changed.

On Windows

On Windows the  serial port is seriously broken at the moment. It can not work non-blocking. Any reading action will block your script until it recieves data. One solution is Serpoxy, a little program that maps the serial port to tcp.

Links

2012-07-31

What Iterators Can Do For You

Basically Iterators provide a list interface for an object. Like all interfaces they are a contract how something can be used. If you use an interface it is not relevant how it is implemented - the implementation logic is encapsulated.

It is of course relevant on the integration level. A bad implementation can impact the performance of you application. Even an good implementation may need special resources (like a database). But all this does not impact how you use it. Your code using the object with the Iterator interface stays the same.

Let's start with a simple example that outputs a list.

$elements = array(
  'line one', 'line two'
);

foreach ($lines as $key => $value) {
  echo $key.': '.$value."\n";
}


If we transfer this into an object it would like that:

class MyProjectLineOutput {
  private $_lines = NULL;

  public function __construct($lines) {
    $this->_lines = $lines;
  }

  public function __invoke() {
    foreach ($this->_lines as $key => $value) {
      echo $key.': '.$value."\n";
    }
  }
}

$output = new MyProjectLineOutput(
  array(
    'line one', 'line two'
  )
);
$output();


On the first glance that looks like a lot more work but it isn't. The code includes two tasks. Get the lines and output them. The class encapsulates the output task and makes it reusable. In this simple example that may look superfluous but think a little larger. Like output an select-field or csv.

Encapsulate file()


Still we haven't used an Iterator, but just encapsulated the output. PHP provides several default iterators and one of them is the ArrayIterator.

$output = new MyProjectLineOutput(
  new ArrayIterator(
    array(
      'line one', 'line two'
    )
  )
);
$output();


The ArrayIterator just takes an array and makes it an Iterator. It is mostly used to implement another interface - IteratorAggregate. Both the "Iterator" and the "IteratorAggregate" interfaces inherit from a common ancestor named "Traversable". You can not implement "Traversable" directly but use it to validate if an object is traversable or in other words can be used with foreach.

Now let's load the lines from a file.

class MyProjectFile implements IteratorAggregate {
  private $_file;

  public function __construct($file) {
    $this->_file = $file;
  }

  public function getIterator() {
    return new ArrayIterator(file($this->_file));
  }
}

$output = new MyProjectLineOutput(
  new MyProjectFile('sample.txt')
);
$output();


The main difference between using file directly to this is that the file() is accessed later in the process. The foreach() inside the MyProjectLineOutput::output() method calls MyProjectFile::getIterator(). Until then we can pass the instance of MyProjectFile around without loading the file into memory. Unlike a direct call to file() we don't pass the concrete data around but an information how it can be obtained.

Iterating A Text File


Implementing Iterator we can make sure that only a part of the file needs to be loaded.

class MyProjectFileUnbuffered implements Iterator {
  private $_file;
  private $_handle = NULL;
  private $_key = -1;
  private $_current = NULL;

  public function __construct($file) {
    $this->_file = $file;
  }

  public function __destruct() {
    if (is_resource($this->_handle)) {
      fclose($this->_handle);
    }
  }

  public function rewind() {
    if (!is_resource($this->_handle)) {
      $this->_handle = fopen($this->_file, 'r');
    } else {
      fseek($this->_handle, 0);
    }
    $this->_key = -1;
    $this->next();
  }

  public function next() {
    if ($this->_key > 0 or $this->_current !== FALSE) {
      $this->_current = fgets($this->_handle);
      $this->_key++;
    }
  }

  public function key() {
    return $this->_key;
  }

  public function current() {
    return $this->_current;
  }

  public function valid() {
    return $this->_current !== FALSE;
  }
}


This is more source then implementing it directly. Mostly because of the class and function declarations. But you have to write this only once. And it can be improved or replaced without affecting the usage.

Map Elements

Using iterators you can encapsulate mapping actions, like using array_map() on an array but only for elements that are read. Let's say you need to chop all trailing whitespaces from the lines.

Step One: Map Iterator:


class MyProjectMapIterator implements OuterIterator {

  private $_innerIterator = NULL;
  private $_callback = NULL;

  public function __construct(Iterator $innerIterator, $callback) {
    $this->_innerIterator = $innerIterator;
    $this->_callback = $callback;
  }

  public function map($current, $key) {
    return call_user_func($this->_callback, $current, $key);
  }

  public function getInnerIterator() {
    return $this->_innerIterator;
  }

  public function rewind() {
    $this->getInnerIterator()->rewind();
  }

  public function next() {
    $this->getInnerIterator()->next();
  }

  public function key() {
    return $this->getInnerIterator()->key();
  }

  public function current() {
    return $this->map(
      $this->getInnerIterator()->current(),
      $this->getInnerIterator()->key()
    );
  }

  public function valid() {
    return $this->getInnerIterator()->valid();
  }
}


OuterIterator is an interface for iterators that wraps other iterators, it is defined in the SPL. It extends the Iterator interface. The MapIterator is an iterator of that kind, so it is cleaner to implement it that way.

Step Two: Using The Map Iterator:

Using the map iterator is not unlike using array_map.

$output = new MyProjectLineOutput(
  new MyProjectMapIterator(
    new MyProjectFile('sample.txt'),
    function($current, $key) {
      return chop($current);
    }
  )
);
$output();


The file() function has an option to do this. But it is limited to exactly this task. With MapIterator you get a lot more flexibility. You could even extend the MapIterator to get reusable mappings.

Step Three: Extending the Map Iterator

class MyProjectMapIteratorUpper extends MyProjectMapIterator {

  public function __construct(Iterator $innerIterator) {
    parent::__construct(
      $innerIterator,
      function($current, $key) {
        return strToUpper($current);
      }
    );
  }
}

Filter Elements:

Here is another option for file(), that skips empty lines. This would be filter task and here is already an superclass for that in SPL.

class MyProjectFilterIteratorSkipEmptyLines extends FilterIterator {

  public function accept() {
    return trim($this->getInnerIterator()->current()) !== '';
  }
}

Conclusion

Iterators are not about writing less code at one time. But they help you to write source that is encapsulated, easy to test and reusable. Because of this over time you will end up with less code.

2012-07-30

Using The PHP 5.4 Webserver On Windows

Starting a server from the command line
PHP 5.4 has an built-in webserver. For local development it is not necessary to install Apache Httpd or another webserver anymore. You can just start an server from the command line.

Change the directory to your project directory. The argument -S starts the webserver. You need to specify a host and a port. All requests are shown in the console window.

A Shortcut

To make things a little easier you can create a windows shortcut. This allows you to change the console window size, font and color, too. The following pictures show the particular steps:
Step 1: Create A Shortcut
Step 2: Select the PHP binary
Step 3: Name the shortcut
Step 4: Change command and working directory
Step 5: Change the window size
x