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
PHPUCHH 2013: Controlling Arduino With PHP
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Thomas Weinert
September 24, 2013
Research
1
100
PHPUCHH 2013: Controlling Arduino With PHP
Slides from the PHP Unconference Hamburg 2013
Thomas Weinert
September 24, 2013
Tweet
Share
More Decks by Thomas Weinert
See All by Thomas Weinert
Build Automation with Phive and Phing
thomasweinert
0
250
Introduction: PHP Extensions
thomasweinert
2
850
PCRE - Matching Patterns
thomasweinert
0
160
Controlling Arduino With PHP
thomasweinert
2
590
PCRE With PHP
thomasweinert
0
790
Modern PHP
thomasweinert
3
250
Controlling Arduino With PHP
thomasweinert
1
180
XPATH WITH PHP AND JS
thomasweinert
0
150
PHPUG CGN: Arduino With PHP
thomasweinert
0
150
Other Decks in Research
See All in Research
ForestCast: Forecasting Deforestation Risk at Scale with Deep Learning
satai
3
520
世界モデルにおける分布外データ対応の方法論
koukyo1994
7
2k
"主観で終わらせない"定性データ活用 ― プロダクトディスカバリーを加速させるインサイトマネジメント / Utilizing qualitative data that "doesn't end with subjectivity" - Insight management that accelerates product discovery
kaminashi
16
23k
第二言語習得研究における 明示的・暗示的知識の再検討:この分類は何に役に立つか,何に役に立たないか
tam07pb915
0
1.8k
離散凸解析に基づく予測付き離散最適化手法 (IBIS '25)
taihei_oki
1
720
製造業主導型経済からサービス経済化における中間層形成メカニズムのパラダイムシフト
yamotty
0
510
データサイエンティストの業務変化
datascientistsociety
PRO
0
290
2026年1月の生成AI領域の重要リリース&トピック解説
kajikent
0
820
生成的情報検索時代におけるAI利用と認知バイアス
trycycle
PRO
0
390
その推薦システムの評価指標、ユーザーの感覚とズレてるかも
kuri8ive
1
340
データサイエンティストをめぐる環境の違い2025年版〈一般ビジネスパーソン調査の国際比較〉
datascientistsociety
PRO
0
930
AWSの耐久性のあるRedis互換KVSのMemoryDBについての論文を読んでみた
bootjp
1
540
Featured
See All Featured
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
76
The Language of Interfaces
destraynor
162
26k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.1k
Color Theory Basics | Prateek | Gurzu
gurzu
0
250
Six Lessons from altMBA
skipperchong
29
4.2k
Making Projects Easy
brettharned
120
6.6k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
A Soul's Torment
seathinner
5
2.4k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
150
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.1k
Transcript
PHPUCHH 2013 Controlling Arduino With PHP
About Me • Thomas Weinert – @ThomasWeinert • papaya Software
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
Event Loop Listeners 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 Event 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
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();
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; } ); }
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 ); }
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'); $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(); }
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(); }
Analog Sensor function () use ($board) { $sensor = new
Carica\Chip\Sensor\Analog( $board->pins[14] ); $sensor->onChange( function ($sensor) { echo $sensor, "\n"; } ); }
Thank You • Questions? • Twitter: @ThomasWeinert • Blog: http://a-basketful-of-papayas.net