センサーとArduinoとRaspberry Piでしたいこと(2)

準備したもの。

Arduino UNO R32
Raspberry Pi 2 Model B1
DIGI-XB24-Z7WIT-0042
Arduino ワイヤレスプロトシールド1
DFR0015(Xbeeシールド)1
BME280使用 温湿度・気圧センサモジュール1
FT232RL USBシリアル変換モジュール1

Arduino UNOはプロトタイプとして使ってます。真面目に使う時は互換機を作るなりして、コストダウンを図らないとダメだなとか思います。それとXbeeもXbeeシールドを使っているのだけど、プロトタイプとして作るには便利ですけど、実際に使うとなるとコストがかかるので、これも考えないといけないです。XbeeシールドはArduino ワイヤレスプロトシールドを2つでも良いのですが、DFR0015の方が安かったので途中で路線変更した結果です。

 

これを順番に組み立てて、それぞれで動作確認をしながら組み立てていきます。

  1. Arduino UNOとBME280の接続
  2. Xbee同士の通信
  3. Arduino UNOからXBeeでの通信
  4. Xbee経由でArduino UNOとの通信
  5. Arduino UNOとRaspberry Pi 2 Model Bとの通信
  6. Raspberry Pi 2 Model BでMySQLへの書き込み
  7. Raspberry Pi 2 Model B上のMySQLとCentOS7上のMySQLとでレプリケーション
  8. CentOS7上のMySQLのデータを使って、グラフ化をする

くらいでしょうか。随分としないといけないことが多いです。

センサーとArduinoとRaspberry Piでしたいこと(1)

今のところのモチベーションとして、センサーを配置して、センサーのデータを収集して、それをデータベースに入力して、そのデータを使って、いろいろなことに使いたいなぁというものがある。最近だと、Raspberry PiやArduinoとかの小型PC、マイコンが簡単に扱えるので、これを使えばできないかなぁと思うところです。

 

Raspberry PiとArduinoの大きな違いはRaspberry PiはあくまでPCなので電源をきちんと確保しないといけないとか、電源を突然切ってはいけないとか取り扱いがちょっと面倒というのがあるけど、その一方で複数のプログラムを同時にうごかすことができるから機能的には便利です。Arduinoは複数のプログラムを動かすことはできないという問題はあるんですけど、消費電力が小さくて、電源を突然切っても問題がないという利点があります。

 

センサーをあちこちに配置する時に一番の問題になるのが電源です。センサーを設置したいところで必ずしも電源が確保できるとは限らないので、太陽電池、バッテリーで長時間稼動できないといけなくなります。こうなうとRaspberry Piには不向きです。消費電力が小さく、電源断でも機器的に問題のないArduinoに向いています。逆にネットワークを使っていろいろしたいというならばRaspberry Piの方が便利です。

ということで、最初のモチベーションの実現方法を考えると次の図のようになるかなと思います。

 

Xbee_1

 

センサーから得られた情報をArduinoで数値化して、それをXbee経由でもう一台のArduinoに転送します。その他とで、シリアルでRaspberry Piとつないで、Raspberry Piに転送します。Raspberry PiではMysqlが稼動していて、いったんそこにデータを格納します。基本、ここまでできればいいのですけど、データのバックアップも兼ねて、センター側のサーバーにデータを転送します。

直接、センサーとXbeeをつないで、XbeeとRaspberry Piをつないで、Arduinoなしでつなぐという方法もあるのだけど、様々な種類のセンサーをつないでも大丈夫なようにしようとすると、Arduinoで一度、データを整形してからの方が便利かなと思ってます。センサーはアナログのものもあれば、デジタルのもあるので、こういうのの処理はArduinoの方が得意です。Raspberry Piはアナログ系が弱いという問題もありますから。アナログはArduino、デジタルはRaspberry Piで処理するというのもあると思いますが、構造が複雑になりそうなので、センサーからの情報はArduinoで処理した方が簡単になると思っています。それに、Arduinoは先人の人たちによるそれぞれのセンサーに合わせてスケッチがあったりして便利なんです。また、Arduinoは互換機を簡単に作れるので、安く作ろうとしたら500円くらいで作ることができるので、あまりコストも高くないのでコントロール性を考えると良いのかと思っています。

 

ということで、この仕組みを作り上げるために順番に作っていきたいと思います。

Raspberry PiでI2CをC言語で遊ぶために

Raspberry PiでGPIO経由で制御したい時にいろいろ調べているとPythonで制御っていうのが多いんですけど、処理速度を要求しない場合にはPythonだと辛い気がするので、やっぱしCでプログラムを書きたくなる。とかいってると、C言語さえ覚えていればいいんじゃないって思えてくるのですが、別に言語なんかどうでもよくて、言語なんか自分の都合にあわせて切り替えればいいんじゃないと思います。ただ、細かく勉強しようと思ったらC言語の方がいいかなぁとかは思ってます。

 

Pythonのパッケージとかを使うとずいぶんと簡単に制御できるんですけど、Pythonがあらゆるプラットフォームで動くと思ってないし、Pythonがいつまでサポートされているかかわらないから、それに偏るよりは基本的なことを覚えて、後で使い易いプログラム言語(スクリプト言語も含む)で作ればいいんじゃないかと思ってます。となると、まずはC言語になるんです(昔はマシン語からだったんだけどなぁ…)。

 

Raspberry PiでGPIOをC言語を使って制御しようと思うとWiringPiが有名でこのライブラリーは便利です。C言語的な前知識はいりますけど、便利です。これもRaspberry Piであればいいですけど、いつまでサポートしてくれるかわからないし、Arduinoあたりのマイコン系を使用したい場合に使えないので、できる限りデフォルトの状態で使うというのが、趣味でする場合にはちょうどいいような気がしてます。

 

Raspberry Piであれ、Arduinoであれ、そのデバイスが使えるようになっているのであれば、そのデバイスを使うための基本となるライブラリー(デベロッパー)も一緒に配布されています。それを使って使えるようにするというのが重要なのだと思います。例えば、Raspberry PiでもArduinoでもI2CやSPIをサポートしていますが(Arduinoはサポートしているのもあるが正解)、それのアクセス方法がRaspberry PiとArduinoで根本から違うということはあまりなく、似ているので関数系の使い方さえわかればなんとなくわかりるものです。

 

ここではI2Cについて話をします。I2Cは2本の信号線だけで通信を行う規格(電源、グランドが必要なので都合4本)でデバイスを数珠繋ぎできる規格でGPIOのピンが無限にあるわけではないRaspberry PiやArduinoでは使用するGPIOピンを減らすことができるという便利な規格です。ハードウェアで直接サポートしていなくてもプログラムさえかけば通信ができるのですが、Raspberry PiやArduinoではサポートしているので簡単に使えます。Raspberry Piでは初期状態では使えない状態になっているので、使えるように変更する必要があります。方法は別に記述したのでそちらを参照してください。

 

Raspberry PiでI2Cを使えるようにすると、/devの下にi2cdev-*というデバイスドライバーでできています。今の仕様だとRaspberry Pi B、Raspberry Pi B+、Raspberry Pi 2ではi2cdev-1になるようです。このデバイスドライバーにアクセスして通信を行えばI2C系のデバイスの制御ができるようになります。

 

Raspberry Piでデフォルトで配布されているi2Cを制御するためにi2c-devというライブラリがあります。ヘッダーファイルはi2c-dev.hというのがあるますので、それをプログラム時にincludeすることで使えるようになります。

 

I2Cのデバイスはそれぞれのデバイスでアドレスがマッピングされているので、そこにアクセスしてあげれば情報を引き出す、書き込むことができます。例えば、気圧センサーのLPS25hは0x5dにマッピングされているのでそのアドレスにアクセスします。

 

基本的な使い方は、最初にopenを使用してi2cdev-1にアクセスして、ioctlを使ってどこのアドレスにアクセスするかを指定して、i2c_smbus_read_byte_data、i2c_smbus_write_byte_dataで必要な情報を呼び出したり、書き込んだりします。データが全て16進数で出力されたり、細切れで出てくるので、それをつなぎ合わせたり、10進数にしたりして加工すれば終わりです。呼び出し、書き込みがそれぞれのデバイスによって異なるのでそれを参照のこと。基本、チープなデバイスですので、できることはそんなにないです。

 

LPS25Hの場合の簡単なプログラム。エラー処理とかいろいろしないといけないのだけど、まずは動けばいいというれべるであれば、こんな感じで大丈夫です。なんかわからないのですが、8bit出力のはずなのに、8bitが2回出力されている感じがあるので、0xffでマスクして8bitに変更してから、細切れのデータをつなぎ合わせて計算してます。プログラム的には美しくないです。

 

 

 

I2Cのデバイスを使用するための準備

Raspberry PiにはI2Cのデバイスを簡単に使用できるようになっています。 I2Cは2本の線だけで通信したり(電源とグラウンドが必要なので実質4本)、カスケード接続ができたりするので、GPIO節約にはもってこいの規格です。

ただ、GPIOポートをI2C用に設定してしまうとI2Cを使わない場合にGPIOポートが無駄になってしまうので、初期状態では使えないようになっています。I2C を使用するためには次の部分の設定を変更します。

まず、/boot/config.txtに

dtparam=i2c_arm=on

を追加して、/etc/modulesに

i2c-dev

を追加して、/etc/modprobe.d/raspi-blacklist.confの

blacklist i2c-bcm2708

をコメントにして、再起動します。

すると、/devの中にi2c-1というデバイスができてます。

Raspberry Piのファームのアップデート

Raspberry Piのアップデートの方法です。

Githubで公開されているツールを使うと簡単にできるらしい。とはいうものの、raspbianにすでに実装されているので特にインストールする必要はないです(rpi-updateのリンク

使い方は次の通りです。