概要
気圧センサー(大気圧センサー、バロメトリックセンサー)は、大気の圧力(気圧)を電気信号に変換するセンサーです。単位はPa(パスカル)またはhPa(ヘクトパスカル)で表し、海面での標準大気圧は1013.25hPaです。
気圧センサーの主な用途は、高度推定と天候予測です。大気圧は高度とほぼ対数的な関係があり、気圧から高度を逆算できます(例:100mの高度差で約12hPaの変化)。これによりGNSSが届かない屋内でも垂直方向の位置推定が可能です。また短時間の気圧変化傾向から天候の悪化・改善を予測できます。
現代の小型MEMS気圧センサーは温度センサー・湿度センサーと統合されていることが多く、Bosch BME280(温度・湿度・気圧)が最も広く使われます。I2CまたはSPIでマイコンと接続し、温度補償済みの高精度な気圧データをデジタル出力します。
歴史・背景
気圧計の発明は1643年にエヴァンジェリスタ・トリチェリによる水銀気圧計に遡ります。真空の管の中の水銀柱の高さが気圧に応じて変化する原理で、「水銀柱ミリメートル(mmHg)」という単位はここに由来します。
1648年にはブレーズ・パスカルが、山の上と麓で気圧計の値が異なることを確認し、高度と気圧の関係を実証しました(これが気圧を高度計に使う原理です)。パスカルの業績を称え、圧力の国際単位はPa(パスカル)と名付けられています。
電子的な気圧センサーは20世紀に入って実用化されました。航空機の高度計・気象観測機器への需要から発展し、1980〜90年代にはMEMS技術による小型化が進みました。
2000年代にはスマートフォンへの搭載が始まり(例:Samsungのフラッグシップモデルや一部のiPhone)、屋内測位・フロア推定への応用が注目されました。現在では登山用GPSウォッチ、ドローン、スマートウォッチへの搭載が一般的です。
技術仕様
代表的な気圧センサーの比較
| センサー | 気圧精度 | 高度分解能 | 気圧範囲 | I/F | 備考 |
|---|---|---|---|---|---|
| BMP180 | ±1hPa | 1m | 300〜1100hPa | I2C | 旧世代・廉価 |
| BMP280 | ±1hPa | 0.16m | 300〜1100hPa | I2C/SPI | BME280の気温気圧版 |
| BME280 | ±1hPa | 0.16m | 300〜1100hPa | I2C/SPI | 温湿度気圧統合 |
| BMP388 | ±0.5hPa | 0.08m | 300〜1250hPa | I2C/SPI | 高精度 |
| BMP390 | ±0.25hPa | 0.05m | 300〜1250hPa | I2C/SPI | 最新高精度 |
| LPS22HH | ±0.5hPa | 0.08m | 260〜1260hPa | I2C/SPI | ST製・高速ODR |
| DPS310 | ±0.06hPa | 0.01m | 300〜1200hPa | I2C/SPI | Infineon製・超高精度 |
高度と気圧の関係
気圧と高度の関係は「国際標準大気(ISA)」に基づき計算されます。
気圧高度計算式(国際標準大気モデル):
0〜11km(対流圏):
P = P₀ × (1 - Lh/T₀)^(gM/RL)
P: 高度h[m]での気圧 [hPa]
P₀: 基準気圧(海面標準気圧 = 1013.25hPa)
T₀: 基準気温(288.15K = 15°C)
L: 気温減率(0.0065K/m)
g: 重力加速度(9.80665m/s²)
M: 乾燥空気の分子量(0.0289644kg/mol)
R: 気体定数(8.31432J/(mol·K))
簡略式(低高度近似):
h ≈ (P₀ - P) / 0.12 [m] (約0.12hPa/m)
または高精度近似式(Hypsometric formula):
h = T₀/L × (1 - (P/P₀)^(RL/gM))
高度の絶対精度と相対精度
| 精度種別 | 説明 | 代表値 |
|---|---|---|
| 絶対高度精度 | 海面からの実際の高度との誤差 | ±数十m(気象変化による) |
| 相対高度精度 | 短時間の高度変化量の精度 | ±数十cm〜1m |
| 高度分解能 | 検出できる最小高度変化 | 数cm〜10cm |
気圧は天候(低気圧・高気圧)によって日々変化するため、絶対高度の精度はGNSSに劣ります。しかし変化量(昇降)の精度は高く、ドローンの定高飛行などに活用されます。
動作原理
MEMSピエゾ抵抗型気圧センサー
最も一般的なMEMS気圧センサーは、薄いシリコンダイアフラム(薄膜)の変形を圧抵抗効果で検出します。
動作原理:
① ダイアフラムの一方(基準空洞)は真空シール、
もう一方は外気に開放
② 外気圧が変化するとダイアフラムがたわむ
③ ダイアフラム上のシリコン圧抵抗素子の
抵抗値が変化(ピエゾ抵抗効果)
④ ホイートストンブリッジ回路で抵抗変化を検出
⑤ ADCとデジタル信号処理で気圧値に変換
圧力-抵抗変換:
ΔR/R = π_l × σ_l + π_t × σ_t
(π: 圧抵抗係数, σ: 応力)
温度補償の重要性
シリコンの特性は温度依存性があるため、気圧測定値は温度により変動します。高精度な気圧センサーは内蔵温度センサーで温度を計測し、ファクトリーキャリブレーション係数を使って補正します。
// BME280の気圧補正計算(Bosch公式アルゴリズム)
int32_t BME280_compensate_pressure(int32_t adc_P, int32_t t_fine,
BME280_Calib *calib) {
int64_t var1, var2, p;
var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)calib->dig_P6;
var2 = var2 + ((var1 * (int64_t)calib->dig_P5) << 17);
var2 = var2 + (((int64_t)calib->dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)calib->dig_P3) >> 8) +
((var1 * (int64_t)calib->dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) *
((int64_t)calib->dig_P1) >> 33;
if (var1 == 0) return 0; // ゼロ除算防止
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)calib->dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)calib->dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)calib->dig_P7) << 4);
return (int32_t)p; // 単位: Pa × 256 (Q24.8形式)
}
IIRフィルタによるノイズ低減
BME280等にはハードウェアIIRフィルタが内蔵されており、短期的な気圧変動(ドア開閉・エアコン等)を平滑化できます。
IIRフィルタ(係数k = 0〜16):
data_filtered = (data_filtered × (k-1) + data_raw) / k
k=0: フィルタOFF
k=2: 短期変動を50%低減
k=16: 最大平滑化(風などの瞬間変動を除去)
出力データレート(ODR)とIIRフィルタ:
IIRなし (k=0): スポット気象計測・高度急変検知
IIR高め(k≥8): ドローン定高制御・フロア検出・気象モニタリング
用途・ユースケース
ドローン・UAV の高度制御
GNSSの垂直精度は水平精度より低く(誤差数m)、更新レートも低いため、ドローンの低高度定高飛行には気圧センサーが不可欠です。1〜50Hzで高度変化を取得し、スロットル制御にフィードバックします。
ドローン高度制御ループ:
BMP390(50Hz) → 高度推定 → PIDコントローラー → スロットル補正
登山・アウトドア機器
GPS腕時計・高度計(アルチメーター)での高度推定。QNH(航空用設定気圧)を入力することで、海面気圧補正した正確な絶対高度を表示します。
屋内測位・フロア検出
スマートフォンの気圧センサーを使い、エレベーターの昇降(フロア変化)を検知します。GPS+気圧センサーのセンサーフュージョンで3D測位精度を向上させる研究も行われています。
気象ステーション・IoT環境センサー
Raspberry PiやESP32にBME280を接続し、気温・湿度・気圧を記録するホームウェザーステーションを構築できます。短期の気圧低下は天候悪化の予兆として天気予測に利用されます。
医療・呼吸器
人工呼吸器の流量制御や肺機能検査(スパイロメトリー)に差圧センサーが使われます。流量は差圧と管断面積から計算します(ベルヌーイの定理)。
産業用差圧計測
気圧センサーの派生として、2点間の圧力差を測る差圧センサーがあります。空調ダクトの風量計測、フィルターの目詰まり検知、液体タンクの液面計(液体柱の重量=圧力差から水位換算)などに使われます。
実装・開発のポイント
BMP280 の I2C 読み取り(C言語)
#include <stdint.h>
#include "i2c_hal.h"
#define BMP280_ADDR 0x76
#define BMP280_REG_ID 0xD0
#define BMP280_REG_CTRL 0xF4
#define BMP280_REG_DATA 0xF7
#define BMP280_REG_CALIB 0x88
typedef struct {
uint16_t T1; int16_t T2, T3;
uint16_t P1; int16_t P2, P3, P4, P5, P6, P7, P8, P9;
} BMP280_Calib;
BMP280_Calib calib;
void bmp280_init(void) {
// 動作モード: ノーマルモード, osrs_t=x2, osrs_p=x16
uint8_t ctrl = 0xB7; // 101_101_11: osrs_t=x2, osrs_p=x16, mode=normal
i2c_write_reg(BMP280_ADDR, BMP280_REG_CTRL, &ctrl, 1);
// キャリブレーションデータ読み取り
uint8_t raw[24];
i2c_read_reg(BMP280_ADDR, BMP280_REG_CALIB, raw, 24);
calib.T1 = (uint16_t)(raw[1]<<8 | raw[0]);
calib.T2 = (int16_t) (raw[3]<<8 | raw[2]);
calib.T3 = (int16_t) (raw[5]<<8 | raw[4]);
calib.P1 = (uint16_t)(raw[7]<<8 | raw[6]);
// ... P2〜P9 も同様
}
float bmp280_read_pressure_pa(void) {
uint8_t buf[6];
i2c_read_reg(BMP280_ADDR, BMP280_REG_DATA, buf, 6);
int32_t adc_P = ((int32_t)buf[0] << 12) | ((int32_t)buf[1] << 4) | (buf[2] >> 4);
int32_t adc_T = ((int32_t)buf[3] << 12) | ((int32_t)buf[4] << 4) | (buf[5] >> 4);
// 温度補正(t_fineの計算、省略)
int32_t t_fine = bmp280_calc_tfine(adc_T);
// 気圧補正(Bosch公式アルゴリズム)
int64_t var1 = (int64_t)t_fine - 128000;
// ... (前述のBME280補正と同様)
return 0; // 実際の実装では補正値を返す
}
// 気圧から高度への変換
float pressure_to_altitude(float pressure_hpa, float sea_level_hpa) {
return 44330.0f * (1.0f - powf(pressure_hpa / sea_level_hpa, 0.1903f));
}
相対高度計測と自動QNH補正
気圧センサーで絶対高度を計測するには、現地の海面更正気圧(QNH)が必要です。起動時の気圧を基準にして相対高度を求める方法が組み込みでは実用的です。
class AltimeterRelative:
"""相対高度計(起動時を基準ゼロとする)"""
def __init__(self, sensor):
self.sensor = sensor
# 起動時の気圧を基準に保存(複数回平均で安定化)
self.base_pressure = self._average_pressure(20)
print(f"基準気圧: {self.base_pressure:.2f} hPa")
def _average_pressure(self, n):
import time
total = 0
for _ in range(n):
total += self.sensor.read_pressure()
time.sleep(0.05)
return total / n
def get_altitude_m(self):
"""現在の相対高度を計算 [m]"""
p = self.sensor.read_pressure()
# 約8.5m/hPa の近似(低高度・標準大気)
return (self.base_pressure - p) * 8.5
高度ノイズのフィルタリング
気圧センサーはドア開閉・エアコン風・手で触れる振動など多くの外乱を受けます。
from collections import deque
class PressureFilter:
"""移動平均 + メディアンフィルタの組み合わせ"""
def __init__(self, window=16):
self.buf = deque(maxlen=window)
def update(self, raw_pressure):
self.buf.append(raw_pressure)
# メディアンでスパイク除去、平均でスムース化
sorted_buf = sorted(self.buf)
n = len(sorted_buf)
median = sorted_buf[n // 2]
# メディアンから遠い値を除外して平均
trimmed = [x for x in sorted_buf if abs(x - median) < 0.5]
return sum(trimmed) / len(trimmed) if trimmed else median
他技術との比較
高度推定手法の比較
| 手法 | 精度(絶対) | 精度(相対) | 屋内対応 | 更新レート | 電力 |
|---|---|---|---|---|---|
| GNSS(GPS等) | ±3〜10m | ±数m | 不可 | 1〜10Hz | 高(20〜50mA) |
| 気圧センサー | ±数十m(天候依存) | ±数十cm | 可能 | 数十Hz | 低(<0.1mA) |
| 気圧+GNSS融合 | ±1〜3m | ±数十cm | GNSSがある場所 | 10〜50Hz | 中 |
| 超音波(ToF) | ±cm | ±cm | 可能(反射面必要) | 10〜50Hz | 低〜中 |
| 慣性航法(IMU積分) | 数分後に数m誤差 | 短期は良好 | 可能 | 〜1kHz | 低 |
気圧センサーの方式比較
| 方式 | 原理 | 特徴 | 用途 |
|---|---|---|---|
| ピエゾ抵抗式 | 薄膜変形→抵抗変化 | 安価・MEMS量産向き | コンシューマー・IoT |
| 容量式 | 薄膜変形→容量変化 | 高感度・低消費電力 | 高精度気圧計 |
| 圧電式 | 力→電荷発生 | 動的圧力変化に高速応答 | 衝撃・振動計測 |
| 光学式 | 光干渉 | 超高精度・電磁気干渉なし | 研究・精密計測 |
| 共振式 | 共振周波数変化 | 高精度・高安定 | 精密気象・航空機器 |