2015年12月31日木曜日

RaspberryPi で温度センサー + MCP3002 を使って室内の温度を計測してみた

概要

アナログ温度センサー + MCP3002 を使って室内の温度を計測してみました
RaspberryPi はアナログ温度センサーのアナログ信号を直接受け取ることはできません
そこで、A/Dコンバータである MCP3002 を使ってアナログ信号をデジタル信号に変換し RaspberryPi で取得します

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+
  • Python 2.7.9
  • pip 7.1.2
  • spidev 3.1

SPI を有効にする

RaspberryPi の SPI (Serial Peripheral Interface Bus) を有効にします
デフォルトでは無効になっているので有効にして再起動する必要があります

SPI を有効にすることで A/D コンバータ (MCP3002) を使うことができるようになります

  • sudo cp /boot/config.txt{,.back}
  • sudo vim /boot/config.txt

以下のような差分になるように修正します

48c48
< dtparam=spi=on
---
> #dtparam=spi=on

dtparam=spi という項目があるので、それをコメントアウトすれば OK です
コメントアウトしたら RaspberryPi を一旦再起動します

  • sudo reboot

再起動したら SPI が有効になっているか確認します

  • lsmod | grep spi
spi_bcm2835             7980  0

上記のようになっていれば OK です

spidev をインストールする

spidev は Python 用の SPI ライブラリです
pip を使ってインストールすれば OK です

  • sudo pip install spidev

配線

RaspberryPi とブレッドボードを使って配線します
実際の配線全体図は以下の通りです
rpi_temp_circuit.jpg

写真だと分かりづらいのでツールを使って書いた配線図は以下の通りです
rpi_temp_circuit_fritzing.png

ポイント

左上の三本足の黒いセンサーがアナログ温度センサーです
VDD と GND そして信号を出力する三本があります
平面左から VDD、出力、GND になります
順番を間違えずに配線する必要があります

真ん中から出力された信号を MCP3002 で受信します
受信するピンは決まっており MCP3002 の場合は 2 箇所 ( 2ch ) で受信することができます
今回は 1 つしかセンサーを使っていないので 1 ch 使えば OK です

あとは MCP3002 の出力を RaspberryPi の SPI 用の GPIO で信号を受信すれば OK です
RaspberryPi 側で使用する SPI 用の GPIO は「CS0」「SCLK」「MISO」「MOSI」になります

配線が完了したら RaspberryPi の電源を入れましょう

ソースコードデプロイ

あとは受信したデータを表示するプログラムをデプロイすれば OK です

  • cd ~
  • mkdir -p work/mcp3002_temperature
  • cd work/mcp3002_temperature
  • touch temperature_sample.py
#!/usr/bin/env python

import time
import sys
import spidev

spi = spidev.SpiDev()
spi.open(0,0)

def readAdc(channel):
    adc = spi.xfer2([1, (2 + channel) << 6,0])
    data = ((adc[1] & 31) << 6) + (adc[2] >> 2)
    return data

def convertVolts(data):
    volts = (data * 3.3) / float(1024)
    volts = round(volts, 4)
    return volts

def convertTemp(volts):
    temp = (100 * volts) - 50.0
    temp = round(temp,4)
    return temp

if __name__ == '__main__':
    try:
        while True:
            data = readAdc(0)
            print("adc  : {:8} ".format(data))
            volts = convertVolts(data)
            temp = convertTemp(volts)
            print("volts: {:8.2f}".format(volts))
            print("temp : {:8.2f}".format(temp))

            time.sleep(5)
    except KeyboardInterrupt:
        spi.close()
        sys.exit(0)

実行してみましょう

  • python temperature_sample.py

でうまく配線できていれば以下のように出力してくれます

adc : 222
volts: 0.72
temp : 21.54
adc : 219
volts: 0.71
temp : 20.58

温度は一番したの 21.54, 20.58 になります
摂氏で出力するようにプログラムしています

ポイントは readAdc でここで spidev を使って変換したアナログ信号をデジタル信号で取得します
実行した際の adc がその値になります
今回使っている MCP3002 は 10 bit 2ch の A/D コンバータでデジタル信号に変更すると 0 - 1024 の範囲 ( 10bit の範囲 ) で値を変換してくれます
最近だと 12bit の A/D コンバータもありビット数が増えれば増えるほどより精度の高い信号を取得できるようになります

最後に

MCP3002 という A/D コンバータを使ってアナログ信号をデジタル信号に変換してみました
センサー系のデバイスは基本的にアナログ信号で受信するしかないので A/D コンバータが必須になります
次は圧力センサーの値でも取得してみたいと思います

参考サイト

0 件のコメント:

コメントを投稿