Table of Contents
この記事で学習できること
- GPS受信機とSDデータロガーをArduino UNO R3に接続しGPS測位データをSDロガーシールドに保存します。
- 携帯性と操作性を向上するためにGPSシールドを自作します。
(参考) 関連する記事
- [ArduinoにGPS受信機を接続し測位精度を測定しました]でGPS受信機から送信される測位データのフォーマット、測位データを解析するプログラム、測位データの位置精度、GPS受信機の設定方法を説明しています。
- [GPS受信機の測位データを地図に表示しました]で測位データを地図に表示する方法を説明しています。
必要な部品は?
| GPS受信機 | 1個 |
| Arduino UNO R3 | 1個 |
| 10KΩ抵抗 | 1個 |
| ダイオード | 1個 |
| SDデータロガーシールド | 1個 |
GPS受信機をSDデータロガーシールドと接続する回路図(接続図)
- SDデータロガーシールドをArduino UNO R3に接続して、GPS受信機を接続します。
- ArduinoとGPS受信機の通信はSoftware Serialを使用します。Arduinoの通信用ポートは、2Pin(RX)と3Pin(TX)を使います。

GPSシールドの自作
- Arduino UNO用のユニバーサル基板を使ってGPSシールドを作成します。ユニバーサル基板上で配線を半田付けすれば、このシールドをデータロガーシールドの上に差し込めば組み立て完成です。
- ブレッドボードで配線しても動作して測定はできますが、持ち運びする場合は配線が外れたり、電気部品がショートしたりする危険性があります。

- GPSシールドはArduino UNO用のユニバーサル基板に部品を取り付け、配線して作ります。KiCADで回路図を描いて、部品間の距離や完成時の構成をイメージしながらPCBレイアウトをします。
- KiCADは、オープンソースの電気回路設計・基板設計CADです。

- PCBレイアウトが決まれば、それに従って部品と線材を半田付けします。SDデータロガーシールドに差し込み、さらにArduino UNO R3に差し込めば完成です。PCに接続して動作確認します。

(参考) KiCADを使ったPCBレイアウトに関連する記事
スケッチに使用するライブラリの入手先
- スケッチで使用する、RTC(実時間)モジュール用のライブラリ(DS3231.h、DS3231.cpp)は[GitHub – jarzebski/Arduino-DS3231: DS3231 Real-Time-Clock]から取得しインストールしてください。
- Arduno用のDS3231用のライブラリは何種類かが公開されていますが、この記事で使用しているライブラリは上記のライブラりであり、異なるライブラリを使用するとコンパイル時にエラーが発生します。
- GitHubでライブラリをダウンロードする
- 対象ライブラリのGitHubページを開く
- 緑色の Code ボタンをクリック (リストの右上にある[<>Code▼]のボタンです。)
- Download ZIP を選択
- ZIPファイルがPCに保存される
- ※「Source code (zip)」でもOKですが、基本は上の手順で問題ありません。
- Arduino IDEにZIPライブラリをインストールする (Arduino IDE 1.x / 2.x 共通)
- Arduino IDE を起動
- メニューから
- スケッチ → ライブラリをインクルード → .ZIP形式のライブラリをインストール
- 先ほどダウンロードした ZIP ファイルを選択
- IDE が自動的に展開してインストール完了
- インストール確認
- メニューのスケッチ → ライブラリをインクルード
- 一覧の「インストール済み」セクションにライブラリ名が表示されていれば成功
- 注意点(特にGitHub系でよくある)
- ZIPの中にさらにフォルダ階層があるとIDEが認識しないことがある
→ libraryname/libraryname/*.h のように二重構造になっていないか確認 - src フォルダがあるタイプはそのままでOK
- リリースページに「Arduino用に整えたZIP」がある場合はそちらを使うと確実
- ZIPの中にさらにフォルダ階層があるとIDEが認識しないことがある
RTC(実時間)モジュールに時間を書き込む
- SDデータロガーシールドのRTC(実時間)モジュールは初期状態では時刻データを保持していません。時刻データ保持用のバッテリーを挿入して時刻を書き込みます。
////////////////////////////////////////////////////////
// RTC(実時間)モジュールの時間設定を行い、時間を画面へ表示する
////////////////////////////////////////////////////////
//ライブラリインクルード
#include <Wire.h>
#include <DS3231.h>
//実時間モジュール設定
DS3231 clock;
RTCDateTime dt;
//一般変数
int i;
void setup()
{
Serial.begin(9600);
//実時間モジュールの初期化
Serial.println("Initialize RTC module");
// Initialize DS3231
clock.begin();
// スケッチのコンパイル時の時刻をRTCモジュールに書き込む
clock.setDateTime(__DATE__, __TIME__);
dt = clock.getDateTime();
//一般変数の初期化
i=0;
delay(1000);
//シリアルログの最初の行に表示項目を表示する
Serial.print("Count,");
Serial.print("Year,");
Serial.print("Month,");
Serial.print("Day,");
Serial.print("Hour,");
Serial.print("Minuts,");
Serial.println("Second,");
//シリアルログの表示
dt = clock.getDateTime();
Serial.print(i); Serial.print(",");
Serial.print(dt.year); Serial.print(",");
Serial.print(dt.month); Serial.print(",");
Serial.print(dt.day); Serial.print(",");
Serial.print(dt.hour); Serial.print(",");
Serial.print(dt.minute); Serial.print(",");
Serial.println(dt.second);
}
void loop()
{
// loopでは何もしない
}GPS受信機から送信されるデータの記録するスケッチ
- GPS受信機から測位データ(GPGGAセンテンス)を送信させて、SDカードに保存します。
//----------------------------------------------
//https://arduinomakesiteasy.com/
//----------------------------------------------
#include <SoftwareSerial.h>
#include <TimeLib.h>
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <DS3231.h>
//SoftwareSerial
SoftwareSerial myGPSSerial(2,3); //rx=2 tx=3
//RTC(実時間) module
DS3231 clock;
RTCDateTime dt;
//SD module
const int chipSelect = 10; //SDカードCS
File logFile;
char fileName[16];
int fileNum = 0;
//TimeStamp matrix (ファイル作成時のタイムスタンプ)
char timestamp[30];
//Variables
String GPSString;
//----------------------------------------------
//setup()
//----------------------------------------------
void setup(){
Serial.begin(9600); //シリアルモニタの開始
delay(500); //待ち時間 0.5秒
init_RTC(); //RTC初期化
init_GPS(); //GPS初期化
init_SD(); //SDカード初期化
}
//----------------------------------------------
//loop()
//----------------------------------------------
void loop(){
//実時間取得
dt = clock.getDateTime();
// ソフトウェアシリアルのデータは改行まで取り込みSDカードに保存する
if (myGPSSerial.available()){
GPSString = myGPSSerial.readStringUntil('\n');
Serial.println(GPSString.c_str());
logFile = SD.open(fileName, FILE_WRITE);
logFile.write(GPSString.c_str());
logFile.close();
}
// ソフトウェアシリアルのデータがオーバーフローしている場合はメッセージを出す
if (myGPSSerial.overflow()) {
Serial.println("myGPSSerial overflow!");
}
}
//----------------------------------------------
//RTCの初期化
//----------------------------------------------
void init_RTC(void){
Serial.print("RTC Start ---> ");
// Initialize DS3231
clock.begin();
//下記の行をコメントアウトすることでコンパイル時の時刻をRTCモジュールに書き込める
//次にコメントアウトして再度コンパイル実行する
//clock.setDateTime(__DATE__, __TIME__);
Serial.println("Done");
}
//----------------------------------------------
//GPSの初期化
//----------------------------------------------
void init_GPS(void){
Serial.print("GPS Start ---> ");
myGPSSerial.begin(9600); //GPSと通信開始、GPSデフォルトの通信レート9600
//GPSモジュールの設定を行う。
myGPSSerial.print("$PMTK314,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2A\r\n"); //$GGAのみ2秒間隔で送信
//GPSモジュールのの設定後にGPSモジュールから返信があることを確認する
while(!myGPSSerial.available()){
delay(500);
}
//GGPSモジュールからの返信をバッファから除去する
GPSString = myGPSSerial.readStringUntil('\n');
Serial.println("Done");
}
//----------------------------------------------
//SDカード初期化とログファイル作成、タイムスタンプ設定
//----------------------------------------------
void init_SD(void){//SDカード初期化とログファイル作成、タイムスタンプ設定
Serial.print("SD Start ---> ");
while (!SD.begin(chipSelect)) {
Serial.println("Failed during starting");
//won't do anything later
return;
}
Serial.println("Done");
//ファイル作成・更新時のタイムスタンプを記録するスケッチ------------------------------
SdFile::dateTimeCallback(dateTime);
sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n",dt.hour,dt.minute,dt.second,dt.month,dt.day,dt.year-2000);
//------------------------------------------------------------------------------
boolean fileexist = false;
String t;
//既存のファイルのファイル名と重複しなければファイル名とする
while(!fileexist){
t = "GPS";
if (fileNum < 10){
t += "00";
}
else if(fileNum < 100){
t += "0";
}
t += fileNum;
t += ".LOG";
t.toCharArray(fileName, 16);
if(!SD.exists(fileName)) {
fileexist = true;
}
fileNum++;
}
// ログファイルの1行目に”GPS NMEA Data ......”と書き込む
logFile=SD.open(fileName, FILE_WRITE);
logFile.println("GPS NMEA Data ......");
logFile.close();
}
//----------------------------------------------
//call back for file timestamps
//----------------------------------------------
void dateTime(uint16_t *date, uint16_t *time) {
sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n",dt.hour,dt.minute,dt.second,dt.month,dt.day,dt.year-2000);
*date = FAT_DATE(dt.year,dt.month,dt.day); // return date using FAT_DATE macro to format fields
*time = FAT_TIME(dt.hour,dt.minute,dt.second); // return time using FAT_TIME macro to format fields
}
スケッチに使用するライブラリとオーバーフローの警告
● 使用したライブラリと機能
#include <SoftwareSerial.h>
#include <TimeLib.h>
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <DS3231.h>| ライブラリ | 機能 |
| SoftwareSerial.h | GPS受信機とのシリアル通信を行う |
| TimeLib.h | Arduinoのシステム時間を扱う |
| SPI.h | SPI通信を行う (SDカードへの記録のため) |
| SD.h | SDカードへの書き込み |
| Wire.h | I2C通信を行う(RTCモジュールとの通信のため) |
| DS3231.h | RTCモジュールの操作 (使用するライブラリに注意) |
● GPS受信機に設定コマンドを送信し、GPGGAの信号を2秒間隔で出力させます
- GPS受信機からのNMEA信号の種類と出力間隔を設定できます。
- GPS受信機にコマンドを送信して設定を変更する方法を[ArduinoにGPS受信機を接続し測位精度を測定しました]にまとめています。
myGPSSerial.print("$PMTK314,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2A\r\n");● データバッファのオーバーフローに注意
- GPS受信機からは連続でNMEAセンテンスが送信されています。Arduino UNO R3の通信用のバッファは64バイトしかないので、送信データの処理よりも送信データの送信量が多ければバッファがオーバーフローします。オーバーフローをしないように、処理速度を上げる、送信データを減らすなどの工夫が必要になります。
- スケッチはオーバーフローした時に、シリアルモニタに””myGPSSerial overflow!”のメッセージを出力します。
if (myGPSSerial.overflow()) {
Serial.println("myGPSSerial overflow!");
} SDカードに出力されたデータ例
● SDカードにCSV形式で保存されています。
GPS NMEA Data ......
$GPGGA,082212.000,3445.9317,N,13537.2365,E,1,5,4.24,-17.4,M,34.5,M,,*46
$GPGGA,082214.000,3445.9283,N,13537.2564,E,1,6,1.28,-11.2,M,34.5,M,,*41
$GPGGA,082216.000,3445.9324,N,13537.2436,E,1,5,4.24,-16.1,M,34.5,M,,*47
$GPGGA,082218.000,3445.9362,N,13537.2338,E,1,6,1.82,-21.9,M,34.5,M,,*44
$GPGGA,082220.000,3445.9347,N,13537.2458,E,1,5,4.25,-22.4,M,34.5,M,,*4C
$GPGGA,082222.000,3445.9392,N,13537.2390,E,6,0,99.99,-23.9,M,34.5,M,,*78
$GPGGA,082224.000,3445.9409,N,13537.2397,E,6,0,99.99,-23.5,M,34.5,M,,*70
$GPGGA,082226.000,3445.9340,N,13537.2592,E,1,6,1.28,-8.6,M,34.5,M,,*7B
$GPGGA,082228.000,3445.9384,N,13537.2674,E,1,5,4.26,20.5,M,34.5,M,,*6Aまとめ
- GPS受信機からのデータをSDデータロガーシールドに保存する手順の学習ができました。GPS受信機を自作シールドに取り付けることで携帯性が向上しました。
(参考) GPS受信機の設定方法や測位データの扱い方に関連する記事
- [ArduinoにGPS受信機を接続し測位精度を測定しました]でGPS受信機から送信される測位データのフォーマット、測位データを解析するプログラム、測位データの位置精度、GPS受信機の設定方法を説明しています。
- [GPS受信機の測位データを地図に表示しました]で測位データを地図に表示する方法を説明しています。
ご質問、誤植の指摘などありましたら。「問い合わせ 」のページからお願いします。

