Slide 1

Slide 1 text

#IPC13 Controlling Arduino With PHP

Slide 2

Slide 2 text

About Me ● Thomas Weinert – @ThomasWeinert ● dimensional GmbH – papaya CMS ● PHP, Javascript, XSLT ● XML Fanatic (JSON is BAD)

Slide 3

Slide 3 text

Arduino

Slide 4

Slide 4 text

Arduino Mega

Slide 5

Slide 5 text

Arduino Nano

Slide 6

Slide 6 text

Arduino Nano Breadboard

Slide 7

Slide 7 text

Arduino Nano Breakout

Slide 8

Slide 8 text

Teensy 3.0

Slide 9

Slide 9 text

Arduino IDE

Slide 10

Slide 10 text

Firmata ● MIDI Based ● Serial Port ● Forks for TCP ● http://firmata.org

Slide 11

Slide 11 text

Firmata StartUp ● Protocol Version ● Firmware Name + Version ● Capabilities – Pin, Mode, Resolution

Slide 12

Slide 12 text

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"

Slide 13

Slide 13 text

Non-Blocking I/O ● Event Loop ● Event Emitter ● Promises

Slide 14

Slide 14 text

Loop vs. Event Loop ● Setup ● Loop – Led on – Wait for 2 seconds – Led off – Wait for 2 seconds ● Setup ● Add 2s interval callback toggling the led ● Run loop

Slide 15

Slide 15 text

Event Loop Listeners/Callbacks Loop External Process External Process File

Slide 16

Slide 16 text

Event Loop ● Timeouts ● Intervals ● Stream Listeners ● Implementations – StreamSelect – LibEvent – MySQLi

Slide 17

Slide 17 text

Browser Example var e = document.getElementById('output'); var counter = 0; var interval = window.setInterval( function() { e.textContent = e.textContent + counter.toString() + ', '; counter++; }, 1000 );

Slide 18

Slide 18 text

Event Emitter Object Event Callback Callback Callback Event Event ● Attach ● on(), once() ● Trigger ● emit()

Slide 19

Slide 19 text

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(); } );

Slide 20

Slide 20 text

Promises ● Asynchronous Condition ● Attach Callbacks – done() – fail() – always() ● Change Status – reject() – resolve()

Slide 21

Slide 21 text

jQuery Example jQuery( function () { jQuery .get('hello-world.xml') .done( function (xml) { $('#output').text( $('data', xml).text() ); } ); } );

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Carica I/O ● Event Loop – Carica\Io\Event\Loop ● Event Emitter – Carica\Io\Event\Emitter ● Promises – Carica\Io\Deferred – Carica\Io\Deferred\Promise

Slide 24

Slide 24 text

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();

Slide 25

Slide 25 text

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);

Slide 26

Slide 26 text

Asynchronous MySQL

Slide 27

Slide 27 text

HTTP Server Why?

Slide 28

Slide 28 text

HTTP Server ● PHP Daemons – Single process for all requests – Share variables

Slide 29

Slide 29 text

Web Interfaces for Firmata

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Carica Firmata

Slide 32

Slide 32 text

Carica Firmata Board activate() ->done( function () use ($board) { ... } ); Carica\Io\Event\Loop\Factory::run();

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Example: Blink OOP function () use ($board, $loop) { $pin = $board->pins[13]; $pin->mode = Firmata\Board::PIN_MODE_OUTPUT; $loop->setInterval( function () use ($pin) { $pin->digital = !$pin->digital; echo 'LED: '.($pin->digital ? 'on' : 'off')."\n"; }, 1000 ); }

Slide 35

Slide 35 text

Carica Firmata Pins ● Properties – int $mode – bool $digital – float $analog – array $supports – int $value – int $maximum ● events – on('change', ...) – on('change-mode, ...) – on('change-value, ...)

Slide 36

Slide 36 text

RGB Wheel

Slide 37

Slide 37 text

Carica Chip ● Hardware Abstraction ● Device Objects

Slide 38

Slide 38 text

LED function () use ($board) { $led = new Carica\Chip\Led( $board->pins[9] ); $led->blink(); }

Slide 39

Slide 39 text

RGB LED function () use ($board) { $colors = array('#F00', '#0F0', '#00F'); $index = 0; $led = new Carica\Chip\Led\Rgb( $board->pins[20], $board->pins[21], $board->pins[22] ); $led->setColor('#000'); $next = function() use ($led, $colors, &$index, &$next) { ... }; $next(); }

Slide 40

Slide 40 text

RGB LED function () use ($board) { … $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(); }

Slide 41

Slide 41 text

Analog Sensor function () use ($board) { $sensor = new Carica\Chip\Sensor\Analog( $board->pins[16] ); $sensor->onChange( function (Carica\Chip\Sensor\Analog $sensor) { echo $sensor, ' '; echo str_repeat('=', 60 * $sensor->get()); echo "\n"; } ); }

Slide 42

Slide 42 text

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(); }

Slide 43

Slide 43 text

Drive

Slide 44

Slide 44 text

Thank You ● Questions? ● Twitter: @ThomasWeinert ● Blog: http://a-basketful-of-papayas.net