SensorTagで使用されている圧力センサー「T5400」は、object temperatureとthe ambient temperatureの2種類の温度データも取得できます。SensorTagの気圧センサー「T5400」は、最少時間「2ms」で更新されます。

SensorTagの 圧力センサーへのデータアクセス

ハンドルを用いたSensorTagの 圧力センサー「T5400」(U4)への問い合わせは、次のテーブルに従います。

SensorTagの気圧センサー(U4)への問い合わせ
Type UUID Handle Read/Write Format
<Data> F000AA41 * 0×4b Read only TempLSB TempMSB PressLSB PressMSB (4 bytes)
<Data Notification> 0×4c R/W 2 bytes
<Configuration> F000AA42 * 0×4f R/W 1 byte
<Calibration> 0×52 Read only C1LSB C1MSB…C8LSB C8MSB (16 bytes)

圧力センサーデータの気圧への変換式

Tempは温度でPressは圧力を示します。
圧力センサー「T5400」から入力した校正データ(Handle:0x52)を次の式にで設定し、圧力データ(Handle:0x4b)の2バイトのデータから生の圧力データを取り出して、次の計算式により圧力に変換します。Prは生の圧力データで、Trは生の温度データを示します。圧力は符号なしで、Pは、パスカル単位の圧力です。パスカルからバールに変換するには、「10000」で除算します。
圧力センサー変換式
温度は符号を持ち、圧力データ(Handle:0x4b)の2バイトのデータから生の温度データを取り出して、次の計算式により温度に変換します。
温度データへの変換式

圧力センサーデータ変換のプログラム

上記の圧力センサーの変換式をjava言語とC言語でコード化した例を示します。
java言語で記述すると次のようになります。

	/*  Conversion algorithm for barometer temperature
	 *
	 *  Formula from application note, rev_X:
	 *  Ta = ((c1 * Tr) / 2^24) + (c2 / 2^10)
	 *
	 *  c1 - c8: calibration coefficients the can be read from the sensor
	 *  c1 - c4: unsigned 16-bit integers
	 *  c5 - c8: signed 16-bit integers
	 */

	private double calcBarTmp(int rawT)
	{
		long m_raw_temp = rawT;

		long temp, val;
		val = ((long) (c1 * m_raw_temp) * 100);
		temp = (val >> 24);
		val = ((long) c2 * 100);
		temp += (val >> 10);

		return ((double) temp) / 100;
	}

	/* Conversion algorithm for barometer pressure (hPa)
	 *
	 * Formula from application note, rev_X:
	 * Sensitivity = (c3 + ((c4 * Tr) / 2^17) + ((c5 * Tr^2) / 2^34))
	 * Offset = (c6 * 2^14) + ((c7 * Tr) / 2^3) + ((c8 * Tr^2) / 2^19)
	 * Pa = (Sensitivity * Pr + Offset) / 2^14
	 */

	private double TcalcBarPress(int rawT)
	{
		long s, o, pres, val;
		long Pr;
		int Tr;

		Pr = rawT;
		//	  Tr = m_raw_temp;
		Tr = 8;

		// Sensitivity
		s = (long) c3;
		val = (long) c4 * Tr;
		s += (val >> 17);
		val = (long) c5 * Tr * Tr;
		s += (val >> 34);

		// Offset
		o = (long) c6 << 14;
		val = (long) c7 * Tr;
		o += (val >> 3);
		val = (long) c8 * Tr * Tr;
		o += (val >> 19);

		// Pressure (Pa)
		pres = ((long) (s * Pr) + o) >> 14;

		return (double) pres / 100;
	}

	//	 #define BUILD_UINT16(loByte, hiByte) ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))

	private void storeCalibrationData(int[] pData)
	{
		c1 = (pData[0] & 0x00FF) | ((pData[1] & 0x00FF) << 8);
		c2 = (pData[2]) | ((pData[3] & 0x00FF) << 8);
		c3 = (pData[4]) | ((pData[5] & 0x00FF) << 8);
		c4 = (pData[6]) | ((pData[7] & 0x00FF) << 8);
		c5 = (pData[8]) | ((pData[9] & 0x00FF) << 8);
		c6 = (pData[10]) | ((pData[11] & 0x00FF) << 8);
		c7 = (pData[12]) | ((pData[13] & 0x00FF) << 8);
		c8 = (pData[14]) | ((pData[15] & 0x00FF) << 8);
	}

C言語で記述すると次のようになります。

/*  Conversion algorithm for barometer temperature
 *
 *  Formula from application note, rev_X:
 *  Ta = ((c1 * Tr) / 2^24) + (c2 / 2^10)
 *
 *  c1 - c8: calibration coefficients the can be read from the sensor
 *  c1 - c4: unsigned 16-bit integers
 *  c5 - c8: signed 16-bit integers
 */

double calcBarTmp(uint16 rawT)
{
  uint16 c1, c2;

  c1 = m_barCalib.c1;
  c2 = m_barCalib.c2;
  m_raw_temp = rawT;

  int64 temp, val;
  val = ((int64)(c1 * m_raw_temp) * 100);
  temp = (val >> 24);
  val = ((int64)c2 * 100);
  temp += (val >> 10);

  return ((double)temp) / 100;
}

/* Conversion algorithm for barometer pressure (hPa)
 *
 * Formula from application note, rev_X:
 * Sensitivity = (c3 + ((c4 * Tr) / 2^17) + ((c5 * Tr^2) / 2^34))
 * Offset = (c6 * 2^14) + ((c7 * Tr) / 2^3) + ((c8 * Tr^2) / 2^19)
 * Pa = (Sensitivity * Pr + Offset) / 2^14
 */

double TcalcBarPress(uint16 rawT)
{
  int64 s, o, pres, val;
  uint16 c3, c4;
  int16 c5, c6, c7, c8;
  uint16 Pr;
  int16 Tr;

  Pr = rawT;
  Tr = m_raw_temp;
  c3 = m_barCalib.c3;
  c4 = m_barCalib.c4;
  c5 = m_barCalib.c5;
  c6 = m_barCalib.c6;
  c7 = m_barCalib.c7;
  c8 = m_barCalib.c8;

  // Sensitivity
  s = (int64)c3;
  val = (int64)c4 * Tr;
  s += (val >> 17);
  val = (int64)c5 * Tr * Tr;
  s += (val >> 34);

  // Offset
  o = (int64)c6 << 14;
  val = (int64)c7 * Tr;
  o += (val >> 3);
  val = (int64)c8 * Tr * Tr;
  o += (val >> 19);

  // Pressure (Pa)
  pres = ((int64)(s * Pr) + o) >> 14;

  return (double)pres/100;
}

 #define BUILD_UINT16(loByte, hiByte) ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))

void storeCalibrationData(uint8 *pData)
{
  m_barCalib.c1 = BUILD_UINT16(pData[0],pData[1]);
  m_barCalib.c2 = BUILD_UINT16(pData[2],pData[3]);
  m_barCalib.c3 = BUILD_UINT16(pData[4],pData[5]);
  m_barCalib.c4 = BUILD_UINT16(pData[6],pData[7]);
  m_barCalib.c5 = BUILD_UINT16(pData[8],pData[9]);
  m_barCalib.c6 = BUILD_UINT16(pData[10],pData[11]);
  m_barCalib.c7 = BUILD_UINT16(pData[12],pData[13]);
  m_barCalib.c8 = BUILD_UINT16(pData[14],pData[15]);
}