できること

第45回「ラズベリーパイ専用アドオンボード Sense HATで遊ぼう!(2)6種類のセンサ編」

raspberrypi45_main

Sense HATで遊ぼう! 2回目は、センサでの値取得!
今回も公式サイトのチュートリアルに沿って進めていきます。前回の続き、4章からのスタートです!

Sense HAT – Raspberry Pi
The Sense HAT has an 8×8 RGB LED matrix, a five-button joystick and includes the following sensors:

  • Gyroscope
  • Accelerometer
  • Magnetometer
  • Temperature
  • Barometric pressure
  • Humidity

公式サイトにもあるとおり、Sense HATには6種類ものセンサが標準搭載されています。今回はこれらのセンサの値取得に挑戦しましょう!

 

気圧・気温・湿度の取得

raspberrypi45_img01

図1

まずは、気圧・気温・湿度センサからスタート!センサは、Sense HATの右側にあります。「HUMIDITY」と書かれているものが湿度センサ、その下の「PRESSURE」が気圧センサです。温度は、湿度センサから読み出すようですね。

それぞれ専用の関数が用意されているので、とても簡単に取得できてしまいます!

get_temperature
Gets the current pressure in Millibars from the pressure sensor.
get_temperature_from_humidity
Gets the current temperature in degrees Celsius from the humidity sensor.

get_pressure
Gets the current pressure in Millibars from the pressure sensor.

get_humidity
Gets the percentage of relative humidity from the humidity sensor.

それではサンプルソースを使って、実際に値を取得してみましょう!

env.py

from sense_hat import SenseHat
sense = SenseHat()

while True:
    t = sense.get_temperature()
    p = sense.get_pressure()
    h = sense.get_humidity()

    t = round(t, 1)
    p = round(p, 1)
    h = round(h, 1)

    msg = "Temperature = %s, Pressure=%s, Humidity=%s" % (t,p,h)

    sense.show_message(msg, scroll_speed=0.05)

コマンドラインから動かしても問題はありませんが、実行中に強制終了させてしまうと、LEDディスプレイが点灯したままになってしまうことがあります(自動的に消灯せず、終了した瞬間の状態が維持されます)。無限ループにならないようなプログラムを書くようにするか、IDLEから動かすことをおすすめします。

実行結果がこちら!
「Temperature = 33.4, Pressure=1010.8, Humidity=33.8」という文字列が流れています。温度33.4℃、気圧1010.8hPa、湿度33.8%という結果となりました。
ラズベリーパイの熱で温度が30度を越えてしまっています……実際の気温とはかなり差が出てしまうものの、本体温度の目安として、熱暴走対策にも活用できそうですね(温度センサのセンサ数値の誤差についてはまとめで対策方法を追記しています)。

scrolling_env.py

from sense_hat import SenseHat
sense = SenseHat()

while True:
    t = sense.get_temperature()
    p = sense.get_pressure()
    h = sense.get_humidity()

    t = round(t, 1)
    p = round(p, 1)
    h = round(h, 1)

    if t > 18.3 and t < 26.7:
        bg = [0, 100, 0]  # green
    else:
        bg = [100, 0, 0]  # red

    msg = "Temperature = %s, Pressure=%s, Humidity=%s" % (t, p, h)

    sense.show_message(msg, scroll_speed=0.05, back_colour=bg)

こちらは応用編。国際宇宙ステーションで温度の異常があると警告してくれるプログラムです。問題ない場合(18.3~26.7℃) は緑色、異常の場合は赤色の背景色になるプログラムです。動画では、温度センサが34.2度という値を感知しているので、赤い背景になっています。

 

ジャイロスコープ・加速度センサ・磁気センサ

raspberrypi45_img02

図2

図2が、Sense HATの「慣性測定ユニット(IMU:加速度、ジャイロ、磁力)」と呼ばれるものです。ジャイロスコープ・加速度センサ・磁気センサの3つが、この1つのパーツに集約されています。

どれもはじめて取り扱うセンサなので、まずは意味を調べておきましょう。

ジャイロスコープ – Wikipedia
ジャイロスコープ(英語: gyroscope)とは、物体の角度(姿勢)や角速度あるいは角加速度を検出する計測器ないし装置。

加速度計 – Wikipedia
加速度計(かそくどけい)は、物体の加速度を計測する機器である。小型の加速度計(加速度センサ)はMEMS技術を用いて作製される。MEMSの加速度センサの場合、質量が小さいため感度は低下するが劇的な小型化が可能になるため、自動車のエアバッグやカーナビゲーションの傾斜計、ゲームのコントローラなどに使われている。

加速度 – Wikipedia
加速度(かそくど、英: acceleration)は、単位時間当たりの速度の変化率。速度がベクトルなので、加速度も同様にベクトルとなる。

磁気センサ – Wikipedia
磁気センサ(じきセンサ)は、磁場(磁界)の大きさ・方向を計測することを目的としたセンサ。

聞き慣れない、似たような単語ばかりで、すでに混乱しています……むずかしいです!
角速度、角加速度、加速度。名前が似ていてさらに覚えにくいのですが、角速度は回転の速さ、角加速度は回転速度の変化率、加速度は速度の変化率のことだそうです。磁場については、一番身近なところで言うと、方位磁針の示すS極・N極でしょうか。

どう使うものなのか、全然見当がつきませんが、とりあえずサンプルコードを実行してみましょう!

まずはジャイロスコープを使って、ラズベリーパイの向きを取得してみます。このセンサを扱うには、「Pitch」「Roll」「Yaw」という3つの用語を理解しておく必要があります。

こちらの動画がとても参考になりました!
飛行機の動きに置き換えると、「Pitch」は離陸するときの動き、「Roll」は機体を傾けるような動き、「Yaw」は水平方向に向きを変えるような動きとなります。

raspberrypi45_img03

図3

Sense HATと照らし合わせると、図3のようになります。

get_orientation
Calls get_orientation_degrees above.
get_orientation_degrees
Gets the current orientation in degrees using the aircraft principal axes of pitch, roll and yaw.

get_orientation関数は、水平に置いた状態を基準に、ラズベリーパイ(Sense HAT)がどれくらい傾いているかを数値で取得します。
値は、Pythonのディクショナリ(辞書型)で返されます。他の言語で言うと、連想配列に似た形です。

pitch, roll, yaw = sense.get_orientation().values()
print("pitch=%s, roll=%s, yaw=%s" % (pitch,yaw,roll))

公式サイトでは、上記のように、3つの変数それぞれに値を代入する方法が紹介されています。代入先を複数指定する方法は、なんだか書き慣れません……。

orientation = sense.get_orientation()
print("p: {pitch}, r: {roll}, y: {yaw}".format(**orientation))

一方、こちらはAPI Reference版。ディクショナリのまま保持しておいて、出力時に個別に指定する方法です。こちらも、少し独特ですね。

orientation = sense.get_orientation()
print("p: %s, r: %s, y: %s" % (orientation["pitch"],orientation["roll"],orientation["yaw"]))

長くなってしまいますが、Python初心者でも分かりやすいのはこちらの書き方でしょうか。

orientation2.py

from sense_hat import SenseHat
import time

sense = SenseHat()

while True:
    orientation = sense.get_orientation()
    p=round(orientation["pitch"], 0)
    r=round(orientation["roll"], 0)
    y=round(orientation["yaw"], 0)
    print("p: %s, r: %s, y: %s" % (p,r,y))
    time.sleep(1)

Pitch、Roll、Yawの値を1秒間隔で出力しながら、ラズベリーパイをいろいろな方向に傾けてみました。値が変化しているのが分かるでしょうか?ラズベリーパイを横方向から裏返すように回転させるとPitchの値が、縦方向に裏返すように回すとRollの値が、水平のまま回転させるとYawが変化していきます。
動かさずに置いていても、ちょっとずつ値が変わってしまったので、もしかすると周囲の何かの影響を受けてしまっているのかもしれません……。

get_accelerometer_raw
Gets the raw x, y and z axis accelerometer data.

acceleration.py

from sense_hat import SenseHat

sense = SenseHat()

while True:
    acceleration = sense.get_accelerometer_raw()
    x = acceleration['x']
    y = acceleration['y']
    z = acceleration['z']

    x=round(x, 0)
    y=round(y, 0)
    z=round(z, 0)

    print("x=%s, y=%s, z=%s" % (x, y, z))

向きを取得する方法がもう1つ紹介されています。こちらは加速度センサを使った取得方法のようです。先程と同様に、ラズベリーパイを傾けることで値の変化が見られました。

ジャイロスコープで向きが取得できるのはなんとなく分かりますが、加速度センサで取得できるのはなぜ?という疑問があったのですが、下記のページが参考になりました。

いまさら聞けない「加速度センサ」とは
加速度センサは重力による地面方向への加速度も検出しており、加速度センサから取得できる加速度は常に、ユーザーによってデバイスに掛けられている加速度と重力加速度の合力です。
加速度センサによって検出された加速度は、下図のようなデバイスを中心とした3次元空間の、それぞれの空間軸の成分として取得できます。
accelerometer

身近なデバイスに置き換えるとイメージしやすいですね!

ちなみに加速度センサについては、はじめての電子工作超入門「第17回 Arduinoでパーツやセンサを使ってみよう~加速度センサ編(その1)」で詳しく解説されています。

ラズベリーパイ公式サイトのチュートリアルには掲載されていませんが、磁気センサでのデータ取得も試してみました。

get_compass
Calls set_imu_config to disable the gyroscope and accelerometer then gets the direction of North from the magnetometer in degrees.

raspberrypi45_img05

図5

図5は、一秒間隔で値を取得してみたところです。値は取得できたのですが、一体これは何の数字なのでしょう(笑)。置いたままでも向きを変えてみても、数値にはあまり変化が見られず。もしかすると、なにか干渉してしまうものが近くにあるのかもしれませんね……(成功した方はぜひご一報を!)。

地磁気センサについての詳しい解説はこちらのページに。ハイレベルです!

 

ケースをつくりました!

Astro Pi: 3D-Print Your Own Flight Case – Raspberry Pi
こちらの記事で紹介されているAstro Pi用のケースを、3Dプリンターで出力してみました!

3d-printed-astro-pi-flight-case/STL at master · raspberrypilearning/3d-printed-astro-pi-flight-case · GitHub
バージョンに合わせて新しいものがどんどん公開されていますが、SECTION_1~4までの4種類を出力しましょう。

3D Printed Astro Pi Flight Case | Raspberry Pi Learning Resources
作り方の詳細ページはこちらです。別途必要な部品や接続方法、組み立て方も詳しく解説されています。サポート剤のはがし方まで掲載されていてとても親切!

raspberrypi45_img06

図6

わたしが出力したケースがこちら。まずはSECTION_2とSECTION_3を出力して、本体を入れてみました。専用のネジを使わないときっちり収まらないようで、少し浮いてしまいました……。
出力してみて、なんだか随分と大きいなと思ったのですが、本体とSense HATだけでなく、ボタンを組み込むスペースも確保されているようでした。なんとカメラも入ります!

raspberrypi45_img07

図7

続いて、SECTION_1とSECTION_4も出力して、重ねてみたところです。分かりやすいように、ヒートシンクとフタは色を変えて出力してみました。個々の歪みの影響が出てきてしまい、組み立てられるところまでは到達できませんでした……。

手順どおりに作ると、図8のように仕上がります。この見本のように完成させたい方は、歪みの少ない素材で出力することをおすすめします!

 

まとめ

Sense HAT搭載の6種類のセンサから、値を取得することができました!

温度センサについては、ラズベリーパイ本体とSense HATを離して接続するようにすれば、本体からの発熱の影響を回避できるようです(こちらのページの4章のように、ネジの部分に高さを持たせると良さそうです)。

IMUユニットのセンサについては、それぞれのセンサについての基礎知識がないとちょっとむずかしいのかもしれないですね……値は取れたものの、その意味がなかなか分からずに大苦戦!(実はここまでくるのに半年もかかっています…)これらのセンサを応用できるようになるまでの道のりは長そうです。

次回はジョイスティックを使って、Sense HATへの入力を制御してみたいと思います!

アバター画像

プロフィール:プログラミング暦通算4年、最近IT業界に舞い戻ってきたプログラマーです。女子です。

高専ロボコン2019出場ロボット解剖計画