PHPUCHH 2013: Controlling Arduino With PHP

3f2fb8bbcd44609346e1cc0c06d0a39b?s=47 Thomas Weinert
September 24, 2013

PHPUCHH 2013: Controlling Arduino With PHP

Slides from the PHP Unconference Hamburg 2013

3f2fb8bbcd44609346e1cc0c06d0a39b?s=128

Thomas Weinert

September 24, 2013
Tweet

Transcript

  1. PHPUCHH 2013 Controlling Arduino With PHP

  2. About Me • Thomas Weinert – @ThomasWeinert • papaya Software

    GmbH – papaya CMS • PHP, Javascript, XSLT • XML Fanatic (JSON is BAD)
  3. Arduino

  4. Arduino Mega

  5. Arduino Nano

  6. Arduino Nano Breadboard

  7. Arduino Nano Breakout

  8. Teensy 3.0

  9. Arduino IDE

  10. Firmata • MIDI Based • Serial Port – Forks for

    TCP • http://firmata.org
  11. Firmata StartUp • Protocol Version • Firmware Name + Version

    • Capabilities – Pin, Mode, Resolution
  12. Byte Stream "\xF9\x03\x02". // Version "\xF0\x79". // Firmware "\x02\x03". //

    Firmware version "\x53\x00\x61\x00\x6D\x00\x70\x00\x6C\x00\x65\x00". // Firmware string "\xF7". "\xF0\x6C". // Capabilities Response "\x00\x01\x01\x01\x03\x08\x04\x0e\x7f". // pin 0 "\x00\x01\x01\x01\x02\x0a\x06\x01\x7f". // pin 1 "\xF7". "\xF0\x6A". // Analog Mapping Response "\x7F\x00". "\xF7"
  13. Non-Blocking I/O • Event Loop • Event Emitter • Promises

  14. Event Loop Listeners Loop External Process External Process File

  15. Event Loop • Timeouts • Intervals • Stream Listeners •

    Implementations – StreamSelect – LibEvent – MySQLi
  16. Browser Example var e = document.getElementById('output'); var counter = 0;

    var interval = window.setInterval( function() { e.textContent = e.textContent + counter.toString() + ', '; counter++; }, 1000 );
  17. Event Emitter Object Event Callback Callback Event Callback Event Event

    • Attach • on(), once() • Trigger • emit()
  18. Event Emitter Example $stream = new Stream\File('c:/tmp/sample.txt'); $stream->events()->on( 'read-data', function($data)

    { echo $data; } ); $stream->events()->on( 'error', function($error) use ($loop) { echo $error; $loop->stop(); } );
  19. Promises • Asynchronous Condition • Attach Callbacks – done() –

    fail() – always() • Change Status – reject() – resolve()
  20. jQuery Example jQuery( function () { jQuery .get('hello-world.xml') .done( function

    (xml) { $('#output').text( $('data', xml).text() ); } ); } );
  21. Carica Projects • Carica I/O – https://bitbucket.org/ThomasWeinert/carica-io • Carica Firmata

    – https://bitbucket.org/ThomasWeinert/carica-firmata • Carica Chip – https://bitbucket.org/ThomasWeinert/carica-chip
  22. Carica I/O • Event Loop – Carica\Io\Event\Loop • Event Emitter

    – Carica\Io\Event\Emitter • Promises – Carica\Io\Deferred – Carica\Io\Deferred\Promise
  23. Timers $loop = Loop\Factory::get(); $i = 0; $loop->setInterval( function ()

    use (&$i) { echo $i++; }, 1000 ); $loop->setTimeout( function () use ($loop) { $loop->stop(); }, 10000 ); $loop->run();
  24. Asynchronous MySQL $mysqlOne = new Io\Deferred\MySQL( new mysqli('localhost') ); $mysqlTwo

    = new Io\Deferred\MySQL( new mysqli('localhost') ); $time = microtime(TRUE); $debug = function($result) use ($time) { var_dump(iterator_to_array($result)); var_dump(microtime(TRUE) - $time); }; $queries = Io\Deferred::When( $mysqlOne("SELECT 'Query 1', SLEEP(5)") ->done($debug), $mysqlTwo("SELECT 'Query 2', SLEEP(1)") ->done($debug) ); Io\Event\Loop\Factory::run($queries);
  25. Asynchronous MySQL

  26. HTTP Server Why?

  27. HTTP Server • PHP Daemons – Single process for all

    requests – Share variables
  28. Carica HTTP Server <?php include(__DIR__.'/../../src/Carica/Io/Loader.php'); Carica\Io\Loader::register(); use Carica\Io\Network\Http; $route =

    new Carica\Io\Network\Http\Route(); $route->startsWith( '/files', new Http\Route\File(__DIR__) ); $server = new Carica\Io\Network\Http\Server($route); $server->listen(8080); Carica\Io\Event\Loop\Factory::run();
  29. Carica Firmata

  30. Carica Firmata Board <?php $board = new Firmata\Board( new Io\Stream\Serial(

    CARICA_FIRMATA_SERIAL_DEVICE, CARICA_FIRMATA_SERIAL_BAUD ) ); $board ->activate() ->done( function () use ($board) { ... } ); Carica\Io\Event\Loop\Factory::run();
  31. Carica Firmata Pins function () use ($board) { $buttonPin =

    2; $ledPin = 13; $board->pins[$buttonPin]->mode = Firmata\PIN_STATE_INPUT; $board->pins[$ledPin]->mode = Firmata\PIN_STATE_OUTPUT; $board->digitalRead( $buttonPin, function($value) use ($board, $ledPin) { $board->pins[$ledPin]->digital = $value == Firmata\DIGITAL_HIGH; } ); }
  32. Example: Blink function () use ($board, $loop) { $led =

    9; $board->pinMode($led, Firmata\PIN_STATE_OUTPUT); $loop->setInterval( function () use ($board, $led) { static $ledOn = TRUE; echo 'LED: '.($ledOn ? 'on' : 'off')."\n"; $board->digitalWrite( $led, $ledOn ? Firmata\DIGITAL_HIGH : Firmata\DIGITAL_LOW ); $ledOn = !$ledOn; }, 1000 ); }
  33. RGB Wheel

  34. Carica Chip • Hardware Abstraction • Device Objects

  35. LED function () use ($board) { $led = new Carica\Chip\Led(

    $board->pins[9] ); $led->blink(); }
  36. RGB LED function () use ($board) { $colors = array('#F00',

    '#0F0', '#00F'); $led = new Carica\Chip\Led\Rgb( $board->pins[20], $board->pins[21], $board->pins[22] ); $led->setColor('#000'); $index = 0; $next = function() use ($led, $colors, &$index, &$next) { if (isset($colors[$index])) { $color = $colors[$index]; $led->fadeTo($color)->done($next); } if (++$index >= count($colors)) { $index = 0; } }; $next(); }
  37. Servo function () use ($board, $loop) { $positions = array(

    0, 45, 90, 180 ); $servo = new Carica\Chip\Servo($board->pins[7], -180); $index = 0; $loop->setInterval( $next = function () use ($servo, $positions, &$index) { if (isset($positions[$index])) { $position = $positions[$index]; $servo->moveTo($position); echo $position, " Grad , ", $servo->getPosition(), " Grad\n"; } if (++$index >= count($positions)) { $index = 0; } }, 2000 ); $next(); }
  38. Analog Sensor function () use ($board) { $sensor = new

    Carica\Chip\Sensor\Analog( $board->pins[14] ); $sensor->onChange( function ($sensor) { echo $sensor, "\n"; } ); }
  39. Thank You • Questions? • Twitter: @ThomasWeinert • Blog: http://a-basketful-of-papayas.net