mraaライブラリーでAD変換
2014年12月28日 - 未分類
edisonのmraaライブラリーを使って、MCP3425というADCを使えるようにしましたので、記事を書きます。
MCP3425は、12bit/14bit/16bit切り替えで使えるAD変換ICです。I2Cで接続します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # 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]); } |
分かってしまえば簡単なここですが、分からないと非常に難しいですね。
まず、
1 | #define ADRES_MCP3425 0x68 /* ADC MCP3425 16bit ADC I2C */ |
のところですが、MCP3425 は、0x68 というI2Cバスでの固有アドレスをもっています。このアドレスが衝突するものは、同じI2Cバスでは使えません。
初期化の部分では、
1 | i2c = mraa_i2c_init(1); /* I2C通信初期化 */ |
では、I2C1を初期化します。
1 | i2c = mraa_i2c_init(0); /* I2C通信初期化 */ |
では、I2C6が初期化されます。何故、こんなややっこしい仕様にしたのでしょうかね。
1 | mraa_i2c_write_byte(i2c, comand_data[1]); /* COMMAND */ |
のところでは、MCP3425のレジスタに、設定値を書き込んでいます。レジスタのアドレスは、0x00です。レジスタのアドレスは、mraa_i2c_write_byteが自動的に選んでいるようです。
ちなみに、
1 | mraa_i2c_write_byte_data(i2c, comand_data, 2); /* COMMAND */ |
としても同じことになります。
レジスタに書き込む値で、One Shotか連続取り込みか、12bit/14bit/16bitのADかを設定できます。設定後は、 mraa_i2c_read(i2c, val, 3); で読み込むのですが、AD変換が終わってるかどうかを調べなければなりません。終わっていないのに値を読み込むと、同じ値ばかり読み込むことになります。
1 2 3 4 | 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になったら正しい値が読めています。