Raspberry Piでアナログデジタル変換器(ADC)「MCP3208」を用いて、電圧値を変換してみます。MCP3208のインタフェースはSPIを使用し、SPI接続のためのbcm2835ライブラリを使用します。なお、bcm2835ライブラリのインストールについては、「bcm2835 ライブラリによるスイッチ入力とLEDの点滅」に示します。

Raspberry PiとMCP3208との接続

Raspberry PiとMCP3208との接続図を次に示します。
Raspberry PiとADC接続図

電圧値はそれぞれのチャンネルに次のような値が設定されます。

  • 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 とのデータ転送

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