GoにいればGoに従え(14) TinyGo、micro:bit v2、CDSセンサ読み取り

Joseph Halfmoon

前回までで、micro:bit v2上でv1.5上でできていたことが出来るように復旧できました。今回からアナログ入力に戻ります。まずはDC的な動きのないアナログ電圧で処理できるものということでCDSセンサを取り付けてみました。ありがち?ちょっとした明るさの変化にも敏感に反応してくれるCDSセンサは実験しやすいです。

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

CDSセンサの接続

CDSセンサは接続が簡単なので別シリーズの過去記事でもなんどかやってます。今回参考にしたのはMicroPythonで実験している以下の2つです。

BBC micro:bit v2への接続は以下の回路図(前回のものにCDSを追加)のとおり。黄色のマーカ部分ですよ。MB20CDS_DUT_SCHEMATIC

 

 

CDSセンサのインタフェース用関数類

CDS関係の関数を書き込んだ mbcds.go というファイル名のファイルを作成して main.goのお隣におきました。こんな感じ。

package main

import (
    "machine"
)

var sensepin machine.ADC

func InitADCforCDS() {
    machine.InitADC()
    sensepin = machine.ADC{Pin: machine.P0}
    sensepin.Configure(machine.ADCConfig{})
}

func ReadCDS() uint16 {
    return (sensepin.Get() >> 4)
}

func ReadAVG() int {
    var temp [3]uint16
    temp[0] = ReadCDS()
    temp[1] = ReadCDS()
    temp[2] = ReadCDS()
    return int((temp[0] + temp[1] + temp[2]) / 3)
}

なお、CDSセンサは敏感な代わり、読み取り値が結構ばらつくので3回測って平均値を返す ReadAVG()という関数も設けてあります。

以前にやりましたが、micro:bit v2のADCは12ビット精度の「良いもの」です。値としては0から4095までの整数値が得られる筈ですが、Get()メソッドは16ビット幅で下4ビット下駄履きの値を返してきます。そのまま16ビット値で処理しても良いのですが、ここでは下駄を外して0から4095までの値にしてます。

Main.go

main.goファイルは、前回の延長ですが、以下のように改造したので全文掲げておきます。

    1. Aボタンの割り込みハンドラでLEDに×、Bボタンの割り込みハンドラでLEDに〇を表示するようになっている。これに「便乗」しAボタンを押したときに内蔵温度計、Bボタンを押したときにCDSセンサを読み取るように切り替えるようにした
    2. 測定した値(内蔵温度計は℃、CDSセンサはADCのカウント値)はAQM1602LCDに表示するようにした。
package main

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

var pat = 0

func boardTemperatureC() int {
    return int(machine.ReadTemperature() / 1000)
}

func main() {
    var msg1 []byte = []byte("Temperature")
    var msg1C []byte = []byte("CDS")
    var msg2 []byte
    var temp int
    var cds int

    dispPattern := []uint32{
        0x00000000, 0x01151151, 0x00E8C62E, 0x01FFFFFF,
    }
    InitLED()
    go DispLoop(dispPattern[:])
    InitAQM1602()
    InitADCforCDS()

    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 = 2
    })

    for {
        if pat == 1 {
            temp = boardTemperatureC()
            fmt.Printf("TEMP: %d\r\n", temp)
            if temp < 99 {
                msg2 = []byte(strconv.Itoa(temp))
            }
            DispStrOnLCD(msg1, msg2)
        } else {
            cds = ReadAVG()
            fmt.Printf("CDS: %d\r\n", cds)
            msg2 = []byte(strconv.Itoa(cds))
            DispStrOnLCD(msg1C, msg2)
        }
        time.Sleep(time.Second * 5)
    }
}

これ以外にI2C接続LCD制御のための mbaqm1602.go ファイル、goroutineをつかってボード表面のLEDをダイナミック点灯する mbdisp.go ファイルの2つが必要ですが、これらは前回以前に全文掲げたものをそのまま流用であります。

実機動作確認

例によって以下で miciro:bit v2のフラッシュにTinyGoのオブジェクトを書き込むことができます。

$ tinygo flash -target=microbit-v2

実機上で、Bボタンを押してCDS測定モード(LED点灯は〇)にしたところが以下に。MB20CDS_DUT

明るいほどCDSの抵抗値が下がります。照明で明るい状態では上記のように358とか小さな値が読み取れますが、手で覆って照明の影にする程度で1800くらいまで値は急上昇します。ざっくりしたところでは、実験の回路の場合、ADC出力の12ビット整数値に0.00078を乗ずるとほぼ電圧値[V]となる感じです。照度計が無いので照度換算は?ですが。

GoにいればGoに従え(13) TinyGo、micro:bit v2、I2Cは要変更 へ戻る

GoにいればGoに従え(15) TinyGo、クラスは無いけど。micro:bit v2 へ進む