気圧センサを使ってみた
RaspberryPi/pigpioでMPL115A1
どもです。
前回は、DHT11をRaspberryPi/pigpioで使用、温度を測定してみました。
今回は、同じ環境(RaspberryPi/pigpio)で大気圧センサーであるPL115A1を使用してみます。
1.開発環境
本エントリの内容の開発環境を、下表に記載します。
PC本体 | OS | Windows10 Pro バージョン:1903 |
---|---|---|
CPU | Intel Core i7-8700 | |
メモリ | 16GB | |
Eclipse | Version | 2019-06 4.12.0 |
Build id | 20190614-1200 | |
RaspberryPi クロスコンパイラ |
raspberry-gcc8.3.0 | |
RaspberryPi | ライブラリ | pigpio バージョン:71 |
2.配線
まず、ブレッドボード上の配線です。
配線図は、下記の通りです。
MPL115A1との通信方法は、SPI通信になります。
なので、RaspberryPiもそのためのピンをしています。
3.使い方
MPL115A1では、大気圧を直接取得できません。
大気圧を取得するためには、必要な係数と値を取得して計算します。
ここでは、係数と値の取得方法について書いていきます。
3.1.MPL115A1との通信
MPL115A1からの値は、SPI通信で取得します。
このとき、通信方法としては「半二重」になります。
一応コードを示しておきます。
void SendAndRecvCommand(
const unsigned int spiHandle,
const uint8_t command,
uint8_t* readData)
{
spiWrite(spiHandle, (char*)(&command), 1);
spiRead(spiHandle, (char*)(readData), 1);
}
上記spiWrite()で送信しているcommandの値はメンドクサイここで書くと量が多くなってしまうので、MPL115A1のデータシートを参照して下さい。
3.2.係数の取得
大気圧を取得するために必要な係数は、a0、b1、b2、およびc12の3つがあります。
データシートによれば、各係数のフォーマットは、
a0→S12.3
b1→S2.13
b2→S1.14
となっています。
全て16bitの値です。
c12ついては、少し異なっています。
即ち、取得データのうち13bitがデータになり、その値は小数点第10位以下の値になります。
また13bitの範囲は、16bitの内の下記の範囲になります。
データシートに明記はされていませんが、最上位MSBの最上位ビットを符号ビットとしています。
係数の取得と変換のコードは、下記の通りです。
/**
* Convert buffer data, data type is uint8_t, into float.
*
* @param[in] buffer Pointer to buffer conataining the uint8_t data.
* @param msbIndex Index of buffer of MSB byte.
* @param lsbIndex Index of buffer of LSB byte.
* @param floatLsb LSB of float value.
* @param mask Bit array to mask buffer. Default value is 0xFFFF.
*/
float Buff2Float(
uint8_t* buffer,
int msbIndex, int lsbIndex,
float floatLsb,
uint16_t mask = 0xFFFF)
{
float converted = 0.0;
uint16_t rawData = ((uint16_t)(buffer[msbIndex] << 8) + (uint16_t)(buffer[lsbIndex]));
rawData &= mask;
converted = (float)((int16_t)rawData * floatLsb);
return converted;
}
/**
* Read coefficient value..
*
* @param spiHandle SPI handle.
*/
void ReadCoefficient(const unsigned int spiHandle) {
StartSequence();
for (int buffIndex = 0; buffIndex < MPL115A1_DATA_INDEX_COEFF_MAX; buffIndex++) {
SendAndRecvCommand(spiHandle, READ_COEFF_SEQ_COMMAND[buffIndex], &coefficientBuff[buffIndex]);
}
SendExtraCommand(spiHandle);
StopSequence();
//Setup coefficient from receive data.
MPL_115A1_a0 = Buff2Float(
coefficientBuff,
MPL115A1_DATA_INDEX_COEFF_A0_MSB, MPL115A1_DATA_INDEX_COEFF_A0_LSB,
MPL115A1_COEFF_A0_LSB);
MPL_115A1_b1 = Buff2Float(
coefficientBuff,
MPL115A1_DATA_INDEX_COEFF_B1_MSB, MPL115A1_DATA_INDEX_COEFF_B1_LSB,
MPL115A1_COEFF_B1_LSB);
MPL_115A1_b2 = Buff2Float(
coefficientBuff,
MPL115A1_DATA_INDEX_COEFF_B2_MSB, MPL115A1_DATA_INDEX_COEFF_B2_LSB,
MPL115A1_COEFF_B2_LSB);
uint16_t rawData_c12 =
((uint16_t)(coefficientBuff[MPL115A1_DATA_INDEX_COEFF_C12_MSB] << 8) + (uint16_t)(coefficientBuff[MPL115A1_DATA_INDEX_COEFF_C12_LSB])); rawData_c12 >>= 2;
rawData_c12 &= 0x3FFF;
MPL_115A1_c12 = (float)((int16_t)rawData_c12 * MPL115A1_COEFF_C12_LSB);
}
3.3.値の取得
大気圧を算出するために参照する値は、大気圧の値と温度の値になっています。
それぞれの値のサイズは、10bitです。
受信した2バイトのデータのうち、上位10bitの値を使用します。
実際に値を取得、抜き出す実装は下記になります。
/**
* Read pressure and temperature value.
*/
void ReadTempAndPress(const unsigned int spiHandle) {
StartSequence();
for (int buffIndex = 0; buffIndex < MPL115A1_DATA_INDEX_MAX; buffIndex++) {
SendAndRecvCommand(spiHandle,
READ_PRESS_TEMP_SEQ_COMMAND[buffIndex],
(uint8_t*)(&dataBuff[buffIndex]));
}
SendExtraCommand(spiHandle);
StopSequence();
//Get Padc and Tadc value by buffer.
{
uint16_t rawData_padc =
(((uint16_t)dataBuff[MPL115A1_DATA_INDEX_PRESS_MSB]) << 8) + dataBuff[MPL115A1_DATA_INDEX_PRESS_LSB]; rawData_padc >>= 6;
MPL_115A1_padc = (float)((int16_t)rawData_padc);
}
{
uint16_t rawData_tadc =
(((uint16_t)dataBuff[MPL115A1_DATA_INDEX_TEMP_MSB]) << 8) + dataBuff[MPL115A1_DATA_INDEX_TEMP_LSB]; rawData_tadc >>= 6;
MPL_115A1_tadc = (float)((int16_t)rawData_tadc);
}
}
3.4.大気圧の計算
これまで取得した値を使用して、大気圧を算出します。
算出は、下記の順番で実施します。
- 圧力補正を算出
- 大気圧を算出
それぞれの値は、下記の計算式で算出します。
この計算の実装は、下記になります。
/**
* Get pressure by reading data from the sensor.
*
* @return Pressure specified by kPa.
*/
float GetPress() {
float MPL_115A1_press_comp =
MPL_115A1_a0 +
(MPL_115A1_b1 + MPL_115A1_c12 * MPL_115A1_tadc) * MPL_115A1_padc +
MPL_115A1_b2 * MPL_115A1_tadc;
MPL_115A1_press = (MPL_115A1_press_comp * ((115.0 - 50.0) / 1023.0)) + 50.0;
return MPL_115A1_press;
}
この関数の戻り値が、kPa単位の大気圧になります。
4.まとめ
今回は、MPL115A1からRaspberryPiで大気圧を取得する方法について記載しました。
このセンサー、データシートには明記されていませんが、実は気温も取得できるようです。
今回のエントリでは省略していますが、分かったら教えてください。
ではっ!
ex.公開しています
今回のエントリで作成したコードや資料は、GitHubで公開しています。
本エントリに記載したコードは、必要な個所のみとなっています。
全てのコードは、上記リンクから参照してください。
ディスカッション
コメント一覧
まだ、コメントがありません