現在鋭意制作中のM5 core2で貸出管理をするシステム、その名も「KASHIDASHI」ですが、
貸出のデータはSDカード内にCSV形式で保存・読み出しをするようにしています。
youtube.com
C言語ならfscanfが使えるので、CSV形式のデータを読み出すのはそこまで大変じゃないでしょうが、
Arduino言語だとそんな便利なものはありません。
そこで今回は、M5Stack(Core2)でArduino言語を使って、CSV形式のデータを要素ごとに読み出す方法についてまとめていこうと思います!
データの形
今回扱うデータの形は以下の通りです。
ちなみに、行と列の関係は以下の通りです
0行・列 | 2列 | 3列 |
1行 | - | - |
2行 | - | - |
プログラム
M5 core2用に組みましたが、コアとなる部分は純粋なArduino言語で作りました。
#include "M5Core2.h" void setup() { M5.begin(); //もろもろ初期化する if (!SD.begin()) // SDカードと通信できるか確認 { M5.Lcd.println("no sdcard"); //通信できなければエラーを表示 while (1) ; } File fp = SD.open("/test.csv", FILE_WRITE); //テスト用のファイルを新規作成する fp.println("characters,figures,booleans"); //ヘッダーを入力 fp.println("abcdef,12345,1"); //値を','で区切って入力 fp.println("ghijkl,67890,0"); fp.println("mnopqr,12345,1"); fp.close(); //ファイルを閉じる char characters[100][10]; //要素記憶用の配列を作成 int figures[100]; bool booleans[100]; int row; File f = SD.open("/test.csv", FILE_READ); String line; //行を一時的に記憶する変数 int row_inheader = 0; //ヘッダーも含めた行数を記憶する変数 while (f.available()) //データが有ればループ { char ch = f.read(); //データを1byteずつ読み取り line += String(ch); // 1byteずつ繋げていく if (ch == '\n') //'\n'が読み込まれた所で一旦読み取りをやめる { M5.Lcd.print(line); //行全体を画面に表示 line.trim(); //行に含まれる不要な空白を取り除く int column = 0; //行に含まれる要素番号カウントする変数 int num_end = 0; //要素の終わりの列番号を記憶する変数 int num_start = 0; //要素の始まりの列番号を記憶する変数 if (0 < row_inheader) //ヘッダーを読み込まないように除外する { while (num_end != -1) //範囲内に','がなくなるまで繰り返し { num_end = line.indexOf(',', num_start); // num_strから','がないか確認。あれば列番号をnum_endに記憶 // M5.Lcd.print('[' + String(num_end) + ']');//正しく認識できているか確認用 String part = line.substring(num_start, num_end); //','で区切られた要素を行から切り出す // M5.Lcd.print('(' + part + ')');//正しく認識できているか確認用 if (column == 0) //行の最初の要素 { part.toCharArray(characters[row_inheader - 1], num_end + 1 - num_start); //配列の"ヘッダーを除いた行数"番目にデータをchar型に変換して代入 } else if (column == 1) //行の2番目の要素 { figures[row_inheader - 1] = part.toInt(); //配列の"ヘッダーを除いた行数"番目にデータをint型に変換して代入 } else if (column == 2) //行の3番目の要素 { booleans[row_inheader - 1] = boolean(part.toInt()); //配列の"ヘッダーを除いた行数"番目にデータをbool型に変換して代入 } num_start = num_end + 1; //','分で1を足して、次の要素を区切る','を探し始めるスタート地点を代入 column++; //要素数に1を加算 } } line = "\0"; //変数を初期化 row_inheader++; //行数に1を加算 } row = row_inheader - 1; //ヘッダーを除いた行数をrowに代入 } f.close(); //ファイルを閉じる M5.Lcd.print('\n'); //改行 for (int i = 0; i < row; i++) //整理したデータを'/'で区切って表示 { M5.Lcd.println(String(characters[i]) + '/' + String(figures[i]) + '/' + String(booleans[i])); } } void loop() { }
実行結果
こんな感じで表示されます。
まとめ
ということで、いい感じに読めました。
ちなみに、最初は以下のようなライブラリーを使用してデータを読んでいたのですが、読んだデータがバグるときがちょこちょこあり、どうせならということで作ってみることにしました。
github.com
データ管理は面倒くさいですね☆
以上、終わり!