Controlling Arduino With PHP

Controlling Arduino With PHP

PHPSummit - September 2014

3f2fb8bbcd44609346e1cc0c06d0a39b?s=128

Thomas Weinert

October 07, 2014
Tweet

Transcript

  1. ARDUINO WITH PHP CONNECTIONS TO THE PHYSICAL WORLD @ThomasWeinert

  2. ARDUINO Arduino is an open-source electronics prototyping platform based on

    flexible, easy-to- use hardware and software. It's intended for artists, designers, hobbyists and anyone interested in creating interactive objects or environments.
  3. ARDUINO UNO

  4. ARDUINO MEGA

  5. SHIELDS HTTP://SHIELDLIST.ORG/

  6. NETWORK

  7. PROTOTYPE

  8. MOTOR

  9. ARDUINO NANO

  10. NANO ON BREADBOARD

  11. NANO ON BASE

  12. BREADBOARD

  13. BREADBOARD HALFSIZE

  14. BREADBOARD SCHEMA

  15. BREADBOARD IN USE

  16. BREADBOARD IN USE

  17. FRITZING http://fritzing.org 1 1 5 5 10 10 15 15

    20 20 25 25 30 30 A A B B C C D D E E F F G G H H I I J J
  18. ARDUINO IDE

  19. None
  20. FIRMATA

  21. FIRMATA PROTOCOL Midi Based Pin Status Pin Manipulation Extended Commands

  22. FIRMATA TEST

  23. FIRMATA TEST PHP

  24. None
  25. PHP - SERIAL PORTS + Just streams - Console commands

    for configuration
  26. WINDOWS - fread() blocks until it gets data.

  27. SERPROXY

  28. GORILLA PHPMAKE\SERIALPORT https://github.com/oasynnoum/phpmake_serialport

  29. FIRST PROJECT

  30. COMPOSER CREATE composer create-project carica/chip-skeleton led --stability=dev

  31. None
  32. CONFIGURE BOOTSTRAP /** * serial - serial connection * tcp

    - tcp connection (network shield or serproxy) */ define('CARICA_FIRMATA_MODE', 'serial'); define('CARICA_FIRMATA_SERIAL_DEVICE', '/dev/tty0'); define('CARICA_FIRMATA_SERIAL_BAUD', 57600); define('CARICA_FIRMATA_TCP_SERVER', '127.0.0.1'); define('CARICA_FIRMATA_TCP_PORT', 5339);
  33. SKELETON $board = include(__DIR__.'/bootstrap.php'); use Carica\Chip as Chip; $board ->activate()

    ->done( function () use ($board) { // Start here! } ); Carica\Io\Event\Loop\Factory::run();
  34. LED OBJECT $board = include(__DIR__.'/bootstrap.php'); use Carica\Chip as Chip; $board

    ->activate() ->done( function () use ($board) { $led = new Chip\Led($board->pins[13]); $led->strobe(2000)->on(); } ); Carica\Io\Event\Loop\Factory::run();
  35. Io Event Loop Server Firmata Protocol Chip Devices 010001000100 111000111000

    011111110001 100100100111 100100101100 001100110110
  36. CARICA CHIP $led = new Carica\Chip\Led($board->pins[13]); $led->strobe()->on();

  37. CARICA CHIP $led = new Carica\Chip\Led($board->pins[13]); $led->pulse()->on();

  38. CARICA CHIP $led = new Carica\Chip\Led($board->pins[13]); $led->brightness(0.5)->pulse()->on();

  39. CARICA FIRMATA $board ->activate() ->done( function () use ($board) {

    $led = new Carica\Chip\Led($board->pins[13]); $led->strobe()->on(); } ); Carica\Io\Event\Loop\Factory::run();
  40. BASIC BLINK $board->pinMode(13, 0x01); while (TRUE) { $board->digitalWrite(13, 0xFF); sleep(1);

    $board->digitalWrite(13, 0x00); sleep(1); }
  41. BASIC BLINK OOP $board->pins[13]->mode = Carica\Firmata\Pin::MODE_OUTPUT; while (TRUE) { $board->pins[13]->digital

    = !$board->pins[13]->digital; sleep(1); }
  42. BLINK NONBLOCKING $loop = Io\Event\Loop\Factory::get(); $board ->activate() ->done( function ()

    use ($board, $loop) { $pin = $board->pins[13]; $pin->mode = Firmata\Pin::MODE_OUTPUT; $loop->setInterval( function () use ($pin) { $pin->digital = !$pin->digital; }, 1000 ); } ); $loop->run();
  43. CARICA IO Event Loop Event Emitter Promises

  44. EVENT LOOP

  45. JAVASCRIPT EXAMPLE var e = document.getElementById('output'); var counter = 0;

    var interval = window.setInterval( function() { e.textContent = e.textContent + counter.toString() + ', '; counter++; }, 1000 );
  46. PHP EXAMPLE $loop = Carica\Io\Event\Loop\Factory::get(); $loop->setInterval( function () { static

    $i = 0; echo $i++; }, 1000 ); $loop->run();
  47. PROMISES They describe an object that acts as a proxy

    for a result that is initially unknown, usually because the computation of its value is yet incomplete.
  48. JAVASCRIPT EXAMPLE jQuery .get('hello-world.xml') .done( function (xml) { alert('loaded.'); }

    ) );
  49. PHP EXAMPLE $mysqlOne = new Carica\Io\Deferred\MySQL(new mysqli('localhost')); $mysqlTwo = new

    Carica\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 = Carica\Io\Deferred::When( $mysqlOne("SELECT 'Query 1', SLEEP(5)") ->done($debug), $mysqlTwo("SELECT 'Query 2', SLEEP(1)") ->done($debug) ); Carica\Io\Event\Loop\Factory::run($queries);
  50. EVENT EMITTER $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(); } );
  51. INTERACTION

  52. HTTPSERVER use Carica\Io\Network\Http; $route = new Http\Route(); $route->match( '/hello/{name}', function

    (Http\Request $request, $parameters) { $response = $request->createResponse( new Http\Response\Content\String( "Hello ".$parameters['name']."!\n" ) ); return $response; } );
  53. FILES $route->match('/hello', new Http\Route\File(__DIR__.'/files/hello.html')); $route->startsWith('/files', new Http\Route\Directory(__DIR__)); $server = new

    Carica\Io\Network\Http\Server($route); $server->listen(8080);
  54. INTERACTIVE LED

  55. HTML FILE <!DOCTYPE html> <html> <head> <title>Led Switch</title> </head> <body>

    <form action="./switch/on" target="iframe"> <button type="submit">On</button> </form> <form action="./switch/off" target="iframe"> <button type="submit">Off</button> </form> <iframe style="width: 200px; height: 40px; border: none;" src="about:blank" name="iframe"></ifra </body> </html>
  56. PHP SERVER use Carica\Io\Network\Http; $board ->activate() ->done( function () use

    ($board) { $led = new Carica\Chip\Led($board->pins[20]); $route = new Http\Route(); $route->match( '/switch/{state}', function (Http\Request $request, array $parameters) use ($led) { if ($parameters['state'] == 'on') { $led->on(); $message = 'ON'; } else { $led->off(); $message = 'OFF'; } $response = $request->createResponse(); $response->content = new Http\Response\Content\String( $message, 'text/plain; charset=utf-8' ); return $response; } ); $route->match('/', new \Carica\Io\Network\Http\Route\File(__DIR__.'/index.html')); $server = new Carica\Io\Network\Http\Server($route);
  57. COLOR CIRCLE

  58. SERVER function () use ($board) { $led = new Carica\Chip\Rgb\Led(

    $board->pins[3], $board->pins[5], $board->pins[6] ); $route = new Carica\Io\Network\Http\Route(); $route->match( '/rgb', function (Http\Request $request) use ($led) { $color = isset($request->query['color']) ? $request->query['color'] : '#000'; $led->color($color)->on(); $response = $request->createResponse(); $response->content = new Http\Response\Content\String( 'Color: '.$color ); return $response; } ); $route->startsWith('/files', new Http\Route\Directory(__DIR__)); $route->match('/', new Http\Route\File(__DIR__.'/index.html')); $server = new Carica\Io\Network\Http\Server($route); $server->listen(8080); }
  59. REACTPHP { "require": { "react/react": "0.4.*" } }

  60. RATCHET { "require": { "cboden/ratchet": "0.3.*" } }

  61. SENSOR PHALANX 1:07

  62. SHIFTOUT()

  63. SHIFTOUT() $loop->setInterval( function () use ($board, $latchPin, $clockPin, $dataPin) {

    static $number = 0; $latchPin->digital = FALSE; $board->shiftOut($dataPin->pin, $clockPin->pin, $number); $latchPin->digital = TRUE; if (++$number > 255) { $number = 0; } }, 1000 );
  64. SHIFTOUT() 0:15

  65. 7 SEGMENT DISPLAYS

  66. 7 SEGMENT DISPLAYS $loop->setInterval( function () use ( $board, $latchPin,

    $clockPin, $dataPin, $numbers, $segments ) { static $number = 0; $digits = str_pad($number, $segments, 0, STR_PAD_LEFT); $bytes = []; for ($i = strlen($digits) - 1; $i >= 0; $i--) { $bytes[] = 0xFF ^ (int)$numbers[$digits[$i]]; } $latchPin->digital = FALSE; $board->shiftOut( $dataPin->pin, $clockPin->pin, $bytes ); $latchPin->digital = TRUE; if (++$number > (pow(10, $segments) - 1)) { $number = 0; } }, 100 );
  67. 7SEG DISPLAYS 0:05

  68. MAX7219 8 Digit - 7Segment Display 8x8 Matrix Displays

  69. $max = new Carica\Chip\Max7219\Matrix( $board, 11, 12, 8 ); $displayCount

    = 4; for ($i = 0; $i < $displayCount; $i++) { $max->addDisplay($i * 8, 0); } $image = imagecreatefrompng(__DIR__.'/elephpant-animation.png'); $max->scrollX($image, -17, 150)->brightness(0.5)->on();
  70. 0:00

  71. THANKS