Arduino GPSデータロガー:リアルタイム飛行追跡、最高高度・速度監視
必要な部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino UNO | 1 | |
| ジャンパーワイヤー(バスバー、ジャンパーリードセット) | 1 | |
| Arduino プロトシールド | 1 | |
| 1.8インチ TFT SPI LCDスクリーン(MicroSDソケット付き) | 1 | SDカードスロット付きなら他のものでも可 |
| u-blox GPS NEO-6M | 1 |
必要な工具と機器
- はんだごて(汎用)
- 無鉛はんだ線
- ワイヤーストリッパー&カッター(18-10 AWG / 0.75-4mm²対応)
プロジェクト概要
はじめに
私は航空模型を趣味としており、自機の速度と高度を知りたいと考えていました。しかし、市販のGPSデータロガーは非常に高価です。
そこで、50ユーロ以下のコストでArduinoベースのGPSデータロガーを自作することにしました。
最初のプロトタイプは、Arduino Uno R3、SainSmart ST7735スクリーン(内蔵SDカード)、NEO 6M V2 GPSモジュールで構成しています。
第2弾では、Arduino Nano、SSD1306 OLEDスクリーン、同GPSモジュール、マイクロSDカードを使用し、ケース込みで約40グラム、サイズ50×30×22mmに収め、中型機への搭載を容易にする予定です(現在部品到着待ち)。
テスト
車内でArduinoの画面を撮影するのは容易ではありませんでしたが、動画で結果を確認できます。
次回は、より小型・軽量化した新プロトタイプをラジコン飛行機でテストする予定です。乞うご期待!
ソースコード
GPSデータロガー(SDカード保存なし版)
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define cs 10
#define dc 9
#define rst 8
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
#define OLED_RESET 5
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
int x = 80, xh = 80;
int maxhigh = 0;
int maxspeed = 0, speed1 = 0;
int high1 = 0;
void setup() {
Serial.begin(9600);
ss.begin(GPSBaud);
tft.initR(INITR_GREENTAB);
tft.fillScreen(ST7735_BLACK);
tft.setCursor(5, 58);
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("initialisation");
}
void loop() {
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
while (ss.available() > 0) {
gps.encode(ss.read());
if (gps.location.isUpdated()) {
drawFrame();
displayLocation();
displayDateTime();
displayAltitude();
displaySpeed();
displaySatellites();
smartDelay(400);
}
}
}
void smartDelay(unsigned long ms) {
unsigned long start = millis();
do {
while (ss.available()) gps.encode(ss.read());
} while (millis() - start < ms);
}
void drawFrame() {
// 画面枠線の描画(省略:元コード参照)
}
void displayLocation() {
tft.setCursor(5, 44);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Latitude :");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.location.lat(), 6);
tft.setCursor(5, 58);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Longitude :");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.location.lng(), 6);
}
void displayDateTime() {
tft.setCursor(5, 7);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("date : ");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.date.day()); tft.print(" ");
tft.print(gps.date.month()); tft.print(" ");
tft.print(gps.date.year());
tft.setCursor(5, 20);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("time : ");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.time.hour() + 1); tft.print(" ");
tft.print(gps.time.minute()); tft.print(" ");
tft.print(gps.time.second()); tft.print(" ");
}
void displayAltitude() {
tft.setCursor(5, 80);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Alt m :");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.altitude.meters(), 0);
tft.setCursor(5, 95);
updateMaxAltitude();
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Hmax :");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(maxhigh);
drawAltitudeGraph();
}
void displaySpeed() {
tft.setCursor(5, 115);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Speed: ");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.speed.kmph(), 0);
tft.setCursor(5, 130);
updateMaxSpeed();
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Vmax: ");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(maxspeed);
drawSpeedGraph();
}
void displaySatellites() {
tft.setCursor(5, 147);
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
tft.print("Sats : ");
tft.setTextColor(ST7735_CYAN, ST7735_BLACK);
tft.print(gps.satellites.value());
}
void updateMaxSpeed() {
speed1 = gps.speed.kmph();
if (speed1 > maxspeed) maxspeed = speed1;
}
void updateMaxAltitude() {
high1 = gps.altitude.meters();
if (high1 > maxhigh) maxhigh = high1;
}
void drawSpeedGraph() {
int val = map(gps.speed.kmph(), 0, 150, 137, 110);
x++;
tft.drawPixel(x, val, ST7735_CYAN);
if (x > 123) {
x = 80;
tft.fillRect(82, 110, 43, 30, ST7735_BLACK);
}
}
void drawAltitudeGraph() {
int val = map(gps.altitude.meters(), 0, 1000, 104, 72);
xh++;
tft.drawPixel(xh, val, ST7735_CYAN);
if (xh > 123) {
xh = 80;
tft.fillRect(82, 72, 43, 35, ST7735_BLACK);
}
}
GPSデータロガー(SDカード保存版)
上記コードにSDカードへのデータ書き込み機能を追加した版です。SD.begin(cs_sd)でカードを初期化し、各ループでdonnees.txtに位置、高度、速度、最大値などをカンマ区切りで記録します。
回路図

製造プロセス
- Samsung SAMI、Arduino UNO、Raspberry Piで高速・信頼性の高い火災検知システムを構築
- Arduinoで実現する低コスト・リアルタイム太陽光パネル監視システム
- Arduinoで作る高精度エナジーモニター&データロガー – Dr. Wattsonボード活用
- Arduino UNOで作るLCDアニメーション&ゲーム入門
- Arduinoで温湿度ロガーを作る – DHT11とEthernetシールドでSDカード記録
- Arduino UNOで作るシンプル電卓 - シリアルモニターで四則演算
- Arduino UNOとATtiny85で作る携帯型POV(残像)ディスプレイ
- u-blox LEA-6H 02 GPSモジュール: Arduino & Python 統合ガイド
- Arduino Unoと1Sheeldで作る4x4x4 LEDキューブ – インタラクティブLEDプロジェクト
- Python 3からArduino UNOを制御 – シリアル通信でLED点滅デモ
- Arduino NanoとRDA5807Mで作るコンパクトFMラジオ