5.3. センサの値を活用する
概要
- 取得したセンサの値を CanSat の制御に活用しよう
- ここでは気圧センサの値を用いて高度を求めてみる
実践
気圧を読む
- 気圧計 のテストコードを参考に,気圧を読んでみよう
#include <CanSatSchool.h>
// 気圧・温湿度計を宣言
BaroThermoHygrometer bth;
void setup()
{
// ロガーを初期化
logger.enableComputer();
// Wire (Arduino-I2C) を初期化
Wire.begin();
// 気圧・温湿度計を初期化
bth.init();
delay(500);
}
void loop()
{
// 気圧を取得する
float pressure = bth.read().pressure;
logger.info("Pressure:", pressure, "[hPa]");
// 1s 待つ
delay(1000);
}
- CanSat を上げ下げしたら,気圧が変わることを確認しよう
気圧から高度を求める
- 気圧から高度を計算しよう
#include <CanSatSchool.h>
// 気圧・温湿度計を宣言
BaroThermoHygrometer bth;
float pressure_at_sea_level = 1013.250; // 海抜 0m での大気圧 [hPa]
void setup()
{
// ロガーを初期化
logger.enableComputer();
// Wire (Arduino-I2C) を初期化
Wire.begin();
// 気圧・温湿度計を初期化
bth.init();
delay(500);
}
void loop()
{
// 気圧を取得する
float pressure = bth.read().pressure;
logger.info("Pressure:", pressure, "[hPa]");
// 気圧の差から海抜高度を計算する
// ざっくり 10m 上昇すると 1hPa 下がるとする
float altitude = (pressure_at_sea_level - pressure) * 10;
logger.info("Altitude:", altitude, "[m]");
// 1s 待つ
delay(1000);
}
- CanSat を上げ下げしたら,気圧とともに高度が変わることを確認しよう
考察
- 気圧計の値にはオフセットがありそう
- 実際の気圧からの定常誤差がある
- 上のプログラムでは
pressure_at_sea_level
(海抜 0m での大気圧)を用いて高度を求めている- ただし,
pressure_at_sea_level
の値は実際には気圧配置などによって変わる - したがって,ここで求めた高度が実際の高度とは一致しない
- ただし,
- 以上から,絶対高度を求めるのは難しい
- CanSatにおいては絶対高度よりも相対高度が重要であるため,キャリブレーションによってオフセットを取り除くとよい
- 地面での高度を基準として,そこからの高度変化を求める
気圧から相対高度を求める
- キャリブレーションを行って,相対高度を求めてみよう
- 高度を求める計算はキャリブレーションと
loop
内とで行うため,計算式を 関数 にして使いまわすと便利
- 高度を求める計算はキャリブレーションと
- キャリブレーションは地面に静置した状態で行う
tutorial_altitude.ino
#include <CanSatSchool.h>
// 気圧・温湿度計を宣言
BaroThermoHygrometer bth;
float altitude_at_ground; // 地表の高度 [m]
// 気圧の差から海抜高度を計算する関数
float calculateAltitudeFromPressure(float pressure)
{
float pressure_at_sea_level = 1013.250; // 海抜 0m での大気圧 [hPa]
float altitude = (pressure_at_sea_level - pressure) * 10; // ざっくり 10m 上昇すると 1hPa 下がるとする
return altitude;
}
void setup()
{
// ロガーを初期化
logger.enableComputer();
// Wire (Arduino-I2C) を初期化
Wire.begin();
// 気圧・温湿度計を初期化
bth.init();
// 安定するまで待つ
logger.info(F("Waiting for stabilization..."));
unsigned long wait_start = millis();
while (millis() - wait_start < 10000)
{
// 気圧を取得する
float pressure = bth.read().pressure;
logger.info(F("Pressure:"), pressure, F("[hPa]"));
delay(1000);
}
// キャリブレーションのためにセンサーを地表に置いておく
logger.info(F("Calibrating pressure sensor..."));
// 地表の気圧を取得する
float pressure_at_ground = bth.read().pressure;
logger.info(F("Pressure at ground:"), pressure_at_ground, F("[hPa]"));
// 地表の海抜高度を計算する
altitude_at_ground = calculateAltitudeFromPressure(pressure_at_ground);
logger.info(F("Altitude at ground:"), altitude_at_ground, F("[m]"));
logger.info(F("Calibration completed"));
delay(500);
}
void loop()
{
// 気圧を取得する
float pressure = bth.read().pressure;
logger.info(F("Pressure:"), pressure, F("[hPa]"));
// 気圧から絶対高度を計算する
float absolute_altitude = calculateAltitudeFromPressure(pressure);
logger.info(F("Absolute altitude:"), absolute_altitude, F("[m]"));
// 地表の海抜高度を引いて相対高度を計算する
float relative_altitude = absolute_altitude - altitude_at_ground;
logger.info(F("Relative altitude:"), relative_altitude, F("[m]\n"));
// 1s 待つ
delay(1000);
}
- 地表からの相対高度が出力されていることを確認しよう