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
dRuby over BLE
Search
makicamel
June 08, 2026
Programming
530
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
dRuby over BLE
dRuby over BLE: Device-to-Device Remote Method Calls
2026.06.06. 松江Ruby会議12
makicamel
June 08, 2026
More Decks by makicamel
See All by makicamel
Road to RubyKaigi: Play Hard(ware)
makicamel
1
1.4k
First step to PicoRuby
makicamel
2
770
PicoRuby on Rails
makicamel
4
350
Take a small step beyond the api
makicamel
2
240
Road to RubyKaigi: Making Tinny Chiptunes with Ruby
makicamel
4
2k
Road to RubyKaigi
makicamel
4
740
Rails アプリ地図考 Flush Cut
makicamel
1
260
ErdMap: Thinking about a map for Rails applications
makicamel
2
4.3k
dRuby 入門者によるあなたの身近にあるdRuby 入門
makicamel
4
1.9k
Other Decks in Programming
See All in Programming
AI時代のシニアエンジニアとは
yosuke_furukawa
PRO
13
11k
Kotlinの15年とServer-Side Kotlin
n_takehata
1
180
Vue.jsで作る空間解析アプリとCapacitorプラグインのData Bridge
hal_spidernight
1
140
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
210
Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜
umigishiaoi
0
130
Performance Optimization With LLMs
xleitix
0
230
AI Augmentation Techniques with Liberty
ivargrimstad
0
220
Modernizing iOS Apps
seyfoyun
0
140
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.5k
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
200
AmebaブログはKMPから卒業します
kmars0605
0
310
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
150
Featured
See All Featured
We Are The Robots
honzajavorek
0
420
Deep Space Network (abreviated)
tonyrice
0
400
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.5k
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
The SEO identity crisis: Don't let AI make you average
varn
0
620
30 Presentation Tips
portentint
PRO
1
450
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
330
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Practical Orchestrator
shlominoach
192
12k
Testing 201, or: Great Expectations
jmmastey
46
8.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
540
Transcript
E3VCZPWFS#-& %FWJDFUP%FWJDF3FNPUF.FUIPE$BMMT !NBLJDBNFM দߐ3VCZձٞ 1 / 64
ࣗݾհ ! !NBLJDBNFMݪສق ! 3VCZ!ͱϏʔϧ"ͱ͓ञ͕͖ ! 1JDP1JDP3VCZͬͯ·͢ ! 3PBEUP3VCZ,BJHJͷ࡞ऀ 2
/ 64
3PBEUP3VCZ,BJHJ NBLJDBNFMSPBE@UP@SVCZLBJHJ IUUQTHJUIVCDPNNBLJDBNFMSPBE@UP@SVCZLBJHJ 3 / 64
3PBEUP3VCZ,BJHJ ! 3VCZJTUʹΑΔ3VCZJTUͷͨΊͷ3VCZͷήʔϜ ! λʔϛφϧ্Ͱ༡ͿԣεΫϩʔϧΞΫγϣϯήʔϜ ! όάΛ͠ʒ͔ΒಀΕͯ3VCZ,BJHJࢀՃΛࢦ͢ 4 / 64
3PBEUP3VCZ,BJHJ⭐ ! !3VCZ,BJHJ-5 ! 1JDP3VCZͱ ՃηϯαʔͰͭ͘Δ ήʔϜίϯτϩʔϥ 3PBEUP3VCZ,BJHJ1MBZ)BSE XBSF !NBLJDBNFM
IUUQTTQFBLFSEFDLDPNNBLJDBNFMSPBEUPSVCZLBJHJQMBZIBSEXBSF 5 / 64
ొਓ 1JDP3VCZ ΈࠐΈ͚3VCZ ηϯαʔͳͲͱଓͯ͠ ͖ͳσόΠεΛͭ͘ΕΔ QJDPSVCZQJDPSVCZ IUUQTHJUIVCDPNQJDPSVCZQJDPSVCZ 6 / 64
ొਓ 1JDP3VCZ ʢ3BTQCFSSZ1J1JDP8ʣ ΈࠐΈ͚3VCZ ηϯαʔͳͲͱଓͯ͠ ͖ͳσόΠεΛͭ͘ΕΔ QJDPSVCZQJDPSVCZ IUUQTHJUIVCDPNQJDPSVCZQJDPSVCZ 7 /
64
ొਓ ίϯτϩʔϥ 8 / 64
ొਓ Ճηϯα 9 / 64
ొਓ Ճηϯα ՃηϯαͷΛ 3PBEUP3VCZ,BJHJʹ͍ͨ͠ 3PBEUP3VCZ,BJHJ 10 / 64
ొਓ 1JDP3VCZ Ճηϯα 1JDP3VCZͰ ՃηϯαͷΛಡΈऔΓ 3PBEUP3VCZ,BJHJ 11 / 64
ొਓ 1JDP3VCZ #MVFUPPUIͰ 3PBEUP3VCZ,BJHJʹૹ৴ 3PBEUP3VCZ,BJHJ 12 / 64
ొਓ 1JDP3VCZ #MVFUPPUIͰ 3PBEUP3VCZ,BJHJʹૹ৴ Ͱ͖ͳ͍ 3PBEUP3VCZ,BJHJ 13 / 64
ొਓ 1JDP3VCZ #MVFUPPUIͷ ΫϩεϓϥοτϑΥʔϜͳ 3VCZΫϥΠΞϯτ͕ͳ͍ #MVFUPPUIͰ 3PBEUP3VCZ,BJHJʹૹ৴ Ͱ͖ͳ͍ 3PBEUP3VCZ,BJHJ 14
/ 64
ొਓ ϒϥβ 8FC#MVFUPPUI"1* 8FC#MVFUPPUI"1*8FC"1*c.%/ IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC"1*8FC@#MVFUPPUI@"1* 15 / 64
ొਓ ϒϥβ 8FC#MVFUPPUI"1* 8&#SJDLαʔό 3PBEUP3VCZ,BJHJ 16 / 64
ొਓ 1JDP3VCZ #MVFUPPUI ϒϥβ 8&#SJDLαʔό 3PBEUP3VCZ,BJHJ 17 / 64
ొਓ 1JDP3VCZ #MVFUPPUI ϒϥβ )551 8&#SJDLαʔό 3PBEUP3VCZ,BJHJʹ ૹ৴Ͱ͖ͨ 3PBEUP3VCZ,BJHJ 18
/ 64
#MVFUPPUI 19 / 64
#-& ! #MVFUPPUI-PX&OFSHZ ! লిྗ͚#MVFUPPUIن֨ ! 3BTQCFSSZ1J1JDP 8ʹແઢνοϓ͕͍ͬͯΔ !
1JDP3VCZ͔Βѻ͑Δ ֓೦ɾ͓࡞๏͕ Ή͔͍ͣ͠ 20 / 64
#-&6"35 ! 6"35 ! ػثΛཧઢͰͭͳ͍ͰํʹόΠτΛૹΔ௨ ৴ํࣜ ! #-&6"35 ! 6"35Λ#-&ͰԾతʹ࣮ݱ͢Δ1JDP3VCZͷ࣮
! *0ͷΑ͏ͳΠϯλʔϑΣʔεͰѻ͑Δ #-&6"35QJDPSVCZQJDPSVCZ IUUQTHJUIVCDPNQJDPSVCZQJDPSVCZUSFFNBTUFSNSCHFNTQJDPSVCZCMFVBSU 21 / 64
#-&6"35 # ૹ৴ଆ(PicoRuby) ble_uart = BLE::UART.new ble_uart.start do if ble_uart.connected?
ble_uart.puts('Hello, BLE::UART!') end end 3VCZͬΆ͍ʂ 22 / 64
#-&6"35 # ड৴ଆ(PicoRuby.WASM) # ηοτΞοϓ @buffer = '' server =
@device.connect service = server.service(@svc_uuid) @rx_char = service.characteristic(@rx_uuid) @rx_char.on_change { |data| @buffer << data } @rx_char.start_notify 23 / 64
#-&6"35 # ड৴ଆ(PicoRuby.WASM) # @bufferΛҰఆ࣌ؒຖʹνΣοΫ͢Δ while (idx = @buffer.index(SEPARATOR)) line
= @buffer.slice!(0..idx).strip line.split(SAMPLE_SEPARATOR) .each { |sample| send_data(sample) } end 3VCZͬΆ͍ʜʜʁ 24 / 64
#-&6"35 ! )551 ! ϦΫΤετϝοηʔδ ! #-&6"35 ! όΠτετϦʔϜ !
ड৴ϝοηʔδ ! FH ෳϝοηʔδɺϝοηʔδ్͕தͰ͖ΕΔ ! ηύϨʔλͰ۠Γͯࣗ͠ͰΈཱͯΔ 25 / 64
#-&6"35 3VCZͬΆ͘ॻ͖͍ͨʂ 26 / 64
E3VCZ 27 / 64
E3VCZ ! EJTUSJCVUJPO3VCZ ! ࢄ3VCZ ! ࢄΦϒδΣΫτγεςϜΛ࣮ݱ͢ΔϥΠϒϥϦ ! ؔকढ़͞Μ࡞ MJCSBSZESC
3VCZϦϑΝϨϯεϚχϡΞϧ IUUQTEPDTSVCZMBOHPSHKBMBUFTUMJCSBSZESCIUNM 28 / 64
E3VCZ ! ϓϩηεωοτϫʔΫΛ͑ͯϝοηʔδΛૹΔ ! ଞϓϩηεͷΦϒδΣΫτͷϝιουΛݺΔ 29 / 64
E3VCZ { greeting: 'Hello, Matsue!' } E3VCZೖऀʹΑΔ͋ͳͨͷۙʹ͋ΔE3VCZೖ!NBLJDBNFM IUUQTTQFBLFSEFDLDPNNBLJDBNFMESVCZBUUSBDUJPO 30 /
64
E3VCZ { greeting: 'Hello, Matsue!' object[:greeting] } E3VCZೖऀʹΑΔ͋ͳͨͷۙʹ͋ΔE3VCZೖ!NBLJDBNFM IUUQTTQFBLFSEFDLDPNNBLJDBNFMESVCZBUUSBDUJPO 31
/ 64
E3VCZ { greeting: 'Hello, Matsue!' object[:greeting] } # => 'Hello,
Matsue!' E3VCZೖऀʹΑΔ͋ͳͨͷۙʹ͋ΔE3VCZೖ!NBLJDBNFM IUUQTTQFBLFSEFDLDPNNBLJDBNFMESVCZBUUSBDUJPO 32 / 64
E3VCZ ! 3VCZͬΆ͍ʂ ! #-&͝͠ʹผϓϩηεͷΦϒδΣΫτΛ͞ΘΓ͍ͨ 33 / 64
E3VCZPWFS#-& 34 / 64
E3VCZPWFS#-& E3VCZϓϩτίϧ͕ࠩ͠ସ͑Մೳ ! ϏϧτΠϯ ! Ϣʔβʔ֦ு ! 5$1 ! 8FC4PDLFU
! 6/*9υϝΠϯιέοτ ! 44- 35 / 64
E3VCZPWFS#-& E3VCZϓϩτίϧ͕ࠩ͠ସ͑Մೳ ! ϏϧτΠϯ ! Ϣʔβʔ֦ு ! 5$1 ! 8FC4PDLFU
! 6/*9υϝΠϯιέοτ ! #-&! GPS1JDP3VCZ1JDP3VCZ8"4. ! 44- 36 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶃΦϒδΣΫτΛެ։ front = Calc.new DRb.start_service( "ble://picoruby", front)
37 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶄελϒΛ࡞Δ ᶃΦϒδΣΫτΛެ։ αʔόͷΞυϨεΛࢦఆ front = Calc.new obj
= DRbObject.new( DRb.start_service( "ble://picoruby") "ble://picoruby", front) 38 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶄελϒΛ࡞Δ ᶃΦϒδΣΫτΛެ։ αʔόͷΞυϨεΛࢦఆ front = Calc.new obj
= DRbObject.new( DRb.start_service( "ble://picoruby") "ble://picoruby", front) ᶅϝοηʔδૹ৴ obj.add(1, 2) όΠτྻมͯ͠ૹ৴ όΠτྻΛૹड৴ 39 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶄελϒΛ࡞Δ ᶃΦϒδΣΫτΛެ։ αʔόͷΞυϨεΛࢦఆ front = Calc.new obj
= DRbObject.new( DRb.start_service( "ble://picoruby") "ble://picoruby", front) ᶅϝοηʔδૹ৴ ᶆϝιουίʔϧ obj.add(1, 2) όΠτྻΛมͯ͠ϝιουίʔϧ όΠτྻมͯ͠ૹ৴ front.send(msg_id, *args) όΠτྻΛૹड৴ 40 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶄελϒΛ࡞Δ ᶃΦϒδΣΫτΛެ։ αʔόͷΞυϨεΛࢦఆ front = Calc.new obj
= DRbObject.new( DRb.start_service( "ble://picoruby") "ble://picoruby", front) ᶅϝοηʔδૹ৴ ᶆϝιουίʔϧ obj.add(1, 2) όΠτྻΛมͯ͠ϝιουίʔϧ όΠτྻมͯ͠ૹ৴ front.send(msg_id, *args) όΠτྻΛૹड৴ ᶇ݁ՌΛฦ͢ # => 3 41 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶄελϒΛ࡞Δ ᶃΦϒδΣΫτΛެ։ αʔόͷΞυϨεΛࢦఆ front = Calc.new obj
= DRbObject.new( DRb.start_service( "ble://picoruby") "ble://picoruby", front) ᶅϝοηʔδૹ৴ ᶆϝιουίʔϧ obj.add(1, 2) όΠτྻΛมͯ͠ϝιουίʔϧ όΠτྻมͯ͠ૹ৴ front.send(msg_id, *args) όΠτྻΛૹड৴ ᶈ݁ՌΛड͚औΔ ᶇ݁ՌΛฦ͢ # => 3 # => 3 42 / 64
όΠτྻͷૹड৴ ! DRbMessage ! ϝιουίʔϧɾΓˡˠόΠτྻͷมΛߦ͏ ! ௨৴࿏ʹͤΒΕΔͷόΠτྻ͚ͩ ! τϥϯεϙʔτͱૄ݁߹ 43
/ 64
όΠτྻͷૹड৴ ! τϥϯεϙʔτ ! FH ! 5$1 ! 8FC4PDLFU !
#-& ! 1JDP3VCZɾ4%,Ͱ࣮͞Ε͍ͯΔ 44 / 64
όΠτྻͷૹड৴ ! DRbMessage τϥϯεϙʔτ ! "1*ͷཁ݅ͱ࣮ଶʹ͕ࠩ͋Δ DRbMessage#recv_message | | |
BLE::UART#read_nonblock 45 / 64
όΠτྻͷૹड৴ ! DRbMessage ιέοττϥϯεϙʔτ ! "1*ͷཁ݅ͱ࣮ଶͷࠩΛٵऩ͢ΔιέοτΛ࣮͢Δ DRbMessage#recv_message | Adapter#read |
BLE::UART#read_nonblock 46 / 64
E3VCZGPS1JDP3VCZ ΫϥΠΞϯτ αʔό ᶄελϒΛ࡞Δ ᶃΦϒδΣΫτΛެ։ αʔόͷΞυϨεΛࢦఆ front = Calc.new obj
= DRbObject.new( DRb.start_service( "ble://picoruby") #-&༻ιέοτΛ "ble://picoruby", front) ࣮͢Δ͚ͩ ᶅϝοηʔδૹ৴ ᶆϝιουίʔϧ obj.add(1, 2) όΠτྻΛมͯ͠ϝιουίʔϧ όΠτྻมͯ͠ૹ৴ front.send(msg_id, *args) όΠτྻΛૹड৴ ᶈ݁ՌΛड͚औΔ ᶇ݁ՌΛฦ͢ # => 3 # => 3 47 / 64
%3C#-&"EBQUFS ! όΠτྻʹର͢Δૢ࡞छྨ ! read ! write DRb::BLE::Adapter#close࣮͠·͕͢ࠓճׂѪ 48 /
64
%3C#-&"EBQUFS ! DRbMessage ! BLE::UART #recv_message(n) #read_nonblock(n) ! ϒϩοΩϯάඞཁ !
ϒϩοΩϯά͠ͳ͍ ! ஸOόΠτ΄͍͠ ! ʙOόΠτΛฦ͢ ͜ͷࠩΛ DRb::BLE::Adapter#read Ͱٵऩ͢Δ 49 / 64
%3C#-&"EBQUFS def read(n) ड৴όοϑΝʹ until @uart.available >= n OόΠτ #
... ཷ·Δ·Ͱͭ ϒϩοΩϯά sleep_ms 10 end end 50 / 64
%3C#-&"EBQUFS def read(n) until @uart.available >= n # ... @uart.poll_once
ड৴ύέοτΛ sleep_ms 10 όοϑΝʹੵΉ end end 51 / 64
%3C#-&"EBQUFS def read(n) until @uart.available >= n # ... @uart.poll_once
sleep_ms 10 end OόΠτཷ·ͬͨΒ @uart.read_nonblock(n) औΓग़ͯ͠ฦ͢ end 52 / 64
%3C#-&"EBQUFS ! DRbMessage ! BLE::UART #send_request(data) #write(data) ࣗͷλΠϛϯάͰόΠτΛૹΕΑ͍ 53 /
64
%3C#-&"EBQUFS ͦͷ··సૹ͢Δ def write(data) @uart.write(data) end 54 / 64
%3C#-& ! ιέοτ͕Ͱ͖ͨ! ! αʔόͷ࣮ ! Πϯελϯε࡞ͬͨΓ ! ϝοηʔδΛड͚औͬͯϝιουίʔϧͯ͠ฦ͠ ͨΓ͢Δ͚ͩ
55 / 64
ΞϓϦଆίʔυ ! CFGPSF # ड৴ଆ(PicoRuby.WASM) # ηοτΞοϓ @buffer = ''
server = @device.connect service = server.service(@svc_uuid) @rx_char = service.characteristic(@rx_uuid) @rx_char.on_change { |data| @buffer << data } @rx_char.start_notify # @bufferΛҰఆ࣌ؒຖʹνΣοΫ͢Δ while (idx = @buffer.index(SEPARATOR)) line = @buffer.slice!(0..idx).strip line.split(SAMPLE_SEPARATOR) .each { |sample| send_data(sample) } end Ή͔͍ͣ͠ʜʜ 56 / 64
ΞϓϦଆίʔυ ! BGUFS # ड৴ଆ(PicoRuby.WASM) # ηοτΞοϓ @obj = DRb::DRbObject.new_with_uri(uri)
# @obj.readΛҰఆ࣌ؒຖʹίʔϧ͢Δ @obj.read.each { |sample| send_data(sample) } 3VCZͬΆ͍ʂ 57 / 64
σϞ 58 / 64
σϞ ! ಈ͍ͯͳ͍ʜʜʁ ! ඵؒαϯϓϧ͕Γ͍ͯͳ͍ 59 / 64
༨ஊ ! ϙʔϦϯάϨʔτԼ ! CFGPSF ! αϯϓϧඵ ! BGUFS !
αϯϓϧඵ ! 60 / 64
༨ஊ ! ϙʔϦϯάϨʔτԼ ʮήʔϜίϯτϩʔϥΈ͍ͨͳͷʹ ɹSFRVFTUSFQMZܕͷ௨৴͖·ͤΜʯ ʮ!ʯ 61 / 64
༨ஊ ! E3VCZ ! QVTI ! SFRVFTUSFQMZܕ ! ҰํͷετϦʔϜ !
ຖճ ! ߴසʹૹΕͯԆ ૹ৴ɾػɾड৴ ! ฦࣄෆཁ ! ௨৴ճ͕૿͑Δ ! ฦࣄΛͭ͘ͳΔ ༻్ʹ͋ͬͨํ๏ Λબ΅͏ ήʔϜίϯτϩʔϥQVTIܕ͖ 62 / 64
͓͠Βͤ 63 / 64
1JDP3VCZ,BJHJ "TTFNCMFΓ·͢ ! 1JDP3VCZΛͭ͘Δɺ1JDP3VCZͰͭ͘Δ ! ϓϩϙʔβϧืूࠓ݄։͖·͢ ! !
!ळ༿ݪ ! IUUQTQJDPSVCZLBJHJPSH 64 / 64