今回は大量のデータをマイコンに入れたい場合の手法をご紹介します。
マイコンでロギングする際にSDカードに情報を書き込む方法がよく使われています。
一方で座標情報やパラメータ設定など大量のデータを読み込みたい場合にも
SDカードを用いて実現することができます。
特にプロジェクションボールで用いる描画の座標情報や
ロボット等のパラメータ情報をそのままマイコンの変数に
1つ1つ代入するのは面倒なのでこの方法がおススメです。
SDカードを使えばPC上で入力したエクセルCSVファイルを
読み込んで簡単に変数に代入することが可能となります。
SDカードに書き込むロギングの情報がネット上にいくらでもありますが
逆のSDカードから読み込むという方法の情報が非常に少ないです。
C言語でファイル操作をしたことがあれば、fgetcやfgets関数はお馴染みなはず。
ここで問題なのはマイクロチップから配布されているSD書き込みMDDFileSystem
スタックにはfread関数と同じ動きをするFSfread関数、fwrite関数と同じ動きをする
FSfwrite関数はありますが、fgetcやfgets関数がないということです。
PICで使用可能なfgetcやfgets関数を作ったのでご紹介します。
既に先人で公開されている方http://www.freeml.com/bl/9519095/55560/がおられましたが、
一部コードが化けていたため、再度作りなおしてみました。
以下に参考としてソースを記述。
char *FSfgets(volatile char *s,volatile int n,FSFILE * stream){
マイコンでロギングする際にSDカードに情報を書き込む方法がよく使われています。
一方で座標情報やパラメータ設定など大量のデータを読み込みたい場合にも
SDカードを用いて実現することができます。
特にプロジェクションボールで用いる描画の座標情報や
ロボット等のパラメータ情報をそのままマイコンの変数に
1つ1つ代入するのは面倒なのでこの方法がおススメです。
SDカードを使えばPC上で入力したエクセルCSVファイルを
読み込んで簡単に変数に代入することが可能となります。
SDカードに書き込むロギングの情報がネット上にいくらでもありますが
逆のSDカードから読み込むという方法の情報が非常に少ないです。
C言語でファイル操作をしたことがあれば、fgetcやfgets関数はお馴染みなはず。
ここで問題なのはマイクロチップから配布されているSD書き込みMDDFileSystem
スタックにはfread関数と同じ動きをするFSfread関数、fwrite関数と同じ動きをする
FSfwrite関数はありますが、fgetcやfgets関数がないということです。
PICで使用可能なfgetcやfgets関数を作ったのでご紹介します。
既に先人で公開されている方http://www.freeml.com/bl/9519095/55560/がおられましたが、
一部コードが化けていたため、再度作りなおしてみました。
以下に参考としてソースを記述。
char *FSfgets(volatile char *s,volatile int n,FSFILE * stream){
char *const head = s; // 先頭ポインタを保存
for (; n > 1; n--) {
int c =FSfgetc(stream); // 1文字入力
if(c == EOF)break;
*s = c; // 配列に代入
s++; // sを進める
if (c == '\n')break;
}
// 入力失敗のとき
if (s == head || FSerror()){
return NULL;
}
*s = NULL;
return head;
//return s;
}
int FSfgetc(FSFILE *fp){
volatile char c;
if(FSfread(&c,1,1,fp) != 1){
//while(1);
}
return (int)c;
}
コメントアウト部分は必要に応じて変更してください。
また、実際に以下のCSVデータをintで読み込む関数をご紹介します。
データ例
1,23,34
1,24,25
1,25,26
・
・
・
以下に参考としてソースを記述。
void setpath(struct path* pR, char* str) {
int i = 0;
// 最初の","を探す
char* pStr = strtok(&str[0], "\",\"");
while (pStr) {
switch (i) {
case 0:
pR->pow = atoi(pStr);
break;
case 1:
pR->x = atoi(pStr);
break;
case 2:
pR->y = atoi(pStr);
break;
default:
break;
}
i++;
// ","を探す
pStr = strtok(NULL, "\",\"");
if (pStr == NULL ) {
// ","がない場合、最後の"を探す
pStr = strtok(NULL, "\"\n");
}
}
}
これらの関数を組み合わせることでCSVファイルからマイコン上の変数に代入できます。
ただ、最後に残る問題はマイコンのRAM容量が限られるため、
dsPIC33Fでもint型400個以上の変数だと容量オーバーしてコンパイルできないんです...
そこをどう回避するかが今後の課題かもしれません。
【ソースに間違い等あっても何もCrescentは責任は負いません】
for (; n > 1; n--) {
int c =FSfgetc(stream); // 1文字入力
if(c == EOF)break;
*s = c; // 配列に代入
s++; // sを進める
if (c == '\n')break;
}
// 入力失敗のとき
if (s == head || FSerror()){
return NULL;
}
*s = NULL;
return head;
//return s;
}
int FSfgetc(FSFILE *fp){
volatile char c;
if(FSfread(&c,1,1,fp) != 1){
//while(1);
}
return (int)c;
}
コメントアウト部分は必要に応じて変更してください。
また、実際に以下のCSVデータをintで読み込む関数をご紹介します。
データ例
1,23,34
1,24,25
1,25,26
・
・
・
以下に参考としてソースを記述。
void setpath(struct path* pR, char* str) {
int i = 0;
// 最初の","を探す
char* pStr = strtok(&str[0], "\",\"");
while (pStr) {
switch (i) {
case 0:
pR->pow = atoi(pStr);
break;
case 1:
pR->x = atoi(pStr);
break;
case 2:
pR->y = atoi(pStr);
break;
default:
break;
}
i++;
// ","を探す
pStr = strtok(NULL, "\",\"");
if (pStr == NULL ) {
// ","がない場合、最後の"を探す
pStr = strtok(NULL, "\"\n");
}
}
}
これらの関数を組み合わせることでCSVファイルからマイコン上の変数に代入できます。
ただ、最後に残る問題はマイコンのRAM容量が限られるため、
dsPIC33Fでもint型400個以上の変数だと容量オーバーしてコンパイルできないんです...
そこをどう回避するかが今後の課題かもしれません。
【ソースに間違い等あっても何もCrescentは責任は負いません】