AndroidThingsでアナログ入力をするには外部のA/Dコンバータを使用する必要があります。今回はSPI接続のMCP3204(以下ADC)を使用してA/D変換したデータを取得してみました。
A/Dコンバータ(MCP3204)と接続
ADCをRaspberry PiのSPI通信に対応するピン(19, 21, 23)と接続します。今回はCS(SS)信号にBCM6を使用し、ADCは0chのみを使用しました。
https://developer.android.com/things/hardware/raspberrypi-io.html
SPI通信の設定
SPIモードはmode0、電源は5Vを使用するのでSPIの通信速度は2MHz、MSBfirstで8bitずつ送信します。
public void configureSpiDevice(SpiDevice device) throws IOException {
device.setMode(SpiDevice.MODE0);
device.setFrequency(2000000); // 2MHz
device.setBitsPerWord(8); // 8 BPW
device.setBitJustification(false); // MSB first
}
AD変換されたデータを取得する
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
byte[] txData = new byte[]{(byte) (0x06 | CHANNEL >> 2), (byte) (CHANNEL << 6), 0x00}; // 送信データ
byte[] rxData = new byte[3]; // 受信データ
// GPIOが閉じている場合はRunnableを終了
if (GPIO_BCM6 == null) {
return;
}
try {
mHandler.postDelayed(mRunnable, 50); // 50ms待つ
GPIO_BCM6.setValue(false); // LOW
mDevice.transfer(txData, rxData, rxData.length); // SPI通信
GPIO_BCM6.setValue(true); // HIGH
float ans = (rxData[1] & 0x0F) * 256 + (rxData[2] & 0xFF); // 10進数に変換
Log.d(TAG, String.valueOf(ans));
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
};
BCM6をLOW→HIGHにする間データを読み込みます。
送信するデータ(制御ビットの詳細)はこちらのサイトを参考にしました。
http://www.geocities.jp/zattouka/GarageHouse/micon/circuit/A_D.htm
rxData[1]に格納されるバイナリデータは下位4bitのみ使用するため0x0FとAND演算し、最下位bitが256を示すので256を乗算します。
rxData[2]に格納される8bitのバイナリデータはすべて使用しますが、byte型が符号付きの8bitで-128~127の範囲しか表現することができないため、0xFFをAND演算して正の値を取り出します。
上記のデータを加算することでAD変換されたデータを取得することができます。