Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

GOBOT+Arduinoでサーボモーターを動かしてみる その3:複数個動かしてみる

shuzo-kino.hateblo.jp

package main

import (
	"fmt"
	"time"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/gpio"
	"gobot.io/x/gobot/platforms/firmata"
)

func main() {
	firmataAdaptor := firmata.NewAdaptor("/dev/tty.usbmodem1421")
	servo1 := gpio.NewServoDriver(firmataAdaptor, "3")
	servo2 := gpio.NewServoDriver(firmataAdaptor, "4")
	count := 1

	work := func() {
		gobot.Every(1*time.Second, func() {
			count = (count + 1) % 254
			if Odd(count) {
				moveVal := (count * 20) % 180
				fmt.Println("Turning Servo1", moveVal)
				servo1.Move(uint8(moveVal))
			} else {
				moveVal := (count * 20) % 180
				fmt.Println("Turning Servo1", moveVal)
				fmt.Println("Turning Servo2", moveVal+100)
				servo1.Move(uint8(moveVal))
				servo2.Move(uint8(moveVal))
			}
		})
	}

	robot := gobot.NewRobot("servoBot",
		[]gobot.Connection{firmataAdaptor},
		[]gobot.Device{servo1, servo2},
		work,
	)

	robot.Start()
}

Go言語製アプリで"signal: killed"等々のエラーが出たら、とりあえず言語のアップデートをかけてみる

$ go run firmata_blink.go 
signal: killed

$ go version
go version go1.8 darwin/amd64

ここからダウンロード
Getting Started - The Go Programming Language

$ go version
go version go1.9 darwin/amd64

再実行すると、xcodeの実行権限つけろとか言われるので

$ go run examples/firmata_blink.go 
# github.com/tarm/serial


Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.


# github.com/raff/goble/xpc


Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.
$ sudo xcodebuild -license
Password:

ライセンスよんで、OKなら"agree"と入力

はい、無事に動きました

$ go run examples/firmata_blink.go 
2017/10/01 13:22:54 Initializing connections...
2017/10/01 13:22:54 Initializing connection Firmata-41AD3F2C0A3122B4 ...
2017/10/01 13:22:54 Initializing devices...
2017/10/01 13:22:54 Initializing device LED-2518522497F97919 ...
2017/10/01 13:22:54 Robot bot initialized.
2017/10/01 13:22:54 Starting Robot bot ...
2017/10/01 13:22:54 Starting connections...
2017/10/01 13:22:54 Starting connection Firmata-41AD3F2C0A3122B4 on port /dev/tty.usbmodem1421...

やめるときはCtrl+C

GOBOT+Arduinoでサーボモーターを動かしてみる その2:制御信号を叩き込む

幸い、PWM制御のサーボ用にドライバーがついてます。
こいつを活かしてやります。
gpio - GoDoc

公式のサンプルは、こんな感じ。
D3ピンにつないだサーボを

package main

import (
  "fmt"
  "time"

  "github.com/hybridgroup/gobot"
  "github.com/hybridgroup/gobot/platforms/firmata"
  "github.com/hybridgroup/gobot/platforms/gpio"
)

func main() {
  gbot := gobot.NewGobot()

  firmataAdaptor := firmata.NewFirmataAdaptor("firmata", "/dev/tty.usbmodem1411")
  servo := gpio.NewServoDriver(firmataAdaptor, "servo", "3") //デジタルの3に繋いでる場合

  work := func() {
    gobot.Every(1*time.Second, func() {
      i := uint8(gobot.Rand(180))
      fmt.Println("Turning", i)
      servo.Move(i)
    })
  }

  robot := gobot.NewRobot("servoBot",
    []gobot.Connection{firmataAdaptor},
    []gobot.Device{servo},
    work,
  )

  gbot.AddRobot(robot)
  gbot.Start()
}

この例だと、D3に繋いだサーボが動きます。
ほかに、CenterやMax、Minといった使い勝手の良さげな奴もあります。

バスパワーさえちゃんと供給すれば、
こんな感じのコード
以下のような動きもできるみたいです。
www.youtube.com

差し込み加工やネジ機構があるならABS樹脂じゃないと詰む

またぞろ3Dプリンターの話題です。
この二週間ほど装置に張り付く日々が続いてるもので……。

差し込み加工やネジ機構があるならABS樹脂じゃないと詰みます。
PLA樹脂は融点が低く反りにくい反面、加工が死ぬほど面倒です。
主観では倍以上の削り難さでした。

よほどの高性能機種でもない限り、生成物は多少の調整は必要です。
よって、ヤスリが入らないのは致命的といえます。

細長いモノを3Dプリントするなら、土台はしっかり作ろう

f:id:shuzo_kino:20170928104541j:plain
おはぎゃーの図

細いモノを3Dプリントするなら、土台はしっかり作らないと写真みたいな事になります。
フィラメント式3Dプリンターというものはヘッドが0.1mmとかいう精度で動いているため、
フィラメントの溶け具合でできた出っ張りができると引っかかります。

接地面積が十分なら問題ないのですが、
細長いとあおりを食らって"折れ"ます。
その後は虚空にフィラメントを垂れ流す装置と化します。

並列印刷をしていた場合はオマケが。
フィラメントカスが隣を殴りつける形となり、形状の変化、最悪の場合巻き込みで隣も折れます。

これを防ぐにはBrim*1を設定してやり、十分な接地面積を確保してやる位しかありません。
f:id:shuzo_kino:20170928234703p:plain

*1:イカダの意

GOBOT+Arduinoでサーボモーターを動かしてみる その1:Lチカまで

実際のところ

環境構築

shuzo-kino.hateblo.jp

Lチカ

/dev/tty.usbmodem1411にFirmata搭載済みArduinoが接続されている状態で、
13番のLチカしたい場合。

package main

import (
	"time"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/gpio"
	"gobot.io/x/gobot/platforms/firmata"
)

func main() {
        //Firmataのアダプター。接続先なんかを決める。センサーや外部機器の登録もこちら
        //今回使ってるLEDドライバーは https://gobot.io/documentation/drivers/led/

	firmataAdaptor := firmata.NewAdaptor("/dev/tty.usbmodem1411")
	led := gpio.NewLedDriver(firmataAdaptor, "13")

        //作業内容。今回はLチカ
	work := func() {
		gobot.Every(1*time.Second, func() {
			led.Toggle()
		})
	}

        //接続先のインスタンスをつくる。アダプターやドライバー、作業内容を与える
	robot := gobot.NewRobot("bot",
		[]gobot.Connection{firmataAdaptor},
		[]gobot.Device{led},
		work,
	)

        //実行。明示的に止めない限り、ループする
	robot.Start()
}

……これだけだと冗長に感じますが、
センサーやサーボの種類が増えてくると効力を発揮します。

全部のArduino関数が使えるわけじゃない

公式によると、以下のような関数が用意されています。

func NewAdaptor(args ...interface{}) *Adaptor
func (f *Adaptor) AnalogRead(pin string) (val int, err error)
func (f *Adaptor) Connect() (err error)
func (f *Adaptor) DigitalRead(pin string) (val int, err error)
func (f *Adaptor) DigitalWrite(pin string, level byte) (err error)
func (f *Adaptor) Disconnect() (err error)
func (f *Adaptor) Finalize() (err error)
func (f *Adaptor) GetConnection(address int, bus int) (connection i2c.Connection, err error)
func (f *Adaptor) GetDefaultBus() int
func (f *Adaptor) Name() string
func (f *Adaptor) Port() string
func (f *Adaptor) PwmWrite(pin string, level byte) (err error)
func (f *Adaptor) ServoConfig(pin string, min, max int) error
func (f *Adaptor) ServoWrite(pin string, angle byte) (err error)
func (f *Adaptor) SetName(n string)
func (f *Adaptor) WriteSysex(data []byte) error

今回使うPWMはともかく、AnaligWriteが無いのはアプリによっては苦しいかも……

awkの正規表現でSHELL変数は使えない……なんて事はなかった!

shuzo-kino.hateblo.jp
に、こんなコメントを頂きました。

ilex
echo "12 hoge fuge" | awk '$1 ~ /^'"$SHELL_VAR"'/{print "アルヨ〜"}'
または
echo "12 hoge fuge" | awk 'BEGIN{var="^"'"$SHELL_VAR"'}$1~var{print "アルヨ〜"}'
でいけるようです。

早速試してみましょう

$ printenv PYENV_SHELL
bash

$ echo "zsh" | awk '$1 ~ /^'$PYENV_SHELL'/{print "アルヨ〜"}' 

$ echo "bash" | awk '$1 ~ /^'$PYENV_SHELL'/{print "アルヨ〜"}'
アルヨ〜