Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
IPC 2013: Controlling Arduino With PHP
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
300
Introduction: PHP Extensions
thomasweinert
2
890
PCRE - Matching Patterns
thomasweinert
0
170
Controlling Arduino With PHP
thomasweinert
2
610
PCRE With PHP
thomasweinert
0
830
Modern PHP
thomasweinert
3
260
Controlling Arduino With PHP
thomasweinert
1
190
XPATH WITH PHP AND JS
thomasweinert
0
170
PHPUG CGN: Arduino With PHP
thomasweinert
0
170
Other Decks in Programming
See All in Programming
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
330
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
460
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
270
iOSDCのペンライトを自動制御したい!
akkeylab
0
330
AWSに止められる覚悟してますか?
morizo_1984
2
490
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
3.1k
海上で動くGoサーバー: goroutineとchannelでさばく航行データストリーム
atsuki_seo
0
1k
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
250
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
350
App Intentsのビルドプロセスを支える技術
kntkymt
0
490
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
410
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
220
Featured
See All Featured
Optimizing for Happiness
mojombo
378
71k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
520
エンジニアに許された特別な時間の終わり
watany
109
250k
Building the Perfect Custom Keyboard
takai
2
890
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
Mobile First: as difficult as doing things right
swwweet
225
10k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Evolving SEO for Evolving Search Engines
ryanjones
0
300
Technical Leadership for Architectural Decision Making
baasie
3
590
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
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