Raspberry Pi用のA/Dコンバータ

著者:Adafruit Industries

image

Adafruit社のご厚意による

Tony DiColaによるガイド

Raspberry Piは、デジタル入出力を制御するための優れた小型ボードコンピュータです。しかし、サーミスタやポテンショメータ、その他多くの種類のセンサから得られるようなアナログ信号を読み取りたい場合はどうしたらよいでしょうか?あきらめないでください! 小さなA/Dコンバータ(Analog to Digital Converter, ADC)チップをPiに接続することで、Raspberry Piのプログラムにアナログ信号の世界を開くことができるのです!

このガイドでは、Raspberry PiでPythonを使ってアナログ値を読み取るための素晴らしい方法をいくつか紹介します。シンプルなA/Dコンバータ(ADC)MCP3008を使用して、最大8チャンネルのアナログ入力を10ビット精度で読み取ることができます。あるいは、より高度なADS1x15シリーズADCを使えば、4チャンネルを12~16ビット精度で読み取ることができ、プログラマブルな増幅段も備えています。この2つのADCからアナログ入力を読み取るためには、Pythonライブラリとサンプルを使えば、すぐに使いこなすことができます。

Raspberry Piを使い始める前に、OSのロード、ネットワークの設定、およびSSHを使ったターミナルへの接続など、Raspberry Piを使う上での基本的な知識を身につけましょう。詳しくは、Learn Raspberry Pi(Raspberry Piを学ぶ)シリーズをご覧ください。

また、ガイドに従って作業を始める前に、Raspberry Piが最新のRaspbian Jessieオペレーティングシステム(フルバージョンまたはライトバージョンのいずれか)を実行していることを確認してください。

MCP3008ADS1015 / ADS1115のA/DコンバータをRaspberry Piで使用する方法については、引き続き説明します。

MCP3008

MCP3008は低価格の8チャンネル10bitのA/Dコンバータです。このADCの精度はArduino Unoとほぼ同じで、8チャンネルあるのでかなりの数のアナログ信号をPiから読み出すことができます。このチップは、温度センサや光センサからの単純なアナログ信号を読み取る必要がある場合に最適なオプションです。より高い精度や機能が必要な場合は、次ページのADS1x115シリーズをご覧ください。

MCP3008を使用する前に、older Raspberry Pi MCP3008 guide(旧版のRaspberry Pi MCP3008ガイド)に目を通すと、Raspberry Piで使用する上でより詳しい情報を得ることができます。しかし、旧版のガイドからのコードは非推奨なので使用しないでください 。このガイドでは、MCP3008 ADCと通信するための新しいPythonコードをインストールし、使用するための簡単な方法を説明します。

またMCP3008 datasheetも重要な資料となりますので、手元に置いておくことをお勧めします。

配線について

MCP3008は、SPIシリアル接続でRaspberry Piに接続します。ハードウェアSPIバス、または4つのGPIOピンとソフトウェアSPIを使用してMCP3008と通信することができます。ソフトウェアSPIは、Piのどのピンでも動作するため、柔軟性があります。一方、ハードウェアSPIは、特定のピンでしか動作しないため、若干高速ですが、柔軟性に欠けます。もし、どちらを使うか迷ったら、セットアップが簡単なソフトウェアSPIをお勧めします。

チップをPiに配線する前に、まずチップをブレッドボードに取り付ける必要があります。MCP3008のようなDIPチップを使ったことがない場合は、ブレッドボードの真ん中の空の溝に、足をまたがせるように押し込んでください。こうすることで、ブレッドボードからチップの各ピンにアクセスすることができます。

チップの向きは重要です。! 必ず半円のくぼみとドットが上になるように置いてください。下の写真を例としてご覧ください。

チップをブレッドボードに取り付けたら、Piに接続する準備ができました。MCP3008チップの各ピンには、以下のような名前がついています。

image

ソフトウェアSPI

MCP3008とRaspberry PiをソフトウェアSPI接続するためには、以下の接続が必要です。

  • MCP3008のVDDRaspberry Piの3.3V
  • MCP3008のVREFRaspberry Piの3.3V
  • MCP3008のAGNDRaspberry PiのGND
  • MCP3008のDGNDRaspberry PiのGND
  • MCP3008のCLKRaspberry Piのピン18
  • MCP3008のDOUTRaspberry Piのピン23
  • MCP3008のDINRaspberry Piのピン24
  • MCP3008のCS/SHDNRaspberryのピン25

MCP3008のCLK、DOUT、DIN、およびCS/SHDNピンをRaspberry Piの他の空いているデジタルGPIOピンに差し替えることができることに注意してください。あなたのピンを使用するには、サンプルコードを変更すればいいだけです。

ハードウェアSPI

ハードウェアSPIを使用するには、まずraspi-configツールを使ってSPIを有効にしていること(enabled SPI using the raspi-config tool)を確認します。SPIインターフェースの有効化とSPIカーネルモジュールのロードの両方にYesと答え、Piを再起動します。ls -l /dev/spi* コマンドを実行したときに /dev/spidev0.0 と /dev/spidev0.1 デバイスが表示されることを確認してから続行してください。

ここで、MCP3008とRaspberry Piを以下のように配線します。

  • MCP3008のVDDRaspberry Piの3.3V
  • MCP3008のVREFRaspberry Piの3.3V
  • MCP3008のAGNDRaspberry PiのGND
  • MCP3008のDGNDRaspberry PiのGND
  • MCP3008のCLKRaspberry PiのSCLK
  • MCP3008のDOUTRaspberry PiのMISO
  • MCP3008のDINRaspberry Pi MOSI
  • MCP3008のCS/SHDNRaspberryのPi CE0

ライブラリのインストール

MCP3008とRaspberry PiをソフトウェアまたはハードウェアのSPI配線で接続したら、Adafruit MCP3008 Python libraryをインストールする準備ができています。

Python package indexからいくつかのコマンドを使ってライブラリをインストールすることができますし、GitHubにあるソースからインストールすることもできます。もし、よくわからないのであれば、ライブラリを使用するためのサンプルもダウンロードできますので、 source on GitHub(GitHubにあるソース)からインストールすることをお勧めします。

なお、ライブラリをインストールする前に、Raspberry Piが有線または無線ネットワークでインターネットに接続されている必要があります。

ソースからのインストール

Githubのソースからインストールする場合は、Raspberry Piのターミナルに接続し、以下のコマンドを実行します。

sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus git
cd ~
git clone https://github.com/adafruit/Adafruit_Python_MCP3008.git
cd Adafruit_Python_MCP3008
sudo python setup.py install

ライブラリのインストールが成功し、以下のようなメッセージが表示されて終了します。

エラーが表示されたら、前に戻って、前のコマンドがすべて実行されているか、エラーで終わっていないか、注意深く確認してください。

Python Package Indexからのインストール

Python package indexからインストールする場合、Raspberry Piのターミナルに接続し、以下のコマンドを実行します。

sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus python-pip
sudo pip install adafruit-mcp3008

以下のようなメッセージが表示されたら、ライブラリのインストールに成功したことになります。

Python package indexからインストールした場合、ライブラリのサンプルコードがないことに注意してください。これらのdownload these MCP3008サンプルを手動でPiにダウンロードし、次のセクションで実行する必要があります。

ライブラリの使い方

このライブラリの使い方を学ぶために、ライブラリに含まれるサンプルコードをいくつか見ていきましょう。これらのサンプルは、ライブラリをソースからダウンロードしてインストールした場合、examplesフォルダにあります。Pi上で実行してそのフォルダに移動してください。

cd ~/Adafruit_Python_MCP3008/examples

注: Python package indexからpipコマンドでライブラリをインストールした場合は、サンプルコードがないので、手動でPiにダウンロードする必要があります。

まず、ADCチャンネルの値を読み込んで表示する基本的なサンプルであるsimpletest.pyの例を見てみましょう。まず、ソフトウェアまたはハードウェアSPIを使用するように設定するために、ファイルを開いてみましょう。以下のコマンドを実行し、nanoテキストエディタでファイルを開いてください。

nano simpletest.py

次に、上部にある次のブロックのコードまでスクロールしてください。

# Software SPI configuration:
CLK  = 18
MISO = 23
MOSI = 24
CS   = 25
mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)

# Hardware SPI configuration:
# SPI_PORT   = 0
# SPI_DEVICE = 0
# mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))

デフォルトでは、このセクションのコードは、前のセクションで説明したソフトウェアSPI設定を使用するようにチップを設定しています。ソフトウェアSPI設定に異なるピンを使用した場合は、CLK、MISO、MOSI、およびCS の値を使用したピンに変更してください。

ハードウェアSPIを使用した場合は、ソフトウェアSPIセクションをコメントアウトし、ハードウェアSPIセクションをアンコメントする必要があります。ハードウェアSPIを使用する場合は、以下のような設定になります。

# Software SPI configuration:
# CLK  = 18
# MISO = 23
# MOSI = 24
# CS   = 25
# mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)

# Hardware SPI configuration:
SPI_PORT   = 0
SPI_DEVICE = 0
mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))

Ctrl-oEnter、そして Ctrl-xでファイルを保存し、終了してください。ターミナルで実行すると、simpletest.py のコードが実行されます。

sudo python simpletest.py

このサンプルでは、すべてのADCチャンネルとその値を含むテーブルを表示します。0.5秒ごとに新しい行が表示され、最新のチャンネル値が表示されます。例えば、次のような出力が表示されます。

各列は異なるチャンネルを表し、最初の行のヘッダにはチャンネル番号(0~7まで、合計8チャンネル)が表示されます。各チャンネルの値は、そのチャンネルのADC値です。これは0~1023までの数値で、0は信号がグランドレベル、1023はAREF値(3.3V)以上であることを意味します。その間のADC値は入力電圧に比例するので、512の値は3.3/2、つまり約1.65Vとなります。

Ctrl-cを押して、サンプルを停止します。

アナログ入力の1つにポテンショメータを接続してみてください。ポテンショメータの真ん中の端子(ワイパ)をアナログ入力に接続し、他の端子の1本をPiの3.3Vに、もう1本をPiのグランドに接続してください。サンプルを実行し、ポテンショメータを回してみてください。ポテンショメータからの電圧が下がるとADC値が変化して低くなり、電圧が上がるとADC値が高くなるのがわかるはずです!

このコードがどのように動作するかを理解するために、もう一度nanoでsimpletest.pyのサンプルを開いてみてください。今度は一番下のメインループまでスクロールダウンしてください。

print('Reading MCP3008 values, press Ctrl-C to quit...')
# Print nice channel column headers.
print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*range(8)))
print('-' * 57)
# Main program loop.
while True:
    # Read all the ADC channel values in a list.
    values = [0]*8
    for i in range(8):
        # The read_adc function will get the value of the specified channel (0-7).
        values[i] = mcp.read_adc(i)
    # Print the ADC values.
    print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values))
    # Pause for half a second.
    time.sleep(0.5)

このコードは少し複雑に見えるかもしれませんが、その複雑さのほとんどはテーブルを表示することに起因しています。ADCチャンネルの値を読み込んでリストに保存する次の行に注目してください。

values[i] = mcp.read_adc(i)

この行は、MCP3008のPythonライブラリからread_adc() 関数を呼び出しています。この関数は1つのパラメータ、つまり読み込むチャンネル番号(0から7の値)を受け取ります。その結果、関数はそのチャンネルの現在のADC値を返します。

自分のコードでADCチャンネルを読むのは、read_adc() 関数を呼ぶのと同じくらい簡単です!読み込むチャンネルを渡せば、その値が返されます。MCP3008ライブラリを使用してアナログ値を読み出すためにすることはこれだけです。!

もし興味があれば、simpletest.pyを実行したのと同じように、differential.pyのサンプルを調べて実行することができます。ソフトウェアまたはハードウェアSPIのどちらかですが、あなたの配線に合うように設定を変更します。そして、サンプルを実行するとread_adc_difference() 関数が呼び出され、それを使ってチップのチャンネル0と1の間の電圧差を読み取ります。アナログ信号のノイズなどの影響を軽減するために、2つの信号の差を読み取ることが有効な場合があります。

MCP3008のPythonライブラリの紹介は以上です。!

ADS1015 / ADS1115

ADS1015とADS1115は、Raspberry PiのI2C通信バスを利用して簡単に使える優れたA/Dコンバータです。ADS1015は4チャンネル12ビットADC、ADS1115は4チャンネル16ビットADCで、より高精度なADCです。どちらも2/3倍から16倍までのゲインをプログラムできるので、小さな信号を増幅してより高精度に読み取ることができます。MCP3008や他のシンプルなADCからのステップアップをお考えなら、ADS1x15シリーズは最適な選択肢です!

始める前に、必ずADS1x15ガイドに従ってヘッダにはんだ付けしてADCボードを組み立ててください。

また、これらのチップのデータシートにもご興味があるかもしれません。

配線について

ADS1015とADS1115は、どちらも同じI2C通信プロトコルを使ってアナログ値を読み取ります。それぞれのチップとPiの配線は、以下のように全く同じ方法で行うことができます。

ADCをPiに配線する前に、Raspberry PiのI2Cをraspi-configで有効にしてください。I2Cを有効にして、i2cdetectコマンドでADCが表示されることを確認するまでは、先に進んではいけません。

ADCとPiを以下のように接続します。

  • ADS1x15のVDDRaspberry Piの3.3V
  • ADS1x15のGNDRaspberry PiのGND
  • ADS1x15のSCLRaspberry PiのSCL
  • ADS1x15のSDARaspberry PiのSDA

ライブラリのインストール

ADS1x15とRaspberry Piの配線が終わったので、Adafruit ADS1x15 Pythonライブラリをインストールする準備ができました。

Python package indexからいくつかのコマンドを使ってライブラリをインストールすることができます。また、GitHubにあるソースからライブラリをインストールすることもできます。以下のオプションのいずれかを選択してください。よくわからない場合は、ライブラリの使用例もダウンロードできますので、GitHubのソースからインストールすることをお勧めします。

なお、ライブラリをインストールする前に、Raspberry Piが有線または無線ネットワークでインターネットに接続されている必要が あります

ソースからのインストール

Githubのソースからインストールする場合は、Raspberry Piのターミナルに接続し、以下のコマンドを実行します。

sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus git
cd ~
git clone https://github.com/adafruit/Adafruit_Python_ADS1x15.git
cd Adafruit_Python_ADS1x15
sudo python setup.py install

ライブラリのインストールが成功し、以下のようなメッセージが表示されて終了します。

エラーが表示されたら、前に戻って、前のコマンドがすべて実行されたか、エラーで失敗していないか、慎重に確認してください。

Python Package Indexからのインストール

Python package indexからインストールする場合、Raspberry Piのターミナルに接続し、以下のコマンドを実行します。

sudo apt-get update
sudo apt-get install build-essential python-dev python-smbus python-pip
sudo pip install adafruit-ads1x15

以下のようなメッセージが表示されたら、ライブラリのインストールに成功したことになります。

Python package indexからインストールした場合、ライブラリのサンプルコードがないことに注意してください。次のセクションで、手動でこれらのADS1x15のサンプルをPiにダウンロードし、実行する必要があります。

ライブラリの利用について

ライブラリの使い方を学ぶために、ライブラリに含まれるサンプルコードのいくつかを見ていくことにします。これらのサンプルは、ライブラリをソースからダウンロードしてインストールした場合、examplesフォルダにあります。Pi上で実行してそのフォルダに移動してください。

cd ~/Adafruit_Python_ADS1x15/examples

注: Python package indexからpipコマンドでライブラリをインストールした場合は、サンプルコードがないので、手動でPiにダウンロードする必要があります。

まず、ADCチャンネルの値を読み込んで表示する基本的なサンプルであるsimpletest.pyのサンプルを見てみましょう。まず、どのチップを使うかを設定するためのファイルを開きましょう。以下のコマンドを実行し、nanoテキストエディタでファイルを開いてください。

nano simpletest.py

次に、上部にある次のコードのブロックまでスクロールします。

# Create an ADS1115 ADC (16-bit) instance.
adc = Adafruit_ADS1x15.ADS1115()

# Or create an ADS1015 ADC (12-bit) instance.
#adc = Adafruit_ADS1x15.ADS1015()

# Note you can change the I2C address from its default (0x48), and/or the I2C
# bus by passing in these optional parameters:
#adc = Adafruit_ADS1x15.ADS1015(address=0x49, bus=1)

このコードは、ADS1115チップまたは ADS1015チップのいずれかを使用するようにサンプルを設定します。一番上のコメントされていない行は、ADS1115オブジェクトを作成してADS1115チップを使用することを選択しています。その下のコメントされた行は、代わりにADS1015オブジェクトを作成してADS1015チップを使用することを選択するコメント行です。使用するチップに応じて、適切な行をアンコメントしてください。

例えば、ADS1015を使用する場合、コードは以下のようになります。

# Create an ADS1115 ADC (16-bit) instance.
# adc = Adafruit_ADS1x15.ADS1115()

# Or create an ADS1015 ADC (12-bit) instance.
adc = Adafruit_ADS1x15.ADS1015()

# Note you can change the I2C address from its default (0x48), and/or the I2C
# bus by passing in these optional parameters:
#adc = Adafruit_ADS1x15.ADS1015(address=0x49, bus=1)

最後のコメント行は、カスタムI2Cアドレスやバス番号の選択など、より高度な使い方を示しています。通常、これらの値を変更する必要はありません。

Ctrl-oEnter、そしてCtrl-xでファイルを保存し、終了してください。ターミナルで実行するsimpletest.pyのコードが実行されます。

sudo python simpletest.py

このサンプルでは、すべての ADCチャンネルとその値を含むテーブルを表示します。0.5秒ごとに新しい行が表示され、最新のチャンネル値が表示されます。例えば、次のような出力が表示されます。

各列は異なるチャンネルを表し、最初の行のヘッダにはチャンネル番号(0から3まで、合計4チャンネル)が表示されます。各チャンネルの値は、そのチャンネルのADC値です。これは、16 ビットのADS1115では-32768~32767、12 ビットのADS1015では-2048~2047の範囲の数値です。0は信号がグランドレベルであることを、32767(ADS105 では2047)は電流ゲインの最大電圧値(デフォルトでは 4.096V)以上であることを、-32768(ADS1015 では-2048)はグランド以下の負の電圧であることを意味します。その間のADC値は入力電圧に比例するので、16384の値は4.096÷2で約2.048Vになります。

Ctrl-cを押して、サンプルを停止します。

アナログ入力の1つにポテンショメータを接続してみてください。ポテンショメータの真ん中の端子(ワイパ)をアナログ入力に接続し、他の端子の1つをPiの3.3Vに、他の端子をPiのグランドに接続します。サンプルを実行し、ポテンショメータを回してみてください。ポテンショメータからの電圧が下がるとADC値が変化して低くなり、電圧が上がるとADC値が高くなるのがわかるはずです!

このコードがどのように動作するかを理解するために、もう一度nanoでsimpletest.pyのサンプルを開いてみてください。コードのこのセクションまでスクロールダウンしてください。

# Choose a gain of 1 for reading voltages from 0 to 4.09V.
# Or pick a different gain to change the range of voltages that are read:
#  - 2/3 =  /-6.144V
#  -   1 =  /-4.096V
#  -   2 =  /-2.048V
#  -   4 =  /-1.024V
#  -   8 =  /-0.512V
#  -  16 =  /-0.256V
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
GAIN = 1

このコードは、ADCが信号を読み出すときに使用するゲインを設定します。ゲインを上げると信号が増幅されるので、小さな弱い信号も読み取りやすくなります。また、ゲインはチップで読み取れる電圧の範囲も制御します。ゲイン値が1の場合、電圧の範囲は4.096ボルトであることを通知します。つまり、チップは-4.096ボルトから4.096ボルトまでの値を読み取ることができます。ゲインを高くすれば、弱い信号でも高い精度で読み取ることができます(より小さな範囲の値を表現するために、より多くのビットが使用されるため)。

信号に対して適切なゲインを選択することは非常に重要であり、表示される可能性のある電圧の範囲について検討する価値があります。ゲインが高すぎると、信号がADCの最大電圧を超えるため、不正確な結果が出ますし、低すぎると、信号がノイズに埋もれて読みにくくなります。慎重に選択してください!

今度は、一番下のメインループまでスクロールしてください。

print('Reading ADS1x15 values, press Ctrl-C to quit...')
# Print nice channel column headers.
print('| {0:>6} | {1:>6} | {2:>6} | {3:>6} |'.format(*range(4)))
print('-' * 37)
# Main loop.
while True:
    # Read all the ADC channel values in a list.
    values = [0]*4
    for i in range(4):
        # Read the specified ADC channel using the previously set gain value.
        values[i] = adc.read_adc(i, gain=GAIN)
        # Note you can also pass in an optional data_rate parameter that controls
        # the ADC conversion time (in samples/second). Each chip has a different
        # set of allowed data rate values, see datasheet Table 9 config register
        # DR bit values.
        #values[i] = adc.read_adc(i, gain=GAIN, data_rate=128)
        # Each value will be a 12 or 16 bit signed integer value depending on the
        # ADC (ADS1015 = 12-bit, ADS1115 = 16-bit).
    # Print the ADC values.
    print('| {0:>6} | {1:>6} | {2:>6} | {3:>6} |'.format(*values))
    # Pause for half a second.
    time.sleep(0.5)

このコードは少し複雑に見えるかもしれませんが、その複雑さのほとんどはテーブルを表示することに起因しています。ADCチャンネルの値を読み込んでリストに保存するこの行に注目してください。

values[i] = adc.read_adc(i, gain=GAIN)

この行は、ADS1x15 Pythonライブラリからread_adc() 関数を呼び出しています。この関数は1つのパラメータ、つまり読み込むチャンネル番号(0から3の値)、そしてオプションでゲイン値(デフォルトは1)を受け取ります。その結果、この関数はそのチャンネルの現在のADC値を返します。

自分のコードでADCチャンネルを読むのは、read_adc()関数を呼ぶのと同じくらい簡単です!読み込むチャンネルを渡せば、その値を返してくれます。ADS1x15のライブラリを使ってアナログ値を読み取る方法は、本当にこれだけです!

もし興味があれば、simpletest.pyを実行したのと同じように、differential.pyのサンプルを調べて実行することができます。チップを選択するために設定を変更します。そして、サンプルを実行すると、read_adc_difference() 関数が呼び出され、それを使ってチップのチャンネル0と1の間の電圧差を読み取ることになります。アナログ信号のノイズなどの影響を軽減するために、2つの信号の差を読み取ることが有効な場合があります。

さらに、continuous.py のサンプルは、連続読み出しモードをオンにして、ADC値のストリームを読み出す方法を実証しています。これは、チップから値を読み取るだけで、read_adc() 関数を常に呼び出す煩わしさを望まない場合に便利です。その仕組みについては、サンプルのコメントをご覧ください。

最後に、comparator.pyのサンプルでは、ADC値が特定の範囲に収まったときにALERT出力ピンを有効にする、より高度なモードのチップを紹介しています。この機能も、コメントやデータシートが参考になるはずです。

ADS1x15 Pythonライブラリは以上です!

主要部品と構成要素

imageimageimage
imageimage


すべてのDigi-Key部品をカートに追加する

  • MCP3008T-I/SLCT-ND
  • 1528-1003-ND
  • 1528-1461-ND
  • 1528-1493-ND
  • 438-1045-ND

image
    ご質問やご意見がおありですか?Digi-Keyのオンラインコミュニティであり、技術情報源でもある
    TechForumに投稿して下さい。




オリジナル・ソース(English)