Baumkuchen’s Workshop

バイオリンと電子工作、DIY、ジョギングなど。

データロガーの改善(ソフト編)

USBのCDCインターフェースの確認が途中ですが、その他機能を整えて、DataLoggerとして、完成させます。

 (順次、追記していきます。記事の順番と実装順は必ずしも一致しません。) 

baum-kuchen.hatenablog.com

 

f:id:Baum_kuchen:20200711222319j:plain

アクリル板に載せてみました。配線面の保護も兼ねます。なんか、かっこよく成った。

f:id:Baum_kuchen:20200711222335j:plain

裏に電池を配置しました。これで、アウトドアへも持っていけます。

 LCD シラパラ変換

既にハードウェアとして実装済みですが、詳細を書き漏らしているので説明します。手持ちのLCD表示器のインターフェースがパラレル8bitのものであったため、PICどうつなぐかを思案。そのままつなげが、8bit+コントロール線(RS:レジスタセレクト、E:データイネーブル)の10PIOが必要でとても28pin PICでは足りない。そこで、74HC164のシフトレジスタを使って、シリアル/パラレル変化をすることにしました。

f:id:Baum_kuchen:20200620165047p:plain

PICからはデータ、クロック(シフトレジスタ用)、イネーブルの3本で実現。LCD表示器としては、R/W設定も必要ですが、表示器のステータスはあえて見ないこととし、Wオンリーとしました。シフトレジスタ用データ線は、LCDのデータ/コマンドレジスタ切替用にも兼用。

更に、LED駆動用のPIOも足りなかったので、クロック線をLED表示と兼用しています。

まず、LCD用の動作としては、データ(A)とクロック(CLK)を使い、シフトレジスタに8bitセットし、次に、データ/コマンド切替(RS)をセット。最後にイネーブル(E)を1パルス出力することで、LCDに1バイト書き込み完了となります。

LEDの駆動は、通常はCLK線でLEDをそのままON/OFF制御。このとき、イネーブル(E)はOFFのままなので、LCD表示器への影響はなし。LCD制御するときは、LEDのON/OFF状態を覚えておき、いったんCLKをOFF(LED消灯)。あとは最初に書いたLCD制御を実施した後、覚えておいたLED状態を復活すればOKです。LCDへのデータ書き込み時間は20μS以下なので、LED表示には全く影響なしです。当然、シフトレジスタセット時のCLKパルスもμS以下なので、LEDが光って見えることはありません。

f:id:Baum_kuchen:20200621172709p:plain

CH1:イネーブル(E)、CH2:CLK 兼 LED (カーソル間がLCD制御)

タイミング設計、作動フロー

プログラム構造も整理しました。全体の流れは次のようです。

メイン

1.USB接続時処理

2.通常処理

・キー入力処理

  各キーの押下、長押し判定

・モード変更処理

  表示モード、サンプリング間隔変更、ロギングon/off

・表示処理

   モード、サブモードで表示

・ロギング処理

  ダブルバッファ処理

チャタリング防止wait(疑似的な周期処理)

割り込み

 ・GPSデータ受信

 ・1msタイマー

   AD、DIデータ記録(ダブルバッファ)

ADデータ、DIデータ記録

アナログ入力とディジタル入力(外部及びイベント)について。サンプリング周期は、最小1msとすることにしました。タイマー割り込みで1msを作り、これを基準にすべてを動かします。

ADが10bit、ディジタルが2bitなので、1サンプルで1ワード16bitで記録し、1秒毎にSDカードに書き込むこととします。バッファとては、1000ワード必要ですが、PIC24FJ64BG002は、RAM容量が8Kbytesあるので大丈夫でしょう。

ADサンプルの時間を測ってみると、約22μSと処理負荷的にも余裕がありそう。GPSの受信割込みが、38400baudなので、0.26msに1回となるが、これも大丈夫。

SDカードへの出力フォーマットはいろいろ考えられますが、バイナリでは取り扱いが面倒なので却下。テキストベース(CSV)を基本とし、可変長とならないようADとディジタルを合わせた1ワードをHex表示4桁で記録することにしました。

問題は、ADカードの書き込みが間に合うかです。SDカードの最高速度は10Mとかありますが、今回はSPIモードでの使用ですので、Microchipのライブラリを覗いてみると4MHzのSPI設定となっているので、500Kbytes/S以上は出ない勘定。

SDデータフォーマットから、

 (データ4bytes+カンマ1byte)×10(サンプル)+改行コード1byes = 51

を100個で、5100bytes。これにGPSデータ(約400bytes/秒)が加わることになる。あとは、実測してみるしか無いです。

500サンプルのSDカードへの記録時間です。通常は40ms以下ですが、10回に1回程度、約100msとなることがありました。多分、ファイル処理の関係かと思いますが、これを最大値としてタイミング設計に落とし込みます。ちなみに、SPIの速度から計算した時間が約10msですから、その10倍(通常は約4倍)程度かかっていることになります。

f:id:Baum_kuchen:20200622004356p:plain

CH1:SDカード書き込み(LED ON/OFFで計測)、CH2:GPS 1PPS(参考)

ダブルバッファ処理

データサンプリングとSDカードへの書き込みを独立させるために、ダブルバッファにします。サンプリングのバッファを2分割(page0,page1)し、サンプリング中は一つのバッファ(仮にpage0)にデータを一時保存し、もう一つのバッファ(page1)のデータをSDカードに書込みます。次のタイミングでは、バッファpage1にサンプリングデータを一時保存し、前のタイミングデータを一時保存したバッファpage0のデータをSDカードに書込みます。あとは、バッファpage0,page1を交互に入れ替えて続けて行きます。 

f:id:Baum_kuchen:20200628212113p:plain

バッファを切り替えるタイミングとしては、一定時間毎とするか、バッファ容量が一杯となったかが考えられますが、前者はサンプリング間隔によってバッファ内のデータ量が変わるため、簡単化のため後者の方式とする事にしました。最大1秒に1000サンプルなので、500サンプルバッファを2個用意して、500msに1回のSDカードへの書き込み。SDカードへの書込みが最大100msなので間に合う勘定です。もっと短い間隔でも問題無さそうですが、メモリ容量も問題ないのでキリの良い値としました。

ログデータのサンプル(抜粋)。一秒おきのGPSデータがあり、その後に500サンプル分のAD、ディジタルデータが続きます。500サンプルは、10サンプル毎にカンマで区切る形としました。

f:id:Baum_kuchen:20200712164856p:plain

判明している問題点 :

・サンプリング間隔が長くなると、500サンプルたまるまでの時間が当選長くなり(1サンプル/秒だと、約8分)、その間に記録ストップすると、SDカードに記録されない。

・設定によっては、大きな容量のファイルが出来る(仕様ですが)。サンプリング間隔を1000サンプル/秒で24時間記録してしまうと、1Gbyteクラスのファイルができる。 

サンプリング間隔設定

サンプリング間隔としては、1秒間に1000サンプルから1サンプルまで、10種類を用意。これを2のスイッチで設定できるようにするため、スイッチの長押しを活用。

まず、スイッチ長押し判定の実装。

f:id:Baum_kuchen:20200628010937p:plain

続いて、SW1とSW2の押し、長押しの状態を検知し、以後、次のアルゴリズムにて処理を実施します。

SW1処理

・通常モード:表示モード切り替え

・設定モード:設定項目変更(現時点ではサンプリング周期のみ)

・ロギング中:イベントトリガーとして記録

 SW1長押し

・通常モード:設定モードへ変更(AD表示時かつロギング非実施中のみ)

・設定モード:サンプリングを設定ファイルへ書き出し、通常モードへ

 SW2処理

・通常モード

     ・ロギング未:ロギング開始、ファイルオープン

     ・ロギング中:ロギング停止、ファイルクローズ

・設定モード:サンプリング(設定項目値)変更

 SW2長押し処理

・通常モード:(処理なし)

・設定モード:初期値へ

これによりサンプリング間隔を変更可能とします。

また、サンプリング間隔は、SDカードの初期設定ファイルに書くようにして、次回電源をONしたときも変わらない様にしました。

ファイル名自動生成

ロギング用ファイル名を”LOGDATn.TXT”として、nを記録するたびに、0から9まで変えるようにしました。今回の記録で何を使えるかは、電源を落としても分かるように、初期設定ファイルとして、SDカードに記録してあります。当面はこれで、何とかしのげると思います。

低電力モード

消費電流を測ると、約60mA。単三のeneloopの容量が約1900mAHなので、約32時間の連続作動が可能な計算です。せめて、1週間位は動かないかなと思ってましたが無理なようです。

バッテリー駆動で出来るだけ作動時間を稼ぐための工夫を考えていきます。 

電圧低下割込み

データロギング中にバッテリーが切れた時の対処。PICのパワーダウン割り込みを活用します。 

テスト

テストは実装と同時並行で実施します。

GPS位置データ

電池駆動にして、家の周辺を車で2周した結果です(単位m)。1周目と2周目の誤差は、最大で3m程度。これは、GPSの性能になってはしまいますが、問題ないと思います。データロガーとして、データの欠けも無さそうです。国土地理院の地図と比べても問題なしです。

f:id:Baum_kuchen:20200711221638p:plain

f:id:Baum_kuchen:20200711220815p:plain右下コーナの拡大図

AD、DIデータ

まず、電源を1/2に分圧し、100Hzでサンプリング。ノイズ成分が39mVpp。PICのAD分解能が1024(10bit)なので、6カウント分ということで、まずまずの結果です。

f:id:Baum_kuchen:20200712172846p:plain

次に、変化する電圧を計測します。100Kと1μFでCRフィルタの応答波形を計測しました。立ち上がりがCRフィルタの時定数。立下りはコンデンサの自己放電によるものです。なめらかに計測できているので、データの欠けも無さそうです。

f:id:Baum_kuchen:20200712224108p:plain 

GPS バッテリー電圧変化

データロガーをバッテリ動作させて、自らのバッテリ電圧を測ってみました。朝6時すぎにスタートさせ、夜23時に手動で記録停止しました。

記録データからは、GPSデータが約7時間後に停止しています。バッテリ電圧が3.62Vのところで、GPSモジュールのチップは3.3V動作ですが、モジュールで5V⇒3.3Vのレギュレーションをしているためだと思われます(3.6Vを設定しところ3.0V出力してました)。LCDも5V仕様なので、表示は全く見えませんでした。PIC自体は最低2.2V作動なので、まだ十分動けていたということです。

途中540minのところにある電圧の低下の原因は分かりません。GPSまたはLCDが定格電圧以下で一時的に電流が増加したのかもしれません。

また、スタート直後のバッテリ電圧の低下が大きいです。Eneloopの放電特性を調べてもこんなに急に電圧が低下するはずないんですが。ひょっとしたら、電池の寿命かも。もう一度、しっかり充電したあとで、再確認してみます。

f:id:Baum_kuchen:20200719210304p:plain

バッテリをフル充電して確認してみました。5V(一本あたり1.25V)に漸近するようです。これで、何時間持つかは最終的に測って見ます。

f:id:Baum_kuchen:20200727004401p:plain

 (2020.7.26更新)