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
110
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPUCHH 2013: Controlling Arduino With PHP
Slides from the PHP Unconference Hamburg 2013
Thomas Weinert
September 24, 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
810
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 Research
See All in Research
(SIGQS17) Frasco-VS:フラグメントに基づく薬剤候補化合物選抜の量子アニーリングによる実現
keisukeyanagisawa
PRO
0
160
言語モデルから言語について語る際に押さえておきたいこと
eumesy
PRO
6
2.5k
typst の使い方:言語学を研究する学生のために
gitomochang
0
520
2026年3月1日(日)福島「除染土」の公共利用をかんがえる
atsukomasano2026
0
670
議論 学術ムーブメントを成功させるために何が必要なのだろうか
rmaruy
0
100
2026 東京科学大 情報通信系 研究室紹介 (すずかけ台)
icttitech
0
4.1k
機械学習で作った ポケモン対戦bot で 遊ぼう!
fufufukakaka
0
370
Sequences of Logits Reveal the Low Rank Structure of Language Models
sansantech
PRO
1
280
重要だけど測れていないもの:高齢者ケアの見えない課題
theoriatec2024
0
410
敵対生成プロンプト同時探索による内省型プロンプト最適化
kinoue_smarthr
0
310
明日から使える!研究効率化ツール入門
matsui_528
13
7.5k
業界横断 副業コンプライアンス調査 三者(副業者・本業先・発注者)におけるトラブル認知ギャップの構造分析
fkske
0
1.3k
Featured
See All Featured
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
250
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
310
Navigating Team Friction
lara
192
16k
Paper Plane
katiecoart
PRO
2
52k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
650
Balancing Empowerment & Direction
lara
6
1.2k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
How to Talk to Developers About Accessibility
jct
2
410
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
220
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
It's Worth the Effort
3n
188
29k
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