GoにいればGoに従え(19) TinyGo、スピーカを鳴らす、micro:bit v2

Joseph Halfmoon

BBC micro:bit v2搭載のペリフェラルを順に動かしてみています。前回は6軸センサLSM303AGRでした。今回はボード部品面の中央に鎮座する「スピーカ」を鳴らしてみたいと思います。回路図には「スピーカ」と書いてありますが、ビープ鳴らすくらいがせいぜい、ブザーという方が穏当かもしれません。PWM駆動とな。

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

スピーカ(ブザー)何というピン名で駆動したらよいの?

BBC micro:bit v2の回路図を参照すれば、speaker駆動するMOSFETを駆動するn信号名はSPEAKERであり、アプリケーションプロセッサnRF52833のP0_00端子に接続しております(KL27マイコンからも接続ありますがとりあえず無視。)

このSPEAKER端子を「ペコペコ」動かせば音が鳴る筈。デジタル出力なのでソフトウエア・ループで動かすこともできますが、ここはPWMにお任せしてソフトは設定するだけ、といたしとうございます。

さて、nRF52833のデータシートを参照するとハード的には以下のようです。

    • PWMは0~3の合計4チャンネル搭載
    • 出力は32本のIO端子全てに接続可能

いつもお世話になっております TinyGo の以下のドキュメントには、microbitの場合のSpeaker端子のお名前がどうだとか書いてません(例によってv1.x系の端子番号で書かれているのでv2から登場のSpeakerについては言及ないものと想像されます。)かろうじてPWMConfig構造体の説明があるので、PWMは使える雰囲気がでてますが。

machine > microbit

PWMを試用する場合は、以下のチュートリアル・ドキュメントの方が参考になります。今回は以下を見て真似しました(アザーす。)

Using PWM

ただし、上記はRaspberry Pi Pico用じゃないかと思われるので、操作方法は真似できますが、端子番号などは参考になりませぬ。

結局、TinyGoのインストール・ディレクトリに忍び込み、micro:bit v2の場合、P0_0端子はなんと「P27」というお名前になっていること発見。P27にはさらに別名

BUZZER    = P27

がつけられていることが分かりました。なんだ、BUZZERというお名前で呼べば良いのね。。。

スピーカ・テストのためのTinyGoソース

さて、上記のチュートリアル・ドキュメントのほぼほぼパクリの実験ソースが以下に。ただし、スピーカを鳴らし続けると耳障りなので、Aボタンを押したら鳴る。Bボタンを押したら鳴りやむという制御をつけました。

また周波数は440Hz(いつもテストに使うラ、A4の音)としましたが、チュートリアルの書き方だとエラーになります(チュートリアルの500Hzであれば割り切れるので問題ない。)

また、既にPWM0という「チャネル」を指定してコンフィグしているのに、後からChannelというメソッドでmachine.BUZZERに接続できるチャネルはどこ?と書いている変なソースに見えるのですが、ここはChannel呼ばないとマズイ感じです。実際にはChannelメソッドの中でPWM用のペリフェラルモジュールと端子を紐づける操作をしているので。PWM0だとchも0が返ってくるので良いのですが、他の番号だとどうなんだろ~。知らんけど。

package main

import (
    "fmt"
    "machine"
    "time"
)

// var period uint64 = 1e9 / 500
var period uint64 = uint64(1e9) / 440
var pat = 0

func main() {
    keyA := machine.BUTTONA
    keyB := machine.BUTTONB
    keyA.Configure(machine.PinConfig{Mode: machine.PinInput})
    keyB.Configure(machine.PinConfig{Mode: machine.PinInput})
    keyA.SetInterrupt(machine.PinFalling, func(machine.Pin) {
        pat = 1
    })
    keyB.SetInterrupt(machine.PinFalling, func(machine.Pin) {
        pat = 0
    })

    pwm0 := machine.PWM0
    pwm0.Configure(machine.PWMConfig{
        Period: period,
    })
    ch, er := pwm0.Channel(machine.BUZZER)
    if er != nil {
        fmt.Printf(er.Error())
        return
    }

    for {
        if pat == 1 {
            pwm0.Set(ch, pwm0.Top()/2)
        } else {
            pwm0.Set(ch, 0)
        }
        fmt.Printf("PWM0 ON/OFF= %d\r\n", pat)
        time.Sleep(time.Second * 2)
    }
}
実機実行結果

micro:bit V2機をUSB接続後、以下でビルド&フラッシュ書き込み(書き込み後、即実行)です。通常、tinygoの接続先は自動で検出されます。

$ tinygo flash -target=microbit-v2

ボタンAを押せば、結構耳障りなビープ音が響きます。Bを押せば止まります(PWMのデューティを0%にして波形が出ないようにしているだけだけれど。)

GoにいればGoに従え(18) TinyGo、加速度センサ読み取り。micro:bit v2 へ戻る

GoにいればGoに従え(20) TinyGo、MICの値を読み取る、micro:bit v2 へ進む