mraaライブラリーでAD変換
2014年12月28日 - 未分類
edisonのmraaライブラリーを使って、MCP3425というADCを使えるようにしましたので、記事を書きます。
MCP3425は、12bit/14bit/16bit切り替えで使えるAD変換ICです。I2Cで接続します。
#include "mraa.h" /* Edison GPIO用ライブラリ */
#define ADRES_MCP3425 0x68 /* ADC MCP3425 16bit ADC I2C */
mraa_i2c_context i2c; /* I2C通信用変数宣言 */
void adc_init(){
uint8_t comand_data[2]={0x00,0x00}; /* 送信用バッファ */
mraa_init(); /* mraaライブラリ初期化 */
i2c = mraa_i2c_init(1); /* I2C通信初期化 */
/*
bit 7 RDY: Ready Bit
bit 6-5 C1-C0 Channel Selection Bits 00
bit 4 O/C Conversion Mode Bit 1 Continuous Conversion Mode
bit 3-2 10 15SPS(16bit)
bit 3-2 01 SPS(14bit)
bit 3-2 00 SPS(12bit)
bit 1-0 Gain 00=1V/V
*/
mraa_i2c_address(i2c, ADRES_MCP3425); /* I2Cアドレス設定 */
comand_data[0]=0x00; // Register
// One Shot か 連続取り込みかを選択する
// comand_data[1]=0x10;// Continuous Conversion Mode
comand_data[1]=0x80;// One Shot Conversion Mode
mraa_i2c_write_byte(i2c, comand_data[1]); /* COMMAND */
}
int adc_read()
{
uint8_t comand_data[2]={0x00,0x00}; /* 送信用バッファ */
uint8_t val[3]={0x00,0x00,0x00};
char RDY=1;
// One Shot ならここで読み込みを開始する。 連続モードなら不要。
comand_data[0]=0x00; // Register
comand_data[1]=0x80;// One Shot Conversion Mode
mraa_i2c_write_byte(i2c, comand_data[1]); /* COMMAND */
//
while(RDY){
mraa_i2c_read(i2c, val, 3); /* I2C data read*/
RDY = (val[2] & 0x80) >> 7; // Data Ready then LOW
}
val[0] = val[0] & 0x0F; // mask n bits
return ((int)val[0]*0xFF+val[1]);
}
分かってしまえば簡単なここですが、分からないと非常に難しいですね。
まず、
#define ADRES_MCP3425 0x68 /* ADC MCP3425 16bit ADC I2C */
のところですが、MCP3425 は、0x68 というI2Cバスでの固有アドレスをもっています。このアドレスが衝突するものは、同じI2Cバスでは使えません。
初期化の部分では、
i2c = mraa_i2c_init(1); /* I2C通信初期化 */
では、I2C1を初期化します。
i2c = mraa_i2c_init(0); /* I2C通信初期化 */
では、I2C6が初期化されます。何故、こんなややっこしい仕様にしたのでしょうかね。
mraa_i2c_write_byte(i2c, comand_data[1]); /* COMMAND */
のところでは、MCP3425のレジスタに、設定値を書き込んでいます。レジスタのアドレスは、0x00です。レジスタのアドレスは、mraa_i2c_write_byteが自動的に選んでいるようです。
ちなみに、
mraa_i2c_write_byte_data(i2c, comand_data, 2); /* COMMAND */
としても同じことになります。
レジスタに書き込む値で、One Shotか連続取り込みか、12bit/14bit/16bitのADかを設定できます。設定後は、 mraa_i2c_read(i2c, val, 3); で読み込むのですが、AD変換が終わってるかどうかを調べなければなりません。終わっていないのに値を読み込むと、同じ値ばかり読み込むことになります。
while(RDY){
mraa_i2c_read(i2c, val, 3); /* I2C data read*/
RDY = (val[2] & 0x80) >> 7; // Data Ready then LOW
}
3バイト目に、Configバイトがあり、そこの7bit目を見て、RDYが0になったら正しい値が読めています。