MCP3002を使う(analogRead編)


前回はwiringPiSPIDataRW()を使用したADコンバータの使用方法 を紹介しました。
今回はanalogRead()を使用したADコンバータの使用方法を紹介します。
MCP3002のライブラリには不具合が有りますので、「$HOME/wiringPi/wiringPi/MCP3002.c」を一部修正しま す。
赤字の部分が修正した箇所です。
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
{
  unsigned char spiData [2] ;
  unsigned char chanBits ;
  int chan = pin - node->pinBase ;

  if (chan == 0)
//    chanBits = 0b11010000 ;
    chanBits = 0b01100000 ;
  else
//    chanBits = 0b11110000 ;
    chanBits = 0b01110000 ;

  spiData [0] = chanBits ;
  spiData [1] = 0 ;

  printf("[MCP3002]data[write]=%02x-%02x\n",spiData[0],spiData[1]);
  wiringPiSPIDataRW (node->fd, spiData, 2) ;
  printf("[MCP3002]data[read]=%02x-%02x\n",spiData[0],spiData[1]);

//  return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
  return ((spiData [0] << 8) | (spiData [1] >> 0)) & 0x3FF ;
}

回路図は前回と同じですが、コードは以下のようになります。
/*
* Read MPC3002 with analogRead
*/
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>

#define DEBUG 0
#define SPI_CHANNEL 0 // /dev/spidev0.0
//#define SPI_CHANNEL 1 // /dev/spidev0.1
#define PINBASE 100

int main(int argc, char **argv){
    int retCode;
    int i;
    int a2dChannel = 0;  // analog channel
    int a2dVal = 0;
    float a2dVol = 0;
    float Vref = 3.3;
    unsigned char data[2];

    if (argc == 2) {
        printf("argv[1]=%s\n",argv[1]);
        a2dChannel=atoi(argv[1]);
    }

    if (mcp3002Setup(PINBASE, SPI_CHANNEL) < 0)
    {
        printf("mpc3002Setup failed:\n");
    }

    for(i=0;i<20;i++) {
        a2dVal = analogRead(PINBASE + a2dChannel);
if(DEBUG)printf("wiringPiSPIDataRW=%d\n",a2dVal);
        a2dVol = (float)a2dVal/1023 * Vref;
        printf("a2dVal=%d\n",a2dVal);
        printf("a2dVol=%f[V]\n",a2dVol);
        sleep(1);
    }
}

あれま!!と思うほどすっきりしました。
PINBASEには65以上の任意の数字を指定します。
リンク方法は前回と同じです。
$ cc -o test3 test3.c -lwiringPi

MCP3004や3008も同じ10Bitの分解能なので、mcp3002Setup()をmcp3004Setup()に変更すれば動くと思い ます。
MCP3204や3208の12Bit版はインストラクションも違うので専用のライブラリ関数が必要ですが、
残念ながらMCP3204/3208用のライブラリ関数はWiringPiライブラリに含まれていません。
12Bitで変換する必要がなければ、このやり方が一番スマートです。

次回はic2接続のAD/DAコンバータ(PCF8591)を紹介します。