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
2
800
TinyGoでIoTを始めよう
TinyGoというGo言語サブセットを使って
PC-OSの無い環境の組み込み開発を始める方法の紹介。
irieda
April 20, 2019
Tweet
Share
More Decks by irieda
See All by irieda
SpaGoでSPAを作ろう!
nobonobo
0
580
Goだけでロビーサーバーを作ってみた
nobonobo
2
510
GopherJS+Vecty
nobonobo
1
890
Other Decks in Technology
See All in Technology
Grafanaのvariables機能について
tiina
0
180
Fin-JAWS第38回reInvent2024_全金融系セッションをライトにまとめてみた
mhrtech
1
120
Oracle Cloud Infrastructure:2025年1月度サービス・アップデート
oracle4engineer
PRO
0
200
さいきょうのアーキテクチャを生み出すセンスメイキング
jgeem
0
270
バクラクの組織とアーキテクチャ(要約)2025/01版
shkomine
13
3k
Creative Pair
kawaguti
PRO
1
130
Amazon Aurora バージョンアップについて、改めて理解する ~バージョンアップ手法と文字コードへの影響~
smt7174
1
250
ソフトウェアアーキテクトのための意思決定術: Software Architecture and Decision-Making
snoozer05
PRO
17
4k
Japan AWS Jr. Championsがお届けするre:Invent2024のハイライト ~ラスベガスで見てきた景色~
fukuchiiinu
0
1.1k
Redmineの意外と知らない便利機能 (Redmine 6.0対応版)
vividtone
0
190
2025/1/29 BigData-JAWS 勉強会 #28 (re:Invent 2024 re:Cap)/new-feature-preview-q-in-quicksight-scenarios-tried-and-tested
emiki
0
310
srekaigi2025-hajimete-ippo-aws
masakichieng
0
240
Featured
See All Featured
Optimizing for Happiness
mojombo
376
70k
How STYLIGHT went responsive
nonsquared
96
5.3k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
GraphQLとの向き合い方2022年版
quramy
44
13k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Navigating Team Friction
lara
183
15k
Visualization
eitanlees
146
15k
Six Lessons from altMBA
skipperchong
27
3.6k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
600
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
113
50k
Automating Front-end Workflow
addyosmani
1367
200k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.5k
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։ൃͲΜͲΜۙʹ ͳ͖ͬͯͯ·͢Αʂ
͓ΘΓ