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になったら正しい値が読めています。