Raspberry Piでアナログデジタル変換器(ADC)「MCP3208」を用いて、電圧値を変換してみます。MCP3208のインタフェースはSPIを使用し、SPI接続のためのbcm2835ライブラリを使用します。なお、bcm2835ライブラリのインストールについては、「bcm2835 ライブラリによるスイッチ入力とLEDの点滅」に示します。
Raspberry PiとMCP3208との接続
Raspberry PiとMCP3208との接続図を次に示します。
電圧値はそれぞれのチャンネルに次のような値が設定されます。
- CH0:0.0V
- CH1:1.6V
- CH2:3.3V
MCP3208から電圧値の入力
bcm2835ライブラリのSPI関数を用いて、MCP3208に接続された電圧値を読み込み表示します。ADCプログラム「adcread.c」を次に示します。
ここで利用する ADC である MCP3204/08 は,そのデータシートによれば,5 ビットからなるコマンド(1, S/D, D2, D1, D0)とそれに続く任意の 14 ビットのデータ(合計 19 ビット)をマスターから受信すると,その 7 ビット目の時点から,0 とそれに続く 12 ビットのデータ(合計 13 ビット)をマスターに送信するようになっています.Raspberry Pi の SPI は 8 ビット単位の送受信しかできない(たぶん)ので,下図のような 3 バイトの「交換」によってスレーブにコマンド(ADC のチャネル指定など)を送り,その結果(12 ビットのデータ)をスレーブから受け取ります.
ADC へのコマンドは,コマンドの先頭を表示する 1 から始まり,シングルエンド入力(Single)と差動入力(Differential)を選択する S/D ビット,そしてチャネルを指定する D2, D1, D0 が続きます。D2×4+D1×2+D0 がチャネル番号(0〜7)となります.ここではシングルエンド入力のみを扱いますので S/D = 1 とします。この 5 ビットのコマンドに先行する 5 ビットはすべて 0 としなければなりません。また後続する 14 ビットは 1 でも 0 でも構いません。
ADC から返答されるデータは,通信開始から 12 ビット目以降に有意味なデータが含まれています。12 ビット目にデータの先頭を表示する 0、その後ろに 12 ビットの二進数(B11〜0)が続きます.これらに先行する 11 ビット分については,ADC からは何もデータが送られません。
ADCプログラム「adcread.c」
#include <bcm2835.h> #include <stdio.h> int main(int arc, char **argv) { char out_ch0[] = { 0b00000110, 0b00000000, 0b00000000 }; char ch0_data[] = { 0x00, 0x00, 0x00 }; char out_ch1[] = { 0b00000110, 0b01000000, 0b00000000 }; char ch1_data[] = { 0x00, 0x00, 0x00 }; char out_ch2[] = { 0b00000110, 0b10000000, 0b00000000 }; char ch2_data[] = { 0x00, 0x00, 0x00 }; if(!bcm2835_init()) return 1; bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_128); bcm2835_spi_chipSelect(BCM2835_SPI_CS1); bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW); bcm2835_spi_transfernb(out_ch0, ch0_data, 3); printf("CH0: %02X %02X %02X\n", ch0_data[0], ch0_data[1], ch0_data[2]); bcm2835_spi_transfernb(out_ch1, ch1_data, 3); printf("CH1: %02X %02X %02X\n", ch1_data[0], ch1_data[1], ch1_data[2]); bcm2835_spi_transfernb(out_ch2, ch2_data, 3); printf("CH2: %02X %02X %02X\n", ch2_data[0], ch2_data[1], ch2_data[2]); bcm2835_spi_end(); bcm2835_close(); }
プログラムのビルドは次のコマンドを使用します。
$ gcc -o adcread adcread.c -l bcm2835
プログラムを実行すると、電圧値が表示されます。
$ sudo ./adcread CH0: 00 00 2B CH1: 00 08 16 CH2: 00 0F FC