Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
IPC 2013: Controlling Arduino With PHP
Search
Thomas Weinert
October 30, 2013
Programming
270
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
IPC 2013: Controlling Arduino With PHP
Thomas Weinert
October 30, 2013
More Decks by Thomas Weinert
See All by Thomas Weinert
Build Automation with Phive and Phing
thomasweinert
0
290
Introduction: PHP Extensions
thomasweinert
2
880
PCRE - Matching Patterns
thomasweinert
0
170
Controlling Arduino With PHP
thomasweinert
2
600
PCRE With PHP
thomasweinert
0
820
Modern PHP
thomasweinert
3
260
Controlling Arduino With PHP
thomasweinert
1
190
XPATH WITH PHP AND JS
thomasweinert
0
160
PHPUG CGN: Arduino With PHP
thomasweinert
0
160
Other Decks in Programming
See All in Programming
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
140
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
630
その節約、円になってますか?
isamumumu
1
720
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
140
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
470
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
180
Google Apps Script で Ruby を動かす
kawahara
0
140
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
210
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
210
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
140
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
250
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
210
Featured
See All Featured
Evolving SEO for Evolving Search Engines
ryanjones
0
250
Darren the Foodie - Storyboard
khoart
PRO
3
3.6k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
200
Side Projects
sachag
455
43k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
Mobile First: as difficult as doing things right
swwweet
225
10k
A Soul's Torment
seathinner
6
3.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Leo the Paperboy
mayatellez
8
2.1k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.3k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
Transcript
#IPC13 Controlling Arduino With PHP
About Me • Thomas Weinert – @ThomasWeinert • dimensional GmbH
– papaya CMS • PHP, Javascript, XSLT • XML Fanatic (JSON is BAD)
Arduino
Arduino Mega
Arduino Nano
Arduino Nano Breadboard
Arduino Nano Breakout
Teensy 3.0
Arduino IDE
Firmata • MIDI Based • Serial Port • Forks for
TCP • http://firmata.org
Firmata StartUp • Protocol Version • Firmware Name + Version
• Capabilities – Pin, Mode, Resolution
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"
Non-Blocking I/O • Event Loop • Event Emitter • Promises
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
Event Loop Listeners/Callbacks Loop External Process External Process File
Event Loop • Timeouts • Intervals • Stream Listeners •
Implementations – StreamSelect – LibEvent – MySQLi
Browser Example var e = document.getElementById('output'); var counter = 0;
var interval = window.setInterval( function() { e.textContent = e.textContent + counter.toString() + ', '; counter++; }, 1000 );
Event Emitter Object Event Callback Callback Callback Event Event •
Attach • on(), once() • Trigger • emit()
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(); } );
Promises • Asynchronous Condition • Attach Callbacks – done() –
fail() – always() • Change Status – reject() – resolve()
jQuery Example jQuery( function () { jQuery .get('hello-world.xml') .done( function
(xml) { $('#output').text( $('data', xml).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
Carica I/O • Event Loop – Carica\Io\Event\Loop • Event Emitter
– Carica\Io\Event\Emitter • Promises – Carica\Io\Deferred – Carica\Io\Deferred\Promise
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();
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);
Asynchronous MySQL
HTTP Server Why?
HTTP Server • PHP Daemons – Single process for all
requests – Share variables
Web Interfaces for Firmata
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();
Carica Firmata
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();
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 ); }
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 ); }
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, ...)
RGB Wheel
Carica Chip • Hardware Abstraction • Device Objects
LED function () use ($board) { $led = new Carica\Chip\Led(
$board->pins[9] ); $led->blink(); }
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(); }
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(); }
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"; } ); }
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(); }
Drive
Thank You • Questions? • Twitter: @ThomasWeinert • Blog: http://a-basketful-of-papayas.net