Arduino互換Linux機pcDuino3でソフトウェアI2C通信
2014/08/12作成

前回の記事ではI2CでADT7410と通信して温度を表示するArduinoスケッチをプログラムしました。
しかしWireライブラリがWire.endTransmission(false)に対応しておらず、Repeated Start Conditionを送信できないため、実は正常に動作していない事に気が付きました。
これはpcDuino3のWireライブラリが内部でLinuxのデバイスを操作するコードになっており、またLinuxのI2CドライバがRepeated Start Conditionに対応していない事が原因でした。
LinuxのI2Cドライバの関数インターフェイスの設計に欠陥があり、ドライバにパッチを当てる以外にソフトウェア的に回避する方法はありません。
そこで今回はGPIOピンを4本使用し、I2Cの信号をソフトウェアで生成することにしました。
本当はピン2本で作りたいのですが、Linuxのsysfsの仕様上、1本のGPIOピンで入力と出力を同時に使用できないため4個使用しています(正直言ってLinuxは組み込みOSに向いていないと思います)。
pcDuino3以前のpcDuinoやpcDuino v2も同様の不具合があるようですが、プログラム等はそれらの製品でも動作可能で、今回の記事の内容をそのまま適用できます。

まずはソフトウェアI2Cのソースコードを作成しました。
今回のプログラムも前回同様にADT7410から得た温度を表示していますが、通信速度は前回のハードウェアの200kHzよりかなり遅く、10kHzとなっています。
プログラムをあまり最適化していないためか、通信速度は33kHzが上限のようです。
なお、ソースコードにはMITライセンス(修正BSDライセンスと互換)を適用しますので、ご自由にお使いください。



コンパイルは初期状態でインストール済みのGCCで行いました。
通常はコマンド1行のみでもコンパイルできますが、今回は以下のようなmakefileを作成し、コンソールからmakeコマンドを実行しました。



次にGPIOピンでI2C通信を行うための基板を作成しました。

回路図

基板の回路図です。
GPIOピンの番号は何でもよいのですが、今回は上記のプログラムで10番から13番を使用することにしましたので、それに合わせてあります。
基本的に隣り合うピンを選ぶとよいでしょう。
100Ωの抵抗は過電流保護のために入れてあり、これが無いとスレーブ側が信号線をプルダウンした際に不具合が生じる可能性があります。

基板

基板の外観です。
わざわざ基板を用意せずとも作れそうですが、扱いやすさを考慮して基板にしました。

取付時

基板をpcDuino3に取り付けた様子です。
ADT7410の電源には他の端子から出ている3.3Vを使用しました。

最後に基板にADT7410を接続し、コンソール内でプログラムを実行しました。
問題なく動作し、温度が表示されました。
30分程度連続して通信してみましたがエラーは発生せず、またCPUの使用率は1%弱程度でした。


目次 質問フォーム Q&A このサイトについて トップページ