電流電圧ロガーの製作:ソフトウェア (1) 入出力

全ソースコード

ina226_logger.ino

開発環境

 ソフトウェア開発は、Arduino IDE (1.0.6) 上で行った。Arduino 上で ATmega328 の開発を行う設定方法と、hidspx の使い方については、こちらのエントリを参照。ヒューズの書き込み、確認は下のように行った。外部発振子を使う設定にするので、これ以降は発振子をつけた状態での書き込みが必要になる。

INA226 の設定・制御

 INA226 の設定のための定数を #define で定義。使うのはこのうちのごく一部だけど。

 INA226 のレジスタ読み書きの関数。I2C 接続なので、Wire.h をインクルードする。

 そして INA226 の初期化関数。Averaging mode だけデフォルトから変えて、64回にしてある。コンバージョンタイムが 1.1 ms(電圧、電流とも)なので、1.1 ms×2×64 = 140.8 ms ごとにデータが更新されることになる。データ取得は1秒に1回なので、これで十分である。

 データを読み込む関数は readDataValues()。電圧・電流とも 16 ビットの値なのだが、電圧は 1.25 mV 単位なので、1 µV 単位の long 値にした。また、ついでに電池電圧の値も読み取っている。analogRead() の値から、分圧の倍率 (3.14倍) と基準電圧 (1.1 V) を使って変換。これは mV 単位の int 値としている。

 setup() では、まず Wire.begin() で I2C を初期化した後、setupINARegister() を呼び出す。また、analogReference も内部 1.1 V に設定しておく。ここで一度 readDataValues() を呼び、cellvoltageLOW_BATTERY (= 2000) よりも低ければ電池切れとする。

液晶表示器の設定・制御

 Arduino の標準ライブラリの LiquidCrystal は、パラレル接続の液晶用なので、今回は使えない。I2C 接続の液晶のライブラリとして、オレ工房さんが作成されたものをお借りした。以下のコードのコメントで、パッチを当てた旨が書いてあるが、今回はパッチで拡張した機能は使っていないので、どちらでもよい。ST7032 型のオブジェクトを作り、setup() の中で初期化する。ST7032 駆動の液晶はコントラストをソフトウェアで制御する。setContrast() の引数は、実際に表示させて適切な値に設定する。

 initCGRAM() という関数は、バッテリー残量表示のための外字を作成する。定数の配列は PROGMEM prog_uchar と指定しないと、実行時に RAM に転送されて RAM 容量を圧迫するので、要注意(参照:2011/11/12エントリ)。

 液晶表示は2行で、1行目に現在の動作モード、2行目に電圧・電流値を表示する。1行目を表示するのが、下の showTitleLine() 関数。動作モードを表す変数を mode として、その値によって表示内容を振り分ける。MODE_READY の時に出てくる intervals[intervalIndex] は、データ取得の間隔である。1,2,5,10,20,30 秒/分の中から選択するようにしてある。また、MODE_STARTREC, MODE_STOPREC(それぞれ記録開始、記録終了時にスタートボタンを長押ししている状態)の時に出てくる logname は、SD に記録するファイル名である。

 バッテリー残量表示は、同じ showTitleLine() の最後の方で処理している。cellvoltage の値が LOW_BATTERY (= 2000) より小さくなった時に電池切れと判断するので、2400 (2.4 V) から LOW_BATTERY の間を6段階に分けて表示する。lcd.write(n) (n = 0..5) は外字表示である。

 データ部分の表示は下の通り。こちらは場合分けがないので、単純である。

SDカードの制御

 SD カードの制御には、Arduino 標準ライブラリの SD を使う。下の makeFileName() 関数は、SD カードに記録するためのファイル名を決定する。「5桁整数.txt」という名前で、00000 から始めて未使用の名前を探す。29999 まで探しても見つからなければ、エラーとする。

 setup() では、まず SD.begin() で SD カードとの通信を開始し、その後 makeFileName() を呼び出す。どちらかで失敗すれば、SD カードエラーとする。

 記録モードでの動作は、割り込み処理の項で説明する。