LoginSignup
0
0

More than 5 years have passed since last update.

micro:bit / MicroPython / SPIデバイス(ADコンバーターMCP3008)を外づけする / それに意味のないとき

Last updated at Posted at 2018-07-01

概要

SPIデバイスをmicro:bitに接続してみる。SPIデバイスにはADコンバーターMCP3008を使う。10ビット、8チャンネルのADCである。

micro:bitにもアナログ入力はあるので、アナログ入力の数を増やしたい場合を除けばADコンバーターを外づけする意味はない。SPIバスの動作を確かめるだけである。

下の回路で試してみる。

  • SPI関連の端子はデフォルトのままとする。!CS端子にはP16を使うことにする。
  • SPIモードは0(0,0)とする。

spiモジュールの使いかた

  • 初期化: microbit.spi.init(baudrate=1000000, bits=8, mode=0, sclk=pin13, mosi=pin15, miso=pin14)
    (引数は全部オプション)
  • read操作: microbit.spi.read(バイト数)
  • write操作: microbit.spi.write(バイトバッファー)
  • write/read操作: microbit.spi.write_readinto(書き込みバイトバッファー, 読み出しバイトバッファー)
    読み書きに使う2つのバイトバッファーはサイズが同じでなければならない。両方とも同じバイトバッファーを指定してもよい。

spiモジュールを使ってMCP3008から10ビットのADC値を読み出す方法

以下の手順で3バイトをwriteして3バイトをreadし、readした3バイトの中から10ビットを取り出す。ビットの送り順はMSBファーストである。

[0]バイト目:
0b 0000 0001をwriteする。この1がスタートビットとして働く。
→同時に、ADCから1バイトが返ってくる。このバイトデータは使わない。

[1]バイト目:
ビット7でシングルエンド(1)か差動(0)か指定し、ビット6:4でチャンネル(0~7)を指定する。下の例では、シングルエンドでチャンネル0を使うので0b 1000 ----をwriteしている。
→同時に、ADCから0b ---- -0??が返ってくる。??の位置にある2ビットが10ビットデータの上位2ビットである。

[2]バイト目:
ダミーバイトをwriteする。下の例では0をwriteしたが何でもよい。
→同時に、ADCから10ビットデータの下位8ビットが返ってくる。

まとめ

まとめると次のとおりである。これで、チャンネル0に印加された電圧が10ビットにAD変換される。?で表した10ビットがそのAD変換値である。spiを使わずに独自に実装するのであればもはや8ビット単位にこだわる必要はないのでスタートビットから始めればよい。

[0]バイト目 [1]バイト目 [2]バイト目
マスターからスレーブへ転送するデータ 0b 0000 0001 0b 1000 ---- 0b ---- ----
スレーブからマスターへ転送されるデータ 0b ---- ---- 0b ---- -0?? 0b ???? ????

1回だけADC値を読み出すためのMicroPythonスクリプト

上の手順をそのままMicroPythonで再現する。spiモジュールのおかげでえらく単純である。AD変換値を電圧値に戻してみる(要するにディジタル電圧計である)。

from microbit import *

mosi = bytearray([1, 0b10000000, 0])
miso = bytearray([0, 0, 0])

pin16.write_digital(1)
spi.init()

pin16.write_digital(0)
spi.write_readinto(mosi, miso)
pin16.write_digital(1)

print("MOSI data: %s" % ([bin(b) for b in mosi]))
print("MISO data: %s" % ([bin(b) for b in miso]))

ADdata = (raw[1]<<8 | raw[2]) & 1023
volt   = ADdata * 3.23/1024.0 # 3.23はMCP3008のVREF端子の実測値。

print("AD %d, %.2f(V)" % (ADdata, volt))

実行結果





整理してクラス化した

from microbit import *
class MCP3008:
    def __init__(self, CSpin=pin16):
        self.CS = CSpin.write_digital
        self.CS(1)

        self.mosi = [bytearray([1, (1<<7)|(ch<<4), 0]) for ch in range(8)]
        self.miso = bytearray([0, 0, 0])

    def read(self, CH):
        self.CH = CH

        self.CS(0)
        spi.write_readinto(self.mosi[CH], self.miso)
        self.CS(1)
        return (self.miso[1]<<8 | self.miso[2]) & 1023

##############
# how to use #
##############
if __name__ == "__main__":
    # Initialize the microbit.spi module.
    # You can also specify any of the following options:
    # baudrate=1000000, bits=8, mode=0, sclk=pin13, mosi=pin15, and miso=pin14
    spi.init()

    # Instantiate the MCP3008 class with !CS assigned to pin16.
    adc = MCP3008(CSpin=pin16)

    while True:
        # Get 10-bit data by converting the voltage applied to the channel 0 of MCP3008.
        ADdata = adc.read(CH=0)
        volt   = ADdata * 3.23/1024.0

        print("AD %d, %.2f(V)" % (ADdata, volt))
        sleep(1000)

実行結果

image.png

参考

関連

はてなブログ / ADコンバーターMCP3008 / SPI

0
0
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
0
0