Raspberry pi+zabbix + BME280 で温度湿度気圧のロギングをする

Raspberry piに温湿度気圧センサーを接続しzabbixから定期的に値を取得しロギングします。

Raspberry piにRaspbianとzabbix agentを入れ監視が出来ている状態を前提とします。

 

1.センサーを接続する

akizukidenshi.com今回は秋月で売っているセンサーを使用しました。

I2CとSPIに対応してますが扱いが簡単なI2Cで接続します。

ブレッドボード等を使用しCSBをVDD、SDOをGNDに接続しI2CモードにしてVDD,GND,SDI,SCKをRasbperry piに接続します。

 

f:id:Hotspring:20180613170556p:plain

 2.I2C使用の準備

I2C使用の準備をします。

$ sudo su

# apt-get install i2c-tools python-smbus

で必要なソフトウエア、ライブラリをインストールします。i2c-toolsはコンソールからI2Cを操作するためのツール、python-smbusはpythonからI2Cを使用するためのライブラリです。

次に、Raspberry piはデフォルトでI2Cが無効になっているため有効にします。

# raspi-config 

 で設定ツールを起動し

5.Interfacing options

f:id:Hotspring:20180612155146p:plain

P5 I2C

f:id:Hotspring:20180612155236p:plain

の順で選びI2Cを有効にします。

f:id:Hotspring:20180612155300p:plain

 

I2C使用の準備が整ったか確認します。

# i2cdetect -y 1

で接続されたI2CデバイスのIDを確認出来ます。

f:id:Hotspring:20180612155547p:plain

ここではIDが0x76のデバイスが接続された状態になっています。

表示されなければ接続や設定を確認してください。

3.値取得

SwitchScienceの公開してるサンプルのpythonスクリプトを値の取得と表示を分離するよう修正したものを用意しました。

そのまま実行すれば温度湿度気圧が表示されます。

https://github.com/Hotspring-r/BME280/blob/master/Python27/bme280_sample.py

# wget https://raw.githubusercontent.com/Hotspring-r/BME280/master/Python27/bme280_sample.py
<略>

2018-06-12 07:46:53 (3.09 MB/s) - `bme280_sample.py' へ保存完了 [3999/3999]

# python bme280_sample.py
temp : 26.78 C
hum : 49.65 %
pressure : 994.03 hPa

上のスクリプトを/etc/zabbixに置き、json形式で出力するスクリプトを barometer.py という名前で同じ場所に作成します。

# barometer.py 

import bme280_sample
bar = bme280_sample.readData()
print str(bar).replace("'","\"") 

 実行するとjson形式で温度湿度気圧が出力されます。

# python barometer.py
{"hum": 51.28607150999257, "pres": 1008.3877801085655, "temp": 27.001369402982526}

4.zabbixの設定

/etc/zabbix/zabbix_agentd.conf に以下の行を足してzabbixからスクリプトを呼べるようにします。

UserParameter=Barometer,python /etc/zabbix/barometer.py

デフォルトでzabbixユーザーにはi2cへのアクセス権限がないのでadduserで権限を付与し、再起動します。

 

# adduser zabbix i2c
ユーザ `zabbix' をグループ `i2c' に追加しています...
ユーザ zabbix をグループ i2c に追加
完了。
# reboot

 

http://static.bmscr.com/blog/barometer_template.xml からテンプレートをダウンロードしzabbixの管理コンソールからインポートしてRaspberry piのホストにテンプレートを設定します。

Barometerという名前のアイテムでjsonを1分ごとに取得し依存アイテムで温度湿度気圧それぞれの値を取り出してます。

f:id:Hotspring:20180614184040p:plain

グラフで値の変化を見ることも出来ます。

f:id:Hotspring:20180614184051p:plain

 

VSSからMercurialに変換する

弊社開発環境からMicrosoft製ソース破壊管理ツールVisual Source ShredderSafeを駆逐しMercurialに移行することに成功しました。

VSSから別のVCSへ移行するツールは大量にあるのですが日本語がまともに扱えなかったりそもそも動かなかったりして最終的に成功したのはhanaguro8/vss2gitだけでした。

私は検証していませんがツール自体はgit,Bazaarにも対応していますしソースがわかりやすいので他のVCSに対応させるのもさほど難しくは無いと思います。

基本的な使い方は

を見ていただければわかると思いますがいくつかの躓いた点を解説します。

  1. Mercurial周りにバグがあります。
    修正してPullRequestを送ってありますが2年以上更新の無いプロジェクトなのでいつ反映されるかわかりません。反映されるまでHotspring-r/vss2gitを使用してください。PR反映されました
  2. rubyが64bitだと死ぬ。
    ちゃんと解説ページにも添付ドキュメントにも書いてあるのですが見落としてしばらく悩みました。内部でCOMを呼び出すので32bit版rubyを使わないと死にます。
  3. Mercurialの言語設定が日本語だと死ぬ
    内部でMercurialの吐き出すメッセージを解析しているので英語以外の言語にしていると死にます。実行前に
    set LANGUAGE=en-us
    のように環境変数を設定すればMercurialの言語を一時的に変更できます。内部で環境変数を設定するよう修正されました
  4. 日本語のファイル名を使ってると死ぬ
    Mercurial側の問題ですが win32mbcs エクステンションを有効にしないと死にます。
    内部でMercurialリポジトリを作成してすぐにコミットされるのでリポジトリ個別設定で有効にしている時間はありません。日本語環境から頻繁に使うのでグローバルで有効にしてしまった方が良いです。

 

Windows 10 IoT Insider Previewの新しいバージョンが出ました

6/24にこっそり新しいバージョンのWindows 10 IoTがリリースされました。

ms-iot.github.io

主な更新点は

  • 専用のFFU書き込みツールが付属するようになった
  • Secure Shell (SSH) サーバーをサポート
  • Raspberry Pi 2 で音声出力をサポート(USBオーディオオンボードアナログ出力)
  • 内蔵Webサーバーのポートが80から8080に変更

 です。

FFU書き込みツールが付属するようになったため dism.exe を入手する必要がなくなり、ディスク番号を間違えて違うディスクのデータを飛ばしてしまうこともなくなりました。また、シンプルなインターフェイスで使いやすくなっています。

公開されているファイルの形式がmsiが1つだけ入ったisoイメージになりました。

インストールするとWindowsIoTImageHelperという名前のFFU書き込みツールがインストールされます。

f:id:Hotspring:20150703163150p:plain

FFUファイルは C:\Program Files (x86)\Microsoft IoT\FFU\RaspberryPi2 におかれています。

SDカードを選択し、ffuを選択すれば書き込みができます。

Raspberry PI + Windows 10 IoT + C#でI2Cでキャラクタディスプレイに接続する

今回は秋月の有機ELキャラクタディスプレイモジュールを接続します。

出力機器なのでデバイス側からデータを受け取る必要は無く一方的に送るだけなのでセンサーよりも簡単かもしれません。

必要な物
 回路接続

今回は秋月で売ってるブレッドボード用変換基板を使いました。接続がしやすくなるだけなのでなくても全く問題ありません。

今回使用するキャラクタディスプレイは4番ピンの接続でアドレスを切り替えることができます。今回はLowにしてアドレス0x3Cを使用します。f:id:Hotspring:20150527172542p:plain

センサーとディスプレイの2つのデバイスを接続しますが並列に接続するだけで問題ありません。

ディスプレイの3番ピンをGNDに接続する必要があったりI2CのInとOutが別のピンになってて両方に接続する必要がありますがデータシート通り接続すれば問題ありません。

プログラム

センサーは前回と同様に初期化します。

ディスプレイはコマンドを送るときは最初に0x00を送ります。

画面クリアは0x01、カーソル位置を初期化するのは0x02、画面表示の設定は0x0Cなので順に送信します。

_display = await InitI2cDevice(0x3C);
// 画面クリア
_display.Write(new byte[] { 0x00, 0x01 });
// カーソルを左上へ
_display.Write(new byte[] { 0x00, 0x02 });
// 表示設定
_display.Write(new byte[] { 0x00, 0x0C });

カーソル位置を1行目先頭にするには0x80、2行目先頭にするには0xA0を送ります。

文字を表示するには0x40に続けてコードを送信します。英数字はASCIIコードと同じコード体系になっているのでChar型をByteにキャストしてそのまま送信できます。

今回は若干トリッキーではありますがLINQを使ってキャストしてToArrayでByte配列にしています。

_display.Write(new byte[] { 0x00, 0x80 });
_display.Write(new byte[] { 0x40 }.Concat(v2.Select(_ => (byte)_)).ToArray());

  前回のプログラムで取得した温度湿度をstring.Formatで文字列に変換して表示しています。

特に変わったことはしていないので解説は省略します。ソースコードを見てください。f:id:Hotspring:20150526102959j:plain

今回のプログラムI2cDisplay.zip

 

Raspberry PI + Windows 10 IoT + C#でI2Cで温湿度センサーに接続する

今回は秋月の HDC1000使用 温湿度センサーモジュール をI2Cで接続して温度と湿度を計測します。

I2C is 何

I2CとはInter-Integrated Circuitの略で近距離通信用の低速なバスです。名前の通りIC間の通信等電子機器内部の使用を想定しています。

※通信速度は10kbps~3.4Mbpsの複数のモードがありますが、Windows 10 IoTの標準ライブラリでは現状100kbps,400kbpsの2つしか対応していません。

2は上付き文字が正式な名称ですが普通の数字が使われることもあります。読み方はアイ スクエアド シーが正式な読みですがアイ ツー シーと呼ばれることも多いです。WikipediaにはIICと略されることもあると書かれていますが私は見たことがありません。

データ線が2本で外付け回路が2本のプルアップ抵抗だけで済む等回路が簡単であること、1つのバスに複数の機器を接続できること、ホットスワップに対応、特許が2004年に失効していてロイヤリティフリーで使用できること等から広く使われており対応したデバイスも簡単に入手できます。

PC内部デバイス管理に使われるSMBusやPCとモニターの間で解像度等の情報を交換するDDC、変わったところではWiiのコントローラーとヌンチャク等の周辺機器との通信等にも使われています。

I2Cはマスターとスレーブの構成で通信は全てマスターが管理しスレーブから通信を開始することはできません。スレーブは全て7bit(16個の予約アドレスがあるため使用可能なのは112個、10bitの拡張規格もあるけどあまり使われていない)のユニークなIDを持っています。マスターを複数にすることもできますがマスター間、スレーブ間の通信はできません。

用意する物
回路作成

I2Cは2本の信号線にプルアップ抵抗が必要ですが、Raspberry PIはプルアップ抵抗が内蔵されているため接続するだけで使用できます。

秋月のHDC1000モジュールには+V,GND,SDA,SCL,RDYの5つの端子があります。

+V,GNDは電源、SDA,SCLはI2Cです。RDYは今回は未接続でかまいません。

図のように接続します。

 

f:id:Hotspring:20150520112007j:plain

プログラム

XAMLにTextBlockを置き温度を表示できるようにします。コードビハインド側に温度、湿度を格納するプロパティを置きINotifyPropertyChangedを実装してプロパティの変更を通知できるようにします。通常のWPFと同じなので解説は省略します。

<TextBlock FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center">
    温度:<Run Text="{Binding Temp}"/>°<LineBreak />
    湿度:<Run Text="{Binding Hum}"/>%
</TextBlock>

最初にI2Cを使用するためポートを初期化します。

I2Cを使用するにはWindows.Devices.I2c名前空間のクラスを使用します。

いろいろデバイス名を取得したり設定をします。I2cDevice.GetDeviceSelectorの引数はRaspberry PIなら"I2C1"固定です。デバイスによって変わるみたいです。初期化処理は基本的に変更する必要は無いはずです。変更するとしたらBusSpeedくらいだと思います。デバイスが対応していればFastModeが選べます。

using Windows.Devices.I2c;
 
private static async Task<I2cDevice> InitI2cDevice(byte address)
{
    var aqs = I2cDevice.GetDeviceSelector("I2C1");
    var device_information_collection = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
    var deviceId = device_information_collection[0].Id;
    var connectionSetting = new I2cConnectionSettings(address);
    connectionSetting.BusSpeed = I2cBusSpeed.StandardMode;
    connectionSetting.SharingMode = I2cSharingMode.Shared;
 
    return await I2cDevice.FromIdAsync(deviceId, connectionSetting);
}

マニュアル通り初期化コマンドを送信します。0x02 0x10 0x00を送信で温度湿度同時測定になります。

I2CのデバイスIDはマニュアルに記載されています。今回は0x40です。

byte address = 0x40;
I2cDevice device = await InitI2cDevice(address);
// デバイス初期化
// 測定モードを温度湿度同時にする。
device.Write(new byte[] { 0x02, 0x10, 0x00 });

0x00を送信すると測定を開始し、約13msで値の取得が可能になります。RDYピンの状態を監視すれば変換完了後すぐに取得できますが回路プログラム共に複雑になるので今回は余裕を持って100ms待ってから値を取得するようにします。

// 測定開始
device.Write(new byte[] { 0x00 });
// センサーの測定待ち。測定にに13[ms]かかるので余裕を持って100[ms]待つ。
await Task.Delay(100);
var buf = new byte[4];
device.Read(buf);
// 仕様書通りに変換
var temp = (buf[0] * 256.0 + buf[1]) / 65536 * 165.0 - 40.0;
var hum = (buf[0] * 256.0 + buf[1]) / 65536 * 100.0;

UIスレッド以外からPropertyChangedイベントを発行すると落ちるっぽいのでDispatcher.RunAsyncでUIスレッドに戻します。

await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
    this.Temp = temp;
    this.Hum = hum;
});

タイマーで定期的に実行するようにすれば温度湿度が表示できます。

f:id:Hotspring:20150520112955j:plain

今回のプログラム i2c.zip

Raspberry PI + Windows 10 IoT + C#でLチカ

Raspberry PIでLチカします。

LチカとはLEDをチカチカ点滅させることで、Hello Worldに相当するエンベデッド系で最初に作成するプログラムです。

今回はRaspberry PIのGPIOにLEDを接続してGUIからLEDを点灯消灯できるプログラムを作成します。

GPIOとはGeneral Purpose Input/Output(汎用入出力)の略でデジタル信号の入出力を行うことができます。

必要な物
  • Windows 10 IoTインストール済みRaspbery PI、VS2015開発環境
  • LED(とりあえず赤か緑を推奨。白や青は電圧が足りず使用できない可能性があります)
  • 抵抗(LEDの仕様で抵抗値を決めますがとりあえず100~400Ωくらいなら動くと思います)
  • ブレッドボード、ジャンパワイヤー(オス-メス)2本
LEDの接続

Raspberry PI 2のGPIO0~4は別の機能と共有になっているため今回はGPIO5を使用します。

Raspberry Pi 2 Model B GPIO 40 Pin Block Pinout | element14

GPIO5,LED,抵抗,GNDを直列につなぎます。LEDは極性があるので注意が必要です。長い方が+です。

f:id:Hotspring:20150520110125j:plain

プログラム作成
  1. Windows Universal のBlank Appプロジェクトを作成します。
  2. GPIO制御のためWindows IoT Extension SDKの参照設定を追加します。Windows Universalの拡張の中にあります。
    f:id:Hotspring:20150513002842p:plain
  3. MainPage.xaml にボタンを2つ追加します。

  4. MainPage.xaml.csを記述
    GPIOの制御にはWindows.Devices.Gpio名前空間のクラスを使用します。
    GpioController.GetDefaultでGpioControllerを取得し、OpenPinで制御したいピンを開きます。
    SetDriveModeでOutputモードに設定すればGPIOの出力ができるようになります。

実行すると画面にON/OFFの2つのボタンが表示されLEDを制御することができます。

 

f:id:Hotspring:20150512210149j:plain

本日のプログラム Lchika.zip

Raspberry PI + Windows 10 IoT + C#でHello World!

 Raspberry PIの開発にはVisual Studio2015とWindowsDeveloperProgramForIoTが必要です。VS2015はRC版が無料で入手できます。WindowsDeveloperProgramForIoTはOSのイメージファイルと一緒ついてくるのでインストールします。

Raspberry PIで動くのはWindows Universal Appです。当然x86用に作られた通常のexeは動きません。残念ですがGDIがサポートされないためWindows Form Appも動かすことはできません。

Universal AppのUIはXAMLで記述します。

プログラムの作成
  1. Windows Universal のBlank Appプロジェクトを作成する。

    f:id:Hotspring:20150511231601p:plain

  2. MainPage.xaml にボタンを追加する。

  3. MainPage.xaml.csにイベントハンドラを記述

Raspberry PIへの転送、実行
  1. プラットフォームをARMに変更
  2. Deviceからリモートコンピュータを選択

    f:id:Hotspring:20150511233155p:plain

  3. リモート接続ダイアログの設定
    アドレスにRaspberry PIのIPアドレスを入力。Raspbarry PIの画面から確認できます。

    f:id:Hotspring:20150511230419j:plain


    認証モードは”なし”で選択ボタンをクリック
    f:id:Hotspring:20150511233255p:plain

  4. F5で実行

  5. ビルドの後自動で配置が行われRaspberry PI上でプログラムが起動します。

マウスを接続すれば通常のGUIと同じように操作できます。(私の環境では反応が鈍くボタンを長めに押す必要があることがありました。)

f:id:Hotspring:20150511234722j:plain

デフォルトでリモートでバッグが有効になっているため複雑な設定等は一切することなく実行、デバッグができます。

ブレークポイントやクイックウォッチ等も普通に動作します。もちろんステップ実行もできます。

f:id:Hotspring:20150511235320p:plain

従来のエンベデッド開発ではデバッグ環境の構築が難しかったり機能が貧弱な事が多かったですがWindows 10 IoT+Raspberry PiではWindows Appと同等のデバッグ環境が簡単に構築できます。

今回作成したプロジェクトをこちらに置いておきます。

helloworld.zip