6
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Arduino Unoでtinygoをやってみた

はじめに

知人の手伝いで行った同人ハードウェアフェスの立ち話でtinygoなるものを聞きました。
golangをLLVMでCに変換してBluePill(STM32F103)や micro:bitなどnrfシリーズで動作するとか!

https://github.com/tinygo-org/tinygo
https://tinygo.org/

Screenshot from 2019-02-12 00-34-49.png

emgoというのもBluePillやnrfシリーズに対応してて、以前ちょっと触ってみたのですがご無沙汰なので、こっちをArduino Unoで試したいと思います。

環境構築

公式ページの手順に従い必要なものを入れます。

以下2つが必要になります。

  • Go 1.11+
  • LLVM 7 (for example, from apt.llvm.org
$ go version
go version go1.11 linux/amd64

go はもともと入っていたのでLLVMを入れます。
※ちなみにOSはUbuntu 18.04でやってます。

$ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install clang-7 lldb-7 lld-7
$ sudo apt-get install libllvm-7-ocaml-dev libllvm7 llvm-7 llvm-7-dev llvm-7-doc llvm-7-examples llvm-7-runtime

Arduinoで試してみるので以下を入れます

  • binutils (avr-objcopy) for flashing.
  • GCC (avr-gcc) for linking object files.
  • libc (avr-libc), which is not installed on Debian as a dependency of avr-gcc.
  • avrdude for flashing to an Arduino.
$ sudo apt-get install gcc-avr binutils-avr avr-libc
$ sudo apt-get install avrdude

必要なものがそろったらtinygoをセットアップします。

$ go get -u github.com/tinygo-org/tinygo
# github.com/tinygo-org/tinygo/loader
/go/src/github.com/tinygo-org/tinygo/loader/libclang.go:16:10: fatal error: clang-c/Index.h: No such file or directory
 #include <clang-c/Index.h> // if this fails, install libclang-7-dev
          ^~~~~~~~~~~~~~~~~
compilation terminated.

失敗しました。メッセージの通りにlibclang-7-devを入れて再チャレンジ

$ sudo apt-get install libclang-7-dev
$ go get -u github.com/tinygo-org/tinygo
$ go install github.com/tinygo-org/tinygo
$ which tinygo
/go/bin/tinygo

インストールできました。
Home > Getting Started > Usage をやってみます。

/tinygo/srcに移動して、tinygo run examples/testを打ってみます。

$ tinygo run examples/test/
Hello world from Go!
The answer is: 42
5 ** 2 = 25
3 + 12 = 15
fib(11) = 89
sumrange(100) = 5050
strlen foo: 3
map length: 2
map read: answer = 42
  answer = 42
  foo = 3
map length: 1
map read: data = 3
  data = 3
len/cap foo: 4 4
len/cap bar: 3 5
len/cap foo[1:2]: 1 3
foo[3]: 5
sum foo: 12
copy foo -> bar: 3
sum bar: 7
thing: foo
is int: 5
is byte: 120
is string: foo
is Thing: foo
is *Thing: foo
is *Thing: foo
is Doubler: 6
Stringer.String(): foo
Stringer.(*Thing).String(): foo
hello from function pointer: 5
deferring...
...run as defer 2
...run as defer 1
bound method: foo
thing inside closure: foo
inside fp closure: foo 3
lower to upper char: h -> H

tiny-goがあるフォルダに移動して、make gen-deviceを実行します。

$ cd /go/src/github.com/tinygo-org/tinygo
$ make gen-device
./tools/gen-device-avr.py lib/avr/packs/atmega src/device/avr/
lib/avr/packs/atmega/AT90CAN128.atdf
lib/avr/packs/atmega/AT90CAN32.atdf
lib/avr/packs/atmega/AT90CAN64.atdf
lib/avr/packs/atmega/AT90PWM1.atdf

省略

src/device/stm32/stm32l1xx.go
src/device/stm32/stm32l4x1.go
src/device/stm32/stm32l4x3.go
src/device/stm32/stm32w108.go
src/device/stm32/stm32l4x2.go
src/device/stm32/stm32l4x5.go
$

サンプル実行

サンプルを実行してみます。

$ tinygo flash -target=arduino examples/blinky1

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "/tmp/tinygo130840926/main.hex"
avrdude: input file /tmp/tinygo130840926/main.hex auto detected as Intel Hex
avrdude: writing flash (698 bytes):

Writing | ################################################## | 100% 0.12s

avrdude: 698 bytes of flash written
avrdude: verifying flash memory against /tmp/tinygo130840926/main.hex:
avrdude: load data flash data from input file /tmp/tinygo130840926/main.hex:
avrdude: input file /tmp/tinygo130840926/main.hex auto detected as Intel Hex
avrdude: input file /tmp/tinygo130840926/main.hex contains 698 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.10s

avrdude: verifying ...
avrdude: 698 bytes of flash verified

avrdude done.  Thank you.

おおお!!
GoのコードがArduinoに書き込まれました!!!
秒数を変えると点滅の速度が変わりました。

blinky1.go
package main

// This is the most minimal blinky example and should run almost everywhere.

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 * 300)

    led.High()
    time.Sleep(time.Millisecond * 300)
  }
}

image.png

Goでマイコンを動かすのは新鮮ですね :heart_eyes:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
6
Help us understand the problem. What are the problem?