この6か月ほど、Teensy4.1でのSDカードログで、いろいろトライしてきましたが、そこそこ動いている状態で、バリエーションを変更すると一からやり直しとなる状態なのでTIPSまとめました。
今回は、3個のGNSSボードから周期の異なるUBXデータをSDログする難易度が高いプログラムで
TIPSとして備忘録しておきます。
感想:OPEN,CLOSE動作は、飛行機で言うと離陸と着陸にあたりますので、緊張を強いられます。
ですので、多数回とか、多数個所で安易な使い方は、事故の元で、慎重に作りこまないと4M変動でこけてしまいます。
TIPS0【シリアル通信からのデータをSDログプログラムは、最低15分テストしないとダメ】
=>数分でハングする場合が多いので、ログテストは、統計的に実験評価しないとこけます。
TIPS1【OPEN CLOSEは、LOOOP内で1対にすること、頻度を減らすことが安定ログには必要】
=>setupで、open して、loopでOPEN1個、CLOSE1個とすること、loop内でopen2個、close1個にするとハングします。
=>毎周期にOPEN CLOSEをいれるとハングしやすくなるので、避けるべきです。
=>種類の違うファイルを何個も1周期でSD書き込みする場合も、OPEN CLOSEが増えますので
ハングし易くなります。
◎良い方法=setup内で初回OPENして、loop内で、if文で、一定時間経過したら、CLOSEして8-10msec delay()してOPENする処理をつけて、ログを延々と回す。だいたい、数分に一回おきにCLOSEして、その間のデータを確定保存したほうが、急な電源落ちに対応できます。
TIPS2【複数ファイルでなく、データをひとまとめにして1ファイルに書いたほうが安定する】
=>私の場合、3枚のGNSSボードとIMUからの周期の違うデータがシリアル4ポートから入ってきます。これをひとまとめにするのが、至難の業で、6か月悪銭苦闘した結果をご説明します。
当初複数ファイルを1周期でログしていたのですが、条件次第では、不安定になる場合があって
最終的に、複数ファイルではダメという結論に至りました。データが大きなファイルになりますが、SD書き込み特性的には、データ量が多いほど、高速書き込みできるので安定します。
●TIPS2の事例
F9P最速10Hz F9H最速8-10Hz M9N最速25Hz IMU最速5msecとバラバラな周期のセンサ入力を
ログするシステムです。
※Teensy4.1でないと簡単には作れないシステムです。
①最小公倍数の周期でまとめる。
F9P100msecを120msec、F9H125msecを120msec、M9N40msecはそのまま、IMU 20msec
そうすると最小公倍数が120msecでまとまるので、システムの周期を120msecに統一できる
②Hardwareシリアルで、センサ毎にバッファ容量を設定する(バッファは32の倍数)
1:F9P,F9Hのシリアルバッファサイズは、192バイトにして、バッファのデータ数が172バイトになったら一挙にバッファからデータ配列へ読み込みます。
2:M9Nのシリアルバッファサイズを1周期100バイトの3周期分の320バイトに設定して
バッファのデータが300バイトになったら一挙にバッファからデータ配列へ読み込む。
3:IMUは、未だ作ってないので、後日追加記事にしてレポートします。
4:Teensy4の場合は、600MHzと高速なので、SDバッファからの読み込みは、300byteでも1msec以内に読み込み完了しますので、シリアル受信には、ほとんど時間を消費しません。
③SD書き込みコードは、関数化してはダメ
loop内を簡略に見たいので、関数化してみたら、エラー続出で、動作しませんでした。
OPEN CLOSEは、serupとloop内で時間管理が分かる場所で、使わないと関数に埋め込むと
時間がばらついたりしますので、SD書き込みは、本文のloop内に書き込むことが重要です。
●模式図
良い例と悪い例です。
●ソースコードは、GISTにおいてあります。
https://gist.github.com/dj1711572002/39dbf6dd2c986a45bcab27feae4cb407