マイコンカーラリーで1mS毎のデータ記録が出来るシリアルポート経由データロガーUART2MMCがとりあえず動作するようになりました。
マイコンカーラリーでは速度を上げるために走行中のデータを記録出来るSDカードが大活躍しています。
拡張基板のSDコネクタの信号をR8CPUに接続してプログラムでデータをSDカードに記録できるようにしていますが、走行制御の合間に記録するため10mS毎に64文字の記録しか出来ない仕様となっています。
走行制御は1mS毎の割り込みと1mS前後で繰り返す制御ループでおこなっているので走行中に起こっていることを正確に把握するためには1mS 以下のサイクルでデータの記録をおこなうのが理想です。
このボードは1mS毎にシリアル送信されたデータをSD/MMCメモリに書き込んで記録する目的で作成しました。
UART2MMCの機能一覧
1.消費電流 typ 50mA
2.通信速度 1250000bps MAX
3.LFN(長いファイル名)対応
4.ファイルオープンで自動的に新しいファイル名を作成
5.対応フォーマット FAT16, FAT32, exFAT
6.USBシリアルプログラム書き込み可能
ロータリーディップSWの選択
0: R8Cへのプログラム書き込み
1:1250000bpsデータロガー
2:USBからのコマンドでSD/MMCへアクセス
データロガー書き込みサンプル関数
/************************************************************************ printdata : シリアルポートにデータ出力 iRunReady: 出力準備フラグ iRunReady!=0で ファイルオープンコマンドを出力し、データ出力の用意をする uRunReady==0 になったらファイルクローズコマンドを出力し初期状態に戻る iRunFlag: データ出力フラグ データ出力(書き込み)の用意が出来ているときにiRunFlag != 0でデータ出力 使い方の例 1.走行開始SWの押し下げで iRunReady を1にする 2.走行開始のタイミングで iRunFlag を1にする 3.停止時にiRunReadyとiRunFlag を0にする ※UART2MMCボードを使ったシリアルポート経由データログの注意 最初に "open filename\n"コマンドを送りファイルをオープンし、 最後に"close \n"コマンドでファイルを閉じる。 ファイル名が重複する場合は最後の3文字を数値に変更してユニークなファイル名で ファイルが作られるので最後の3文字は"000"にしておくと良い。 ファイル名は拡張子を含めて最大255文字までなのでコンパイル日時もファイル名に 付加することを推奨 通信速度に最大の1250000bpsを使った場合 1mSで送ることの出来る(保存できる)文字数は約100文字以内 printf()関数を使うと時間がかかるので下の例のように個別のデータ出力関数を使う。 (uart0.cのデータ出力関数一覧) 文字列出力 : void uart0_puts(char far *s); 2桁16進出力 : void uart0_puthxb(unsigned char n); 4桁16進出力 : void uart0_puthxw(unsigned short n); 8桁16進出力 : void uart0_puthxl(unsigned long n); int 10進出力 : void uart0_putint(int n); unsigned int 10進出力 : void uart0_putuint(unsigned int n); long 10進出力 : void mon_putlong(long n); unsigned long 10進出力 : void mon_putulong(unsigned long n); 数値を文字列に変換して uart0から出力 u : 出力する数値, len : 文字列の長さ, radix : 基数 2,10,16等 void uart0ltoa(unsigned long u, int len, int radix); CRLF出力 : void uart0_putcrlf(void); ************************************************************************/ void printdata(void) { static int state=0; switch( state ){ case 0: // アイドル状態 if( iRunReady ) state = 10; break; case 10: // ファイルオープンコマンド出力 if( iRunReady == 0 ){ state = 0; break; } /* ファイル名にコンパイル日時を追加、 ファイル名重複時に最後の数字'000'は自動的に置き換えられる */ uart0_puts( "open "); uart0_putfn("KENKO_H28_LogData_" ); uart0_putfn(C_DATE); uart0_putfn("_"); uart0_putfn(C_TIME); uart0_putfn( "_000.csv\r\n" ); state = 20; errorct = 0; break; case 20: // ヘッダー出力 uart0_puts( "wr Time,Pattern,Sensor,Center,Analog,Angle," "SB_M,Encoder,LF_M,RF_M,LR_M,RR_M,saka\r\n" ); state = 30; break; case 30: // iRunReadyが1の間データ出力を繰り返す if( !iRunReady ){ state = 40; break; } if( iRunFlag ){ /*************** データ出力例 **********************/ uart0_puts("wr "); // 書き込みコマンド(必須) uart0_putuint(uRunTime); uart0_putch(','); // mS単位の走行時間 uart0_putint(pattern); uart0_putch(','); // パターン番号 uart0_puthxb(sensor_inp()); uart0_putch(','); // デジタルセンサ(4bit) uart0_putint(center_inp()); uart0_putch(','); // デジタルセンサ(中心) uart0_putint(getAnalogSensor()); uart0_putch(','); // アナログセンサ uart0_putint(getServoAngle()); uart0_putch(','); // ボリューム(ステアリング角度) uart0_putint(ServoPwm_Buff); uart0_putch(','); // サーボPWM uart0_putint(iEncoder); uart0_putch(','); // ロータリエンコーダ uart0_putint(motorLF); uart0_putch(','); // 左前モータ uart0_putint(motorRF); uart0_putch(','); // 右前モータ uart0_putint(motorLR); uart0_putch(','); // 左後モータ uart0_putint(motorRR); uart0_putch(','); // 右後モータ uart0_putint(ad4); // 坂センサー uart0_putcrlf(); /*************** データ出力:ここまで ******************************/ } break; case 40: printf("close\n"); state = 0; break; default: state = 0; break; } }