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に変更してから、細切れのデータをつなぎ合わせて計算してます。プログラム的には美しくないです。