Tutorial
5.3. センサの値を活用する

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);
}

GitHub (opens in a new tab)

  • 地表からの相対高度が出力されていることを確認しよう