前回までで、micro:bit v2上でv1.5上でできていたことが出来るように復旧できました。今回からアナログ入力に戻ります。まずはDC的な動きのないアナログ電圧で処理できるものということでCDSセンサを取り付けてみました。ありがち?ちょっとした明るさの変化にも敏感に反応してくれるCDSセンサは実験しやすいです。
※「GoにいればGoに従え」Go関連記事の総Index
CDSセンサの接続
CDSセンサは接続が簡単なので別シリーズの過去記事でもなんどかやってます。今回参考にしたのはMicroPythonで実験している以下の2つです。
BBC micro:bit v2への接続は以下の回路図(前回のものにCDSを追加)のとおり。黄色のマーカ部分ですよ。
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ファイルは、前回の延長ですが、以下のように改造したので全文掲げておきます。
-
- Aボタンの割り込みハンドラでLEDに×、Bボタンの割り込みハンドラでLEDに〇を表示するようになっている。これに「便乗」しAボタンを押したときに内蔵温度計、Bボタンを押したときにCDSセンサを読み取るように切り替えるようにした
- 測定した値(内蔵温度計は℃、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点灯は〇)にしたところが以下に。
明るいほどCDSの抵抗値が下がります。照明で明るい状態では上記のように358とか小さな値が読み取れますが、手で覆って照明の影にする程度で1800くらいまで値は急上昇します。ざっくりしたところでは、実験の回路の場合、ADC出力の12ビット整数値に0.00078を乗ずるとほぼ電圧値[V]となる感じです。照度計が無いので照度換算は?ですが。