- ベストアンサー
機器のI/OをArduinoでSDに記録したい
- Arduinoを使用して、機器のI/OをSDカードに記録する方法について説明します。
- Arduinoデーターロガーのスケッチを作成し、SDカードに2番ピンの状態を記録する方法を紹介します。
- SDライブラリを使用してArduinoでデーターロギングを行う方法を解説します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
なんか切れているようですが…。 > val=digitalRead(2); ここで黄色になり >下に >stry '¥'in program >と、でます。 ですかね。(半角円マークはうまく表示できない場合があるので全角にしてみた) >明記はしていませんがインデントを「全角空白」であらわしていますので、そのままコピペするとエラーになりますよ。 と回答した通り、その場所に全角空白があるから…でしょう。 「全て選択」してコピー、テキストエディタに貼り付けてみてください。 # できれば全角空白を記号などで表示できるテキストエディタで。(秀丸など。) # 有名どころのテキストエディタなら記号で表示するオプションがあるでしょう。 テキストエディタの置換機能で全角空白を半角空白2つに置換するか…単純に削除した後で再度arduinoのスケッチにペーストしてください。 # ペーストした後で[ツール][自動整形]すればインデントとか調整してくれるでしょう。 あとは…Valとvalか混じっていたり、ブロック区切りがおかしくなっていたりするようですのでその辺りを見直してくださいな。
その他の回答 (3)
- Wr5
- ベストアンサー率53% (2173/4061)
>早速、貼り付けてみましたが検証するとエラーに… どんなエラーだったのか掲示されないと……。 ちなみに、明記はしていませんがインデントを「全角空白」であらわしていますので、そのままコピペするとエラーになりますよ。
お礼
記入せず、申し訳ありません。 val=digitalRead(2); ここで黄色になり 下に stry`in program と、でます。 自分でも確認していますが、現在発見できていません。 ありがとうございました。
- Wr5
- ベストアンサー率53% (2173/4061)
void loop() { // 2番ピンの状態を取得 Val=digitalRead(2); // 前回と変化があったら… if(old_val != Val) { // ファイルを開く File dataFile = SD.open("datalog.txt", FILE_WRITE); if(dataFile) { // 書き込む dataFile.println(Val); dataFile.close(); } else { // ファイルが開けなかったらエラーを出力 Serial.println(F("error opening datalog.txt")); } // シリアルポートにも出力 Serial.println(Val); old_val = Val; } } こんなところでしょうかね? 時刻は書き出していないので追加してくださいな。 ファイルオープンはsetup()でやって、dataFile.close()でクローズしない。 という方法もアリかも知れません。 # dataFileはグローバル変数にする必要があります。 ただし、その場合は途中でSDカード抜いた場合の動作が保証できませんけど。 # dataFile.flush()するとある程度は書き込まれると思われます。が、完全には保証できない点は変わらないかと。
お礼
ありがとうございます! 早速、貼り付けてみましたが検証するとエラーに… もう少し、勉強してみます。 #include <SD.h> // この値は使用しているシールドや基板に合わせて変更すること。たとえば、 // イーサーネットシールドは 4 // Adafruit のSDシールドは 10 // Sparkfun のSDシールドは 8 const int chipSelect = 4; const int BUTTON=2; int val=0; int old_val=0; int state=0; void setup() { // シリアルポート初期化 Serial.begin(9600); while (!Serial) { ; // USBケーブルが接続されるのを待つ。この待ちループは Leonardo のみ必要。 pinMode(2,INPUT) ; //スイッチに接続ピンをデジタル入力に設定 } Serial.print(F("Initializing SD card...")); // SSピン(Unoは10番、Megaは53番)は使わない場合でも出力にする必要があります。 // そうしないと、SPIがスレーブモードに移行し、SDライブラリが動作しなくなります。 pinMode(SS, OUTPUT); // SDライブラリを初期化 if (!SD.begin(chipSelect)) { Serial.println(F("Card failed, or not present")); } Serial.println(F("ok.")); // 日付と時刻を返す関数を登録 SdFile::dateTimeCallback( &dateTime ); } void loop(){ { // 2番ピンの状態を取得 val=digitalRead(2); // 前回と変化があったら… if(old_val != Val) { // ファイルを開く File dataFile = SD.open("datalog.txt", FILE_WRITE); if(dataFile) { // 書き込む dataFile.println(Val); dataFile.close(); } else { // ファイルが開けなかったらエラーを出力 Serial.println(F("error opening datalog.txt")); } // シリアルポートにも出力 Serial.println(Val); old_val = Val; } } void dateTime(uint16_t* date, uint16_t* time) { uint16_t year = 2014; uint8_t month = 7, day = 22, hour = 9, minute = 0, second = 0; // GPSやRTCから日付と時間を取得 // FAT_DATEマクロでフィールドを埋めて日付を返す *date = FAT_DATE(year, month, day); // FAT_TIMEマクロでフィールドを埋めて時間を返す *time = FAT_TIME(hour, minute, second); } }
- Wr5
- ベストアンサー率53% (2173/4061)
試していませんが…… >2番ピンに変化が有った時(ONかOFF)に時間と2番ピンの状態を 変化があった時…ではないですし、loop()実行中はガンガン書き出すスケッチになっています。 # ついでに時間は書き出されません。 loop()の中で前回通った時の2番ピンの状態を保持する変数を用意する必要があるでしょう。 その上で、現在の値と変更があったかを確認し、現在の値を書き出す。 ということになるかと。 2番ピンに接続されているモノによってはチャタリング対策とか必要です。 時間も書き出すとしたら、起動時にPCから日時データを受け取れるようにする必要があるかと思われます。 # SDカード使える状態だとどこからか時刻を取ってこれるのなら別ですが。 # SDカード使ったコトありませんのでPC側から取得…でしょうね……。
お礼
早速のご回答ありがとうございます。 おっしゃる通り、あれこれ試していたら大量の0と1が・・・・ Val=digitalRead(2); if((val==HIGH)&&(old_val==LOW)){ state=1-state; こんな文章にすれば良いのでしょうか。 入力していますが、検証するとエラーに。 もっと勉強します。 ありがとうございました。
お礼
ありがとうございます。 いろいろいじっていたら動きました。 勉強させて戴き、ありがとうございました。