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
TinyGoでIoTを始めよう
Search
irieda
April 20, 2019
Technology
930
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TinyGoでIoTを始めよう
TinyGoというGo言語サブセットを使って
PC-OSの無い環境の組み込み開発を始める方法の紹介。
irieda
April 20, 2019
More Decks by irieda
See All by irieda
SpaGoでSPAを作ろう!
nobonobo
0
660
Goだけでロビーサーバーを作ってみた
nobonobo
2
580
GopherJS+Vecty
nobonobo
1
1.1k
Other Decks in Technology
See All in Technology
ruby.wasmとPicoRuby.wasmに対応した仮想DOMライブラリを作ってる話 #kaigieffect_kaigi
sue445
PRO
0
150
アカウントが増えてからでは遅い? ~ マルチアカウント統制の勘所 ~
kenichinakamura
0
230
誤解だらけの開発生産性 / Myths and Misconceptions about Developer Productivity
i35_267
2
610
Making sense of Google’s agentic dev tools
glaforge
1
220
“それは自分の仕事じゃない"を越えて行け
yuukiyo
1
370
Devsumi 2026 Summer 人もAIも使える共通基盤を事業の加速装置にする~デザインシステム運用に学ぶ組織レバレッジ~ 渡辺 凌央
legalontechnologies
PRO
0
150
公式ドキュメントの歩き方etc
coco_se
0
110
AI時代の開発生産性は、個人技からチーム設計へ
moongift
PRO
3
2k
Claude Code公式skillで 自分の仕事を少しずつ手放そう!(Claude Code開発ノウハウ大公開スペシャル by クラスメソッド)
kaym
1
360
Terraform共通モジュールをチーム横断で“変えられる”運用へ ― リリースと適用の分離
kekke_n
1
3k
Kaggleで成長するために意識したこと
prgckwb
2
360
キャリアの中で本を作る / Making a Book During Your Career
ak1210
0
140
Featured
See All Featured
Designing Experiences People Love
moore
143
24k
So, you think you're a good person
axbom
PRO
2
2.1k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
A designer walks into a library…
pauljervisheath
211
24k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
600
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
250
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Color Theory Basics | Prateek | Gurzu
gurzu
0
390
The Art of Programming - Codeland 2020
erikaheidi
57
14k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
260
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Transcript
TinyGoͰIoTΛ࢝ΊΑ͏
͓લ୭Αʁ ϝΧτϩιϑτ Pythonista -> Gopher झຯͰGoʹ͔ͳ͍ͷ։ Goྺ̒ऑ͘Β͍ αΠτ: ձࣾ: 144Lab(2017/07/01
͔Β৽໊ࣾ) HN: @nobonobo http://golang.rdy.jp/
ΈࠐΈ։ൃͬͯʁ
ΈࠐΈͱݴͬͯʁ େผͯ͠ PC͚OSͷ্ͰΈࠐΈ PC͚OSແ͠ͰΈࠐΈ ʢΈࠐΈ͚OS·ͨOSແ͠ʣ ͱ͍͏̎छྨ͕͋Γ·͢ɻ
PC͚OSͷ্ͰΈࠐΈ PCʹ͍ۙখܕϘʔυʢRaspberryPiͳͲʣͰ LinuxWindows10ͷ্ʹ ΞϓϦΛ࣮͢ΔελΠϧ ͕ૉΒ͍͠ ͨͩ͠ɺిݯ֬อ͕ඞਢ Ϟϊͷબࢶ࣮࣭̎ RaspberryPiܥ ߴՁͳϘʔυͷྨ https://gobot.io
PC͚OSແ͠ͰΈࠐΈ Goͷෆಘҙ Goͷཪํͷػೳηοτ͕OSʹґଘ goroutineͷεέδϡʔϥGCͳͲ OSͷແ͍ڥʹҠ২͢Δίετ͕ߴ͍ ϨΠϠͷI/Oࢧԉػೳ͕ͱͱແ͍ PCͱҧ͍ཧతʹଟ༷͗͢Δڥ
ΈࠐΈ։ൃͷੈք ιϑτΣΞͷ͕ࣝٻΊΒΕΔ ϨΠϠʔͷࣝٻΊΒΕΔ ϋʔυΣΞͷࣝগ͠ٻΊΒΕΔ ։ൃڥΛ͑Δͷʹίετ͕͔͔Δ ΈࠐΈ is Hard!
ͦͯ͠ɾɾɾ C/C++͕σϑΝΫτελϯμʔυ C͚ͩͳΒ·ͩ͠C++πϥΠ ॲཧͷ࣮ମΛӅ͢ͷ্͕ख͗͢Δ ࠔͳґଘղܾ includeࠈͱIFDEFࠈ ΦʔόʔϩʔυʹςϯϓϨʔτ ΈࠐΈ is Hard!
C/C++ͷΘΓʹGoͳΒʁ ϦʔμϏϦςΟ࠷ߴʂ ΤϥʔΛపఈͯ͠νΣοΫ͢ΔจԽʂ undefined-behavierʹ·͞Εͳ͍ʂ ґଘղܾʹgo-get͕͑Δʂ ΈࠐΈ͕গۙ͠ʹͳΔ͔ʁʂ
ͱ͍͏Θ͚Ͱ TinyGoͰ͢Αʂʂ
ઌ݄ϗοςϯτϦೖΓ https://tech.144lab.com/entry/tinygo
λʔήοτྫ
micro:bit ରԠ։ൃπʔϧͷ͕τοϓΫϥε ϒϩοΫํࣜͰখֶੜϓϩάϥϛϯάOK ϒϩοΫʹ͖ͨΒJS,TS ArduinoͰPythonͰRuby,Jacvascript,LuaͳͲͳͲ ϓϩ͚SEGGER Embedded StudioͰOK
circuit playground express ࡌΪϛοΫ͕τοϓΫϥε ϑϧΧϥʔ֊ௐ͖ͭLED̍̌ݸ εϐʔΧʔʹϚΠΫ ޫྔηϯαɺԹɾ࣪ηϯα ̒࣠ʢՃɾ֯ʣηϯα IRϦϞίϯૹड৴ λονηϯγϯά
UART/USB/SPI/I2C/etc...
࣮ࡍʹ͍ΖΜͳίʔυΛ ίϯύΠϧͯ͜͠ΕΒͰ ಈ͔ͯ͠Έ·͠ΐ͏ʂ
TinyGoͷ͍ํ dockerϕʔε͕ࠓΦεεϝͰ͢ɻ ʢdevϒϥϯνϏϧυେม ˍ ߴසͰґଘมߋ͞Ε Δʣ $ docker run -it
--rm tinygo/tinygo tinygo version tinygo version 0.4.1 linux/amd64
ͨ·ʹΞοϓσʔτͯ͠Έ·͠ΐ͏ $ docker pull tinygo/tinygo:latest latest: Pulling from tinygo/tinygo Digest:
sha256:821ad71e7d9b3fe46a84a5818e52d3d3596e0d8f3855f8407b917a37371b2b23 Status: Image is up to date for tinygo/tinygo:latest
sample̍ ͍ΘΏΔLνΧʢΈࠐΈͰͷHelloWorldʣ package main import ( "machine" "time" ) func
main() { led := machine.GPIO{machine.LED} led.Configure(machine.GPIOConfig{Mode: machine.GPIO_OUTPUT}) for { led.Low() time.Sleep(time.Millisecond * 500) led.High() time.Sleep(time.Millisecond * 500) } }
Ϗϧυ output.uf2 --Drag&Drop--> CIRCUITPYσόΠε ͜Ε͚ͩͰλʔήοτʹॻ͖ࠐ·ΕΔ $ go mod init github.com/nobonobo/examples/sample1
$ PACKAGE_PATH = github.com/nobonobo/examples/sample1 $ PROJECT_PATH = /go/src/$PACKAGE_PATH $ docker run -it --rm $PWD:$PROJECT_PATH -w $PROJECT_PATH \ tinygo/tinygo tinygo build -target=circuitplay-express -o output.uf2 .
TinyGoͷఏڙόε࣮(1) ڞ௨Ͱఏڙ͢Δόε GPIO(൚༻ೖग़ྗϐϯ) ADCʢΞφϩάܭଌʣ PWMʢαʔϘɺύϫʔίϯτϩʔϧ͚ʣ UARTʢPCͱͷ࿈ܞ༻ʣ SPIʢখ͞ͳσόΠεͱͷ࿈ܞ༻ʣ I2Cʢখ͞ͳσόΠεͱͷ࿈ܞ༻ʣ
TinyGoͷఏڙόε࣮(2) Ұ෦ͷλʔήοτ DACʢΞφϩάిѹൃੜʣ
ΞʔΩςΫνϟผͷఏڙػೳ ϨδελΞΫηε ΠϯϥΠϯΞηϯϒϥ λΠϚʔɺUARTϋϯυϦϯά ΄ͱΜͲͷλʔήοτͰ ʮprintlnʯͰ γϦΞϧϙʔτʹσόοάϩάΛग़ྗͰ͖Δɻ
पลσόΠεผυϥΠόʔ Device Name Interface Type SPI I2C I2C I2C GPIO
UART I2C I2C I2C GPIO https://github.com/tinygo-org/drivers APA102 RGB LED BH1750 ambient light sensor BlinkM RGB LED BMP180 barometer "Easystepper" stepper motor controller ESP8266/ESP32 AT Command set for WiFi/TCP/UDP MAG3110 magnetometer MMA8653 accelerometer MPU6050 accelerometer/gyroscope WS2812 RGB LED
֎෦ύοέʔδͱdocker ґଘ͢ΔύοέʔδΛՃ͍ͨ͠ʂʂ ͋ΕʁdockerϕʔεͩͱͲ͏͢Δʁʂ ͦ͜Ͱgo modͰ͢Α $ export GO111MODULE=on $ go
mod github.com/..../sample1 $ go get github.com/tinygo-org/drivers/ws2812 $ go mod vendor
͢Δͱʁ vendor/ github.com/ tinygo-org/ drivers/ ws2812/ main.go ͖ͬࣔͨ͞͠dockerίϚϯυͰίϯςφ͔Β ws2812ύοέʔδ͕ࢀরՄೳʹͳΔɻ
LEDετϦοϓυϥΠόΛ࡞Δ package main import ( "device/arm" "image/color" "machine" "github.com/tinygo-org/drivers/ws2812" )
// NeopixelDriver represents a connection to a NeoPixel type NeopixelDriver struct { pin machine.GPIO device ws2812.Device pixelCount int pixels []color.RGBA } // NewNeopixelDriver returns a new NeopixelDriver
ͦͯ͠ಈ͔ͯ͠ΈΔ package main import ( "image/color" "machine" "time" ) const
NUM_PIXELS = 10 func main() { neo := NewNeopixelDriver(machine.GPIO{machine.NEOPIXELS}, NUM_PIXELS) n := 0 var pows = []uint8{255, 127, 63, 31, 15, 7, 3, 1, 0, 0} for { for i := 0; i < NUM_PIXELS; i++ { pow := pows[NUM_PIXELS-1-i] neo.SetPixel((n+i)%NUM_PIXELS, color.RGBA{R: pow, G: pow, B: pow}) }
DEMO ͕ʔɾɾ͕ʔʂʂ
໌Δ͞ʹԠͯ͡LEDΛ౮͢ package main import ( "image/color" "machine" "time" ) const
NUM_PIXELS = 10 func main() { machine.InitADC() sensor := machine.ADC{machine.A8} sensor.Configure() neo := NewNeopixelDriver(machine.GPIO{machine.NEOPIXELS}, NUM_PIXELS) for { for i := 0; i < NUM_PIXELS; i++ { pow := uint8(sensor.Get() / 256) neo.SetPixel(i, color.RGBA{R: pow, G: pow, B: pow})
DEMO
GoͬΆ͘ॻ͘ package main import ( "image/color" "machine" "time" ) const
NUM_PIXELS = 10
Ϙλϯࢹؔ func observer(event chan int) { btnA := machine.GPIO{machine.BUTTONA} btnA.Configure(machine.GPIOConfig{Mode:
machine.GPIO_INPUT_PULLDOWN}) btnB := machine.GPIO{machine.BUTTONB} btnB.Configure(machine.GPIOConfig{Mode: machine.GPIO_INPUT_PULLDOWN}) next := make([]bool, 2) prev := make([]bool, 2) prev[0], prev[1] = btnA.Get(), btnB.Get() for { time.Sleep(20 * time.Millisecond) next[0], next[1] = btnA.Get(), btnB.Get() for i := range next { if !prev[i] && next[i] { event <- i } } prev[0], prev[1] = next[0], next[1] } }
ϨϯμϦϯάؔ func renderer(ch chan *NeopixelDriver) { for { v :=
<-ch v.Show() } }
mainؔ func main() { events := make(chan int) go observer(events)
// ϘλϯࢹλεΫىಈ ɹneo := NewNeopixelDriver(machine.GPIO{machine.NEOPIXELS}, NUM_PIXELS) ch := make(chan *NeopixelDriver) go renderer(ch) // ϨϯμϥʔλεΫىಈ prev, next := 0, 0 neo.SetPixel(prev, color.RGBA{R: 10, G: 10, B: 10}) ch <- neo // ϨϯμϦϯάΛൃՐ for { select { case v := <-events: switch v { case 0: println("buttonA pressed") next++ if next >= NUM_PIXELS {
DEMO
·ͱΊ ฒߦॲཧ͕ॻ͖͍͢ʂ ݱঢ়ͷϨΠϠ֦ுखஈ ΠϯϥΠΞηϯϒϥ SVCall CGOαϙʔτߴϨϕϧαϙʔτ͕ෆ TinyGoͷϏϧυͰgo-mod·ͩ͑ͳ͍ ͕ɺdockerͱͷซ༻ͰͳΜͱ͔ͳΔ
ࠓޙͷൃల
׆ൃͳ׆ಈ BLEϥΠϒϥϦରԠ CGOαϙʔτ ՃηϯαͳͲͷυϥΠόʔ ESPγϦʔζͷαϙʔτ
ݱঢ়ͷωοτػೳ ҎԼͷΞΠςϜΛ͏͜ͱͰ࣮ݱՄೳ ESP8266 or ESP32 ͱ͍͏֨҆Wi-Fiػೳ͖ϚΠίϯ driversʹ͋Δ ࠓճͷλʔήοτΛESPϞδϡʔϧͱUARTͱ͍͏̎৴߸ Λͭͳ͙ TCP/UDP௨৴͕ՄೳʹͳΔ
ESP8266/ESP32 AT Command set for WiFi/TCP/UDP
ࠓޙͷωοτଓ LINE ThingsͷΑ͏ʹࠓ୭͕࣋ͭεϚϗΛ BLEtoΠϯλʔωοτͷϋϒʹͪ͠Ό͏ΞΠσΟΞ LoRaɺNB-IoTϞδϡʔϧ΅ͪ΅ͪೖखՄೳʹͳΓͭͭ ͋Γ·͢
WebAssemblyग़ྗ ຊՈΑΓޮతͳՌΛग़ͤΔ syscall/jsαϙʔτͳͲ࢝·ͬͯΔ
IoT։ൃͲΜͲΜۙʹ ͳ͖ͬͯͯ·͢Αʂ
͓ΘΓ