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
Thomas Weinert
September 24, 2013
Research
1
95
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
210
Introduction: PHP Extensions
thomasweinert
2
830
PCRE - Matching Patterns
thomasweinert
0
120
Controlling Arduino With PHP
thomasweinert
2
550
PCRE With PHP
thomasweinert
0
710
Modern PHP
thomasweinert
3
220
Controlling Arduino With PHP
thomasweinert
1
150
XPATH WITH PHP AND JS
thomasweinert
0
110
PHPUG CGN: Arduino With PHP
thomasweinert
0
140
Other Decks in Research
See All in Research
チャッドローン:LLMによる画像認識を用いた自律型ドローンシステムの開発と実験 / ec75-morisaki
yumulab
1
470
Streamlit 総合解説 ~ PythonistaのためのWebアプリ開発 ~
mickey_kubo
1
940
引力・斥力を制御可能なランダム部分集合の確率分布
wasyro
0
180
Creation and environmental applications of 15-year daily inundation and vegetation maps for Siberia by integrating satellite and meteorological datasets
satai
3
120
Transparency to sustain open science infrastructure - Printemps Couperin
mlarrieu
1
190
Sosiaalisen median katsaus 03/2025 + tekoäly
hponka
0
1.3k
Adaptive fusion of multi-modal remote sensing data for optimal sub-field crop yield prediction
satai
3
220
Weekly AI Agents News!
masatoto
33
68k
Submeter-level land cover mapping of Japan
satai
3
120
Computational OT #1 - Monge and Kantorovitch
gpeyre
0
190
SSII2025 [SS2] 横浜DeNAベイスターズの躍進を支えたAIプロダクト
ssii
PRO
7
3.6k
CSP: Self-Supervised Contrastive Spatial Pre-Training for Geospatial-Visual Representations
satai
3
210
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Raft: Consensus for Rubyists
vanstee
140
7k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
820
The Language of Interfaces
destraynor
158
25k
The Invisible Side of Design
smashingmag
301
51k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
A better future with KSS
kneath
238
17k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.9k
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