LoginSignup
2
1

More than 3 years have passed since last update.

gobot I2CでLチカ

Last updated at Posted at 2020-08-08

1.はじめに

goとgobotを使って、RaspberryPiのI2Cに接続したIOエキスパンダ(MCP23017)を操作してみます。

公式にMCP23017がサポートされてるので、チュートリアルチャレンジで終わるかと思ったら、なんと、サンプルコードが書かれてなかったので、覚え書きを兼ねて簡単にまとめてみました。

実行環境

ハードウェア Raspberry Pi 4
OS Raspbian Buster
go Ver.1.14.3
IOエキスパンダ MCP23017
→これを、RaspberryPiのI2C端子に接続済
$ uname -a
Linux raspi4 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
$ go version
go version go1.14.3 linux/arm
$ sudo i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --    

2.準備

インストールは別記事で解説しているので、詳細はそちらをご覧下さい。

3.LEDの点滅例

MCP23017のポートAのピン0~7につないだLEDを、流れるように点灯する例です。
こちらのドキュメントを参考12に書いてみました。

重要な関数は以下の通りです。

  • i2c.NewMCP23017Driver
i2c.WithBus(1) ラズパイのi2cは1です。(1を指定している例:$ sudo i2cdetect -r -y 1
i2c.WithAddress(0x20) MCP23017の設定にあわせます。(ここでは0x20)
  • WriteGPIO(ピン番号, 値, ポート名)
    • 値は0:消灯、1:点灯
    • ポート名は文字列で指定、"A"あるいは"B"
raspi_blink_i2c.go
package main

import (
    "time"

    "gobot.io/x/gobot"
    "gobot.io/x/gobot/drivers/i2c"
    "gobot.io/x/gobot/platforms/raspi"
)

func main() {
    //初期化
    raspiAdaptor := raspi.NewAdaptor()
    //MCP23017の初期化
    //I2Cバス1番、アドレス0x20
    i2cexp := i2c.NewMCP23017Driver(raspiAdaptor,
        i2c.WithBus(1),
        i2c.WithAddress(0x20))

    //LEDを流れるように点灯するための制御変数
    //pin: ピン番号0から開始
    //val: 点灯1状態から開始
    var pin, val uint8
    pin, val = 0, 1

    //定期実行
    work := func() {
        //100ms毎にループ
        gobot.Every(100*time.Millisecond, func() {

            //ポートAのピンを点灯/消灯
            i2cexp.WriteGPIO(pin, val, "A")

            //ピン番号を次に移動
            pin++
            if pin > 7 {
                //ピン番号7になったら、ピン番号を0に戻す
                pin = 0
                if val == 1 {
                    //現在が点灯1状態なら、次は消灯0状態に
                    val = 0
                } else {
                    //次は点灯1状態に
                    val = 1
                }
            }
        })
    }

    robot := gobot.NewRobot("bot",
        []gobot.Connection{raspiAdaptor},
        //デバイスに追加
        []gobot.Device{i2cexp},
        work,
    )

    robot.Start()
}

実行

コマンドライン
$ go run raspi_blink_i2c.go 
2020/05/31 20:56:29 Initializing connections...
2020/05/31 20:56:29 Initializing connection RaspberryPi-308BFB50 ...
2020/05/31 20:56:29 Initializing devices...
2020/05/31 20:56:29 Initializing device MCP23017-6301D4B5 ...
2020/05/31 20:56:29 Robot bot initialized.
2020/05/31 20:56:29 Starting Robot bot ...
2020/05/31 20:56:29 Starting connections...
2020/05/31 20:56:29 Starting connection RaspberryPi-308BFB50...
2020/05/31 20:56:29 Starting devices...
2020/05/31 20:56:29 Starting device MCP23017-6301D4B5...
2020/05/31 20:56:29 Starting work...
2020/05/31 20:58:30 Stopping Robot bot ...
[Ctrl-C]
$

下記の動画、下の方の8つのLEDが、左から右へ流れています。

VID_20200531_205746_144x256_fps25.gif

4.おわりに

残課題としては、[Ctrl-C]で止めたときに、IOエキスパンダを全て消灯することです。

現状のままだと、制御が止まった時点の点灯が残ってしまいます。
こちら3を参考に、SIGINT捕捉後にIOエキスパンダのピン番号全てにLを送って消灯するプログラムを試しましたが、どうやらwork := func() {の実行が生きている間に消灯処理を入れないとダメなようです。(今の所、解決できてません)

参考資料

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1