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
510
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.3k
First step to PicoRuby
makicamel
2
740
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
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
AWSに止められる覚悟してますか?
morizo_1984
2
520
カツオ、ご期待ください
suneo3476
0
150
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
310
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
320
Jetpack Compose Mechanisms
skydoves
2
540
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
360
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
720
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.5k
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
150
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
21
21k
Verilogで学ぶCPU自作入門
uyuki234
8
4k
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
260
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
Optimizing for Happiness
mojombo
378
71k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
540
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
740
Designing for humans not robots
tammielis
254
26k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
570
How to build a perfect <img>
jonoalderson
1
6.1k
Navigating Weather and Climate Data
rabernat
0
550
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
320
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