M5StackでSDカードにCSVデータを作成する
調べてみたのですが、情報がヒットしなかったのでメモとして記事にしておきます。あまり難しくはありませんが、SD.begin()で少し悩みました。
もくじ(Index)M5Stack関連の目次へ戻る
用意するもの
ボタンのイベントを記録するだけなのでM5Stack本体があれば大丈夫です。
サンプルスケッチ
まずはいきなり、サンプルスケッチからです。WiFiに接続しNTPサーバから日付と時刻を取得して、M5Stackのボタンが押下されたときにCSVファイル出力を行うサンプルです。
※ssidとpassは環境に合わせて書き換えてください。
#include <M5Stack.h>
#include <WiFi.h>
#include <time.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXXXXXXXXX";
char pass[] = "XXXXXXXXXXXXXXXXXXXX";
// Time
char ntpServer[] = "ntp.jst.mfeed.ad.jp";
const long gmtOffset_sec = 9 * 3600;
const int daylightOffset_sec = 0;
struct tm timeinfo;
String dateStr;
String timeStr;
File file;
// 保存するファイル名
const char* fname = "/btnevent_log.csv";
// ボタン押下時に記録するイベント名
// CSVファイルは日本語が使えます。
char *eventName[] = { "ボタンA", "ボタンB", "ボタンC" };
void getTimeFromNTP(){
// NTPサーバと時刻を同期
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
while (!getLocalTime(&timeinfo)) {
delay(1000);
}
}
void getTime(){
// 時刻の取得と表示
getLocalTime(&timeinfo);
dateStr = (String)(timeinfo.tm_year + 1900)
+ "/" + (String)(timeinfo.tm_mon + 1)
+ "/" + (String)timeinfo.tm_mday;
timeStr = (String)timeinfo.tm_hour
+ ":" + (String)timeinfo.tm_min
+ ":" + (String)timeinfo.tm_sec;
M5.Lcd.setTextColor(WHITE,BLACK);
M5.Lcd.setCursor(0, 50, 1);
M5.Lcd.println(dateStr + " ");
M5.Lcd.println(timeStr + " ");
}
void writeData(char *paramStr) {
// SDカードへの書き込み処理(ファイル追加モード)
// SD.beginはM5.begin内で処理されているので不要
file = SD.open(fname, FILE_APPEND);
file.println(dateStr + "," + timeStr + "," + paramStr);
file.close();
}
void setup()
{
M5.begin();
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE,BLACK);
M5.Lcd.println("CSV Writer");
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
M5.Lcd.print(".");
}
M5.Lcd.println("\nWiFi connected.");
// timeSet
getTimeFromNTP();
}
void loop()
{
M5.update();
// 時刻表示
getTime();
// カーソル位置の指定
M5.Lcd.setCursor(0, 100, 1);
// ボタンイベント処理
if (M5.BtnA.wasPressed()) {
M5.Lcd.print("Button A Pressed");
writeData(eventName[0]);
}
if (M5.BtnB.wasPressed()) {
M5.Lcd.print("Button B Pressed");
writeData(eventName[1]);
}
if (M5.BtnC.wasPressed()) {
M5.Lcd.print("Button C Pressed");
writeData(eventName[2]);
}
}
サンプルスケッチの補足
SD.beginは不要
ESP32だとSD.begin()が必要なのですが、M5.begin()内で行われているため不要です。
書き込んでいる処理は「writeData()」のみ
WiFiへの接続や日付の加工で色々していますが、SDカードへ書き込んでいる部分は下記のwriteDataのみです。
SD.open(ファイル名, モード)でモードは「FILE_WRITE」(上書き)、「FILE_APPEND」(追加)が指定できます。
void writeData(char *paramStr) {
// SDカードへの書き込み処理(ファイル追加モード)
// SD.beginはM5.begin内で処理されているので不要
file = SD.open(fname, FILE_APPEND);
file.println(dateStr + "," + timeStr + "," + paramStr);
file.close();
}
おわりに
センサー等のデータをかき出す場合はバッファを使う必要もあるかもしれませんが、初心者向けにSDカードへ書き込むという手順を紹介しました。様々なデータロガーとしてもM5StackはLCDと同時に確認できるので便利です。ぜひ使ってみましょう。
はじめまして。
m5stack を使用して、加速度、角速度などのロガーとして使用したいのですが、csvファイルとしてsdカードに書き込むときに、ファイル名の決め方について教えてください。ボタンの押下に応じてそのときの日時をファイル名にするようにプログラムを組みたいのですがなかなかうまくいきません。
何か解決策を教えていただけると助かります。
よろしくお願いいたします。
コメントありがとうございます。
「C言語 日時 ファイル名」で調べると色々でてきますね。これなんかはどうでしょうか?
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14150655064
ご無沙汰しております。サリエリの隣人です。
先日コメントを送りたいと思い送信したつもりだったのですが、表示されていなかったので再度コメントさせて頂きます。連続で投稿してしまっていましたら大変申し訳ございません。
このNTPサーバーからは、ミリ秒は取得できるのでしょうか?それとも秒単位までしか取得できないのでしょうか?
もんごんたさんの知っている範疇で構いませんのでお教えいただけますと大変幸いです。
お手数おかけいたしますが、何卒よろしくお願い致します。
サリエリの隣人 様
すいません。英語交じりでスパムと認識されてしまっていたようです。(;’∀’)
多分tmオブジェクトにミリ秒がないのでNTPサーバからの取得は無理そうです。私の中ではNTPサーバはミリ秒単位の精度で時刻を同期するものという認識なのですが、そこまで精度を求めたことは無いので詳しくは理解していません。
ミリ秒はローカルへ同期した後にローカルから取得するしかないと思います。
早急かつ分かりやすいご回答感謝いたします!
NTPからのミリ秒の取得は難しそうですね…
でもローカルへ同期する別の方法を教えて頂きありがとうございます。
まだまだArduinoやM5Core2への理解がないので頑張って調べてみたいと思います!