LoginSignup
45
47

More than 5 years have passed since last update.

はじめてのAD変換(RaspberryPi3で試すアナログ・デジタル変換)

Last updated at Posted at 2016-11-22
1 / 25

今日のゴール


アナログ値をデジタル値に変換する


"AD変換"


本記事の登場人物


主役

彼らがAD変換の主役です。本記事で解説します。

  • 12ビットADコンバータ MCP3208-CI/P x 1
    • アナログ値をデジタル値に変換します
  • 半固定抵抗 x 1
    • 抵抗値を変化させアナログ値をセンシングします
  • フォトレジスタ x 1
    • 抵抗値を変化させアナログ値をセンシングします

脇役

ちなみに彼らも必要ですが、本記事では解説しません。

  • RaspberryPi一式
  • 抵抗(330Ω) x 1
  • 赤色LED x 1
  • ブレッドボード x 1
  • ジャンパワイヤ
    • オス-メス x 1セット
    • オス-オス x 1セット

AD変換とは?

アナログ値をデジタル値に変換します。


なぜデジタル値が必要なのか?

RaspberryPiへの入力は基本的には、2進数として、LOW(0)/HIGH(1) 2つの状態のどちらかになる。
これは、部屋の明るさだと、明かりがついているか消えているか、の2段階として理解します。

これをデジタル値、0-4095のような段階的な値として入力することを狙います。


そもそもアナログ値、デジタル値って?

  • アナログ値
    • 連続値
    • e.g. 明るさ、温度、電圧など
  • デジタル値
    • 飛び飛びの値(離散値)
    • e.g. 計測して桁を切り捨てた値(デジタル時計)など

AD変換 (画像引用元: Raspberry Piで学ぶ電子工作|ブルーバックス)

adc.jpg

  • 1. センサからのアナログ値の取得
  • 2. AD変換
  • 3. デジタル値の通信

1. センサからのアナログ値の取得:

特定の地点での抵抗値を変化させ、端子から出力させるアナログ電圧を変化させる(0V-3.3V)1.65V

  • 半固定抵抗
  • フォトレジスタ (CdSセル)

半固定抵抗?

P-06110.jpg

画像引用元: akizukidenshi.com

  • 可変抵抗の一つで抵抗の大きさを調整可能

フォトレジスタ (CdSセル)?

I-00110.jpg

画像引用元: akizukidenshi.com


2. AD変換

アナログ電圧を測定しその値を、ADコンバータにてAD変換しデジタル値にする(0-4095->12bit) 2048

  • ADコンバータ

ADコンバータ?

(12ビットADコンバータ MCP3208-CI/P)

I-00238.JPG

画像引用元: akizukidenshi.com


ADコンバータ特徴

  • 16ピンを持つ回路
    • 0ch-7chの8つのアナログ値を読み取れるチャネル
  • アナログ値をデジタル値に変換する
  • 12ビット精度で送れる
    • $2^12=4096=4*10^3$

スクリーンショット 2016-11-22 1.59.36.png

MCP3204/3208データシート


3. シリアル通信

デジタル値を2進数 (1000_0000_0000 = 2048) としてSPI通信で送る

  • SPI通信
  • I2C通信

3. シリアル通信

スクリーンショット 2016-11-22 1.55.37.png

MCP3204/3208データシート


code

# MCP3208からSPI通信で12ビットのデジタル値を取得。0から7の8チャンネル使用可
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if adcnum > 7 or adcnum < 0:
        return -1
    GPIO.output(cspin, GPIO.HIGH)
    GPIO.output(clockpin, GPIO.LOW)
    GPIO.output(cspin, GPIO.LOW)

    commandout = adcnum
    commandout |= 0x18  # スタートビット+シングルエンドビット
    commandout <<= 3    # LSBから8ビット目を送信するようにする
    for i in range(5):
        # LSBから数えて8ビット目から4ビット目までを送信
        if commandout & 0x80:
            GPIO.output(mosipin, GPIO.HIGH)
        else:
            GPIO.output(mosipin, GPIO.LOW)
        commandout <<= 1
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
    adcout = 0
    # 13ビット読む(ヌルビット+12ビットデータ)
    for i in range(13):
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
        adcout <<= 1
        if i>0 and GPIO.input(misopin)==GPIO.HIGH:
            adcout |= 0x1
    GPIO.output(cspin, GPIO.HIGH)
    return adcout
inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)

演習1

スクリーンショット 2016-11-21 0.22.03.png

画像引用元: Raspberry Piで学ぶ電子工作|ブルーバックス

06-01-print.py
    while True:
        inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        print(inputVal0)

演習2

スクリーンショット 2016-11-21 0.22.10.png

画像引用元: Raspberry Piで学ぶ電子工作|ブルーバックス

06-02-led.py
    while True:
        inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        if inputVal0 < 2000:
            GPIO.output(LED, GPIO.HIGH)
        else:
            GPIO.output(LED, GPIO.LOW)

演習3

06-03-volume.py
    while True:
        inputVal0 = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        vol = "{0}%".format(int(inputVal0*100/4095))
        if vol != vol_old:
            print(vol)
            args = ['amixer','-q','cset','numid=1',vol]
            subprocess.Popen(args)
            vol_old = vol

まとめ

  • AD変換することで、センサーに入力されたアナログ値をデジタル値として回路から利用することができる
  • AD変換はADコンバーターを使って行う
  • デジタル値の通信はSPI通信でおこなう

なお、AD変換の仕組みはRaspberry Piで学ぶ電子工作(ブルーバックス)にわかりやすくまとまっているので、みなさん買って読みましょう。


参考

書籍

回路

45
47
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
45
47