概要

GR-PEACHでSDカードにCSV形式でデータを保存して、Excelでグラフ表示してみます。リアルタイムクロック(RTC)やアナログ値を読み込むなど、少し応用的な使い方をします。


準備

GR-PEACH、USBケーブル(マイクロBタイプ)の他にマイクロSD、照度センサー(NJL7502L)、10kΩ抵抗を準備します。照度センサーがなくても途中までお試しできます。


時計を作る

以下のサンプルを実行してみてください。1秒ごとに緑LEDが光ります。


#include <arduino.h>
#include <RTC.h>
 
RTC rtc;
static int year, mon, day, hour, min, sec, week;
  
void setup() {
    pinMode(PIN_LED_GREEN, OUTPUT);
    digitalWrite(PIN_LED_GREEN, LOW); // LED OFF
    Serial.begin(9600);
      
    year = 2016;
    mon  = 7;
    day  = 23;
    hour = 13;
    min  = 20;
    sec  = 50;
    week = RTC_WEEK_SATURDAY;
      
    rtc.begin();
    rtc.setDateTime(year, mon, day, hour, min, sec, week);
  
}
  
void loop() {
    static int sec_old = sec;
    rtc.getDateTime(year, mon, day, hour, min, sec, week);
     
    if((sec - sec_old) % 60){
        digitalWrite(PIN_LED_GREEN, HIGH); // blink LED
        delay(5);
        digitalWrite(PIN_LED_GREEN, LOW);
        Serial.print(year); Serial.print("/");
        Serial.print(mon);  Serial.print("/");
        Serial.print(day);  Serial.print(" ");
        Serial.print(hour); Serial.print(":");
        Serial.print(min);  Serial.print(":");
        Serial.print(sec);
        Serial.println();
        sec_old = sec;
    }
}



またTeratermやCooltermなどのシリアルモニターで見ると以下のように一秒ごとに時間が表示されます。この時間はSDにデータを保存するときのタイムスタンプや、データロガーとしての時間軸に使用されます。


SDに保存してグラフを作る

次はSDカードにデータを保存するサンプルです。GR-PEACHの裏面にあるSDソケットにマイクロSDを差し込んでスケッチを実行してみてください。緑LEDが点滅したらSDカードへの書き込みが成功しています。赤LEDが光った場合はSDカードへのアクセスが失敗していますので、きちんとマイクロSDが挿入されているか確認してください。


#include <arduino.h>
#include <RTC.h>
#include <SD.h>
 
RTC rtc;
static int year, mon, day, hour, min, sec, week;
void sd_timestamp(uint16_t* date, uint16_t* time);
 
 
void setup() {
    pinMode(PIN_LED_GREEN, OUTPUT);
    pinMode(PIN_LED_RED, OUTPUT);
    digitalWrite(PIN_LED_GREEN, LOW);
    digitalWrite(PIN_LED_RED, LOW);
     
    Serial.begin(9600);
    if (!SD.begin()) {
        digitalWrite(PIN_LED_RED, HIGH); // error
        while(1);
    }
     
    SdFile::dateTimeCallback( &sd_timestamp );
     
    year = 2016;
    mon  = 7;
    day  = 23;
    hour = 13;
    min  = 20;
    sec  = 50;
    week = RTC_WEEK_SATURDAY;
     
    rtc.begin();
    rtc.setDateTime(year, mon, day, hour, min, sec, week);
 
}
 
void loop() {
    static int deg = 0;
    File file = SD.open("data.csv", FILE_WRITE);
    if (file) {
        digitalWrite(PIN_LED_GREEN, HIGH);
        rtc.getDateTime(year, mon, day, hour, min, sec, week);
        // date
        file.print(year);   file.print("/");
        file.print(mon);    file.print("/");
        file.print(day);
        file.print(",");
        // time
        file.print(hour);   file.print(":");
        file.print(min);    file.print(":");
        file.print(sec);
        file.print(",");
        // data
        file.print(sin(deg * PI / 180.0));
        file.print(",");
        file.print(cos(deg * PI / 180.0));
        file.println();
        file.close();
        deg+=5;
        digitalWrite(PIN_LED_GREEN, LOW);
    }
     
    delay(500);
}
 
void sd_timestamp(uint16_t* date, uint16_t* time)
{
    *date = FAT_DATE(year, mon, day);
    *time = FAT_TIME(hour, min, sec);
}

適当なタイミングでSDカードを抜いて、PCで保存結果を見てみます。SDの中に以下のファイルができていると思います。

DATA.CSVをExcel等の表計算ソフトで開いてみましょう。

グラフ化すると以下のようにSinとCosの波形が表示されます。


照度センサーのロガーを作る(準備中)

最後は照度を測り、SDにデータを保存するサンプルです。上記のサンプルから変更しているのはsinとcosのデータではなく、A0ピンのアナログ値をanalogRead(A0)で読みSDに保存しているところです。また、サンプルの違いが分かるようにSDにアクセスするときのLEDは青色にしています。

以下のように照度センサーと抵抗を接続して、サンプルを実行してみましょう。


#include <arduino.h>
#include <RTC.h>
#include <SD.h>

RTC rtc;
static int year, mon, day, hour, min, sec, week;
void sd_timestamp(uint16_t* date, uint16_t* time);
  
  
void setup() {
    pinMode(PIN_LED_BLUE, OUTPUT);
    pinMode(PIN_LED_RED, OUTPUT);
    digitalWrite(PIN_LED_BLUE, LOW);
    digitalWrite(PIN_LED_RED, LOW);
      
    Serial.begin(9600);
    if (!SD.begin()) {
        digitalWrite(PIN_LED_RED, HIGH); // error
        while(1);
    }
      
    SdFile::dateTimeCallback( &sd_timestamp );
      
    year = 2016;
    mon  = 7;
    day  = 28;
    hour = 23;
    min  = 55;
    sec  = 50;
    week = RTC_WEEK_THURSDAY;
      
    rtc.begin();
    rtc.setDateTime(year, mon, day, hour, min, sec, week);
  
}
  
void loop() {
    File file = SD.open("data.csv", FILE_WRITE);
    if (file) {
        digitalWrite(PIN_LED_BLUE, HIGH);
        rtc.getDateTime(year, mon, day, hour, min, sec, week);
        // date
        file.print(year);   file.print("/");
        file.print(mon);    file.print("/");
        file.print(day);
        file.print(",");
        // time
        file.print(hour);   file.print(":");
        file.print(min);    file.print(":");
        file.print(sec);
        file.print(",");
        // data
        file.print(analogRead(A0));
        file.println();
        file.close();
        digitalWrite(PIN_LED_BLUE, LOW);
    }
      
    delay(500);
}
  
void sd_timestamp(uint16_t* date, uint16_t* time)
{
    *date = FAT_DATE(year, mon, day);
    *time = FAT_TIME(hour, min, sec);
}

グラフ化すると照度に応じて数値が変化しているのが分かります。例えばグラフが下がっているところは暗いことを示しています。なお、このサンプルでの数値は単位Luxで表したものではありません。測る環境、例えば屋内か屋外かに応じて抵抗値を変え、照度センサーの仕様から算出する必要があります。是非トライしてください。