GoにいればGoに従え(3) micro:bitのLED、ダイナミック駆動じゃね

Joseph Halfmoon

前回TinyGoを使って BBC micro:bit(v1.5)のボード表面のLEDの所望の場所を点灯できるようになりました。今回は5x5の配列を使ってXというかバッテンというかを表示させようと思います。その前に表示関数の行数が長くてうるさいので別ファイルに追い出したいのだけれど、どうする?(Goする?)

※「GoにいればGoに従え」Go関連記事の総Index

TinyGoでソースファイルを分けるにはどしたらよいの?

以前Go(TinyGoでないパソコン上の)をやっていて、GoのPackageの作り方、慣れないとよくわからん件に遭遇、ま、なんとかやっつけたのですが、既に忘却の彼方であります。上記のインデックスから自分の過去記事を見てその苦闘の後をたどるかとも思ったのですが、いまや頼りになるご本が手元にあります。

高砂様著、「TinyGoの組み込み開発」

であります。

そんな立派なパッケージを作ろうというのでもなく、単純にファイルを分けたいだけなのよ。でも、上記を少し読ませていただくけばお答えがありましたぜ。

  • TinyGoのビルド時に何も指定しないとカレントフォルダのパッケージがビルドされる

ほほう、つまり同じフォルダに同じパッケージ名で複数のファイルを置いておけば一度にビルドしてくれるということですな。ありがたし。なんだ、ファイルを分けるだけなら簡単じゃん。

BBC micro:bitのLEDにパターンを映すならダイナミック点灯じゃ

前回はテスト用に1灯、1灯光らせていたのでスタティックな点灯で良かったのですが、「パターン」を映すためにはダイナミック点灯(時分割でROW毎か、COL毎に点灯する)のが必要だということにようやく気付きましたです。

そこで前回の関数をチョイ直ししたものが以下のコード。ROW毎ダイナミック。

package main

import (
    "machine"
    "time"
)

func InitLED() {
    machine.LED_ROW_1.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_ROW_2.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_ROW_3.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_1.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_2.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_3.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_4.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_5.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_6.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_7.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_8.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_COL_9.Configure(machine.PinConfig{Mode: machine.PinOutput})
    machine.LED_ROW_1.Low()
    machine.LED_ROW_2.Low()
    machine.LED_ROW_3.Low()
}

func SetLED(arg uint32) {
    if (arg & 0x0404001) != 0 {
        machine.LED_COL_1.Low()
    } else {
        machine.LED_COL_1.High()
    }
    if (arg & 0x1000404) != 0 {
        machine.LED_COL_2.Low()
    } else {
        machine.LED_COL_2.High()
    }
    if (arg & 0x0101010) != 0 {
        machine.LED_COL_3.Low()
    } else {
        machine.LED_COL_3.High()
    }
    if (arg & 0x0080022) != 0 {
        machine.LED_COL_4.Low()
    } else {
        machine.LED_COL_4.High()
    }
    if (arg & 0x0040048) != 0 {
        machine.LED_COL_5.Low()
    } else {
        machine.LED_COL_5.High()
    }
    if (arg & 0x0820080) != 0 {
        machine.LED_COL_6.Low()
    } else {
        machine.LED_COL_6.High()
    }
    if (arg & 0x0210100) != 0 {
        machine.LED_COL_7.Low()
    } else {
        machine.LED_COL_7.High()
    }
    if (arg & 0x0008200) != 0 {
        machine.LED_COL_8.Low()
    } else {
        machine.LED_COL_8.High()
    }
    if (arg & 0x0002800) != 0 {
        machine.LED_COL_9.Low()
    } else {
        machine.LED_COL_9.High()
    }
}

func DispLED(arg uint32) {
    machine.LED_ROW_1.Low()
    machine.LED_ROW_2.Low()
    machine.LED_ROW_3.Low()
    if (arg & 0x00F8815) != 0 {
        SetLED(arg & 0x00F8815)
        machine.LED_ROW_1.High()
        time.Sleep(time.Millisecond * 10)
        machine.LED_ROW_1.Low()
    }
    if (arg & 0x0A0540A) != 0 {
        SetLED(arg & 0x0A0540A)
        machine.LED_ROW_2.High()
        time.Sleep(time.Millisecond * 10)
        machine.LED_ROW_2.Low()
    }
    if (arg & 0x15023E0) != 0 {
        SetLED(arg & 0x15023E0)
        machine.LED_ROW_3.High()
        time.Sleep(time.Millisecond * 10)
        machine.LED_ROW_3.Low()
    }
}

また、上記の関数を呼び出してエックスというかバッテンというかを表示するだけのメイン関数が以下に。

package main

func main() {
    InitLED()
    var dispPattern [4]uint32
    dispPattern[0] = 0x00000000
    dispPattern[1] = 0x01151151
    dispPattern[2] = 0x00E8C62E
    dispPattern[3] = 0x01FFFFFF
    for {
        DispLED(dispPattern[1])
    }
}

同じフォルダ内に2つソースファイルを置いておくだけ、お楽。ビルドしてフラッシュ書き込みは以下で(勿論 microbitの接続は必須です。)

$ tinygo flash -target=microbit

いや、バッテン表示されました。

DispX

バッテン一つ表示するのに随分だな。まあ、まだ慣れないし。

GoにいればGoに従え(2) 再びmicro:bit v1.5のLED配列に謀られる へ戻る

GoにいればGoに従え(4) micro:bitのLED、goroutineで動的駆動じゃ へ進む