2021/05/22
M5Stack Core2とGPSユニットで遊ぶ
今年の1月のブログでM5StickCとGPSユニットの組み合わせで遊んだことをお話ししました。その時はデータが保存できずに、休日散歩の要所要所で携帯カメラで撮影して値を記録していました。格好悪いですね・・。今回はSDカードが装備されているM5Stack Core2とGPSユニットの組み合わせで遊んでみました。作成したArduinoのコードは以下の通りで、前回のM5Stickのものを参考にしました。
#include <M5Core2.h>追記した部分はSDカードの部分で、29行目でSDカードにgps_data.txtというファイルを作り、データを書き込みました。34〜36行目で測定した緯度、経度、高度の数値データを文字列に変換し、38〜47行目で書き込みます。測定周期は10秒にしました。
#include <TinyGPS++.h>
HardwareSerial GPSRaw(2);
TinyGPSPlus gps;
int cnt=0;
File f;
char lat_v[11];
char lng_v[11];
char alt_v[8];
void setup() {
M5.begin();
M5.Lcd.setRotation(3);
GPSRaw.begin(9600, SERIAL_8N1, 33, 32);
}
void loop() {
M5.Lcd.setCursor(0, 0, 2);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.printf("### GPS TEST %d\n", cnt++);
while(GPSRaw.available()>0) {
if(gps.encode(GPSRaw.read())) {
break;
}
}
if(gps.location.isValid()) {
f = SD.open("/gps_data.txt", FILE_APPEND);
M5.Lcd.printf("LAT:%.6f\n", gps.location.lat() );
M5.Lcd.printf("LNG:%.6f\n", gps.location.lng() );
M5.Lcd.printf("ALT:%.2f\n", gps.altitude.meters());
dtostrf(gps.location.lat(), 10, 6, lat_v);
dtostrf(gps.location.lng(), 10, 6, lng_v);
dtostrf(gps.altitude.meters(), 7, 2, alt_v);
String dataString = "";
dataString += String(cnt);
dataString += String(",");
dataString += String(lat_v);
dataString += String(",");
dataString += String(lng_v);
dataString += String(",");
dataString += String(alt_v);
f.println(dataString);
f.close();
} else {
M5.Lcd.printf("INVALID\n");
}
delay(10000);
}
得られた緯度、経度のデータから距離を算出したいと思い、ネットで情報を探していると「ヒュベニ(Hubeny)の公式」というもので算出できることが分かり、Pythonのコードもありましたので、ライブラリ(distance.py)として読み込ませてもらい、緯度、経度から連続する2点間の距離を求め、それらを合計してトータルの移動距離を求めることにしました。コードは以下の通りです。
import folium今回は私の通勤時に計測を行いました。11行目で地図に得られた緯度・経度の位置をプロットしますが、問題なく目的の位置を表していました。移動距離のプロットは以下の通りです。
import pandas as pd
import matplotlib.pyplot as plt
import distance
positions = pd.read_csv('gps_data.csv')
map = folium.Map(location=[35.xxxxxx,135.xxxxxx], zoom_start=16)
for i, r in positions.iterrows():
folium.Marker(location=[r['latitude'], r['longtude']], popup=r['position']).add_to(map)
map.save("map_position.html")
# distance calculation
dst = []
dst_sum = []
dst_sum_temp = 0
for i in range(0, len(positions['position'])-2):
start_point = distance.Coordinate(positions['latitude'][i], positions['longtude'][i], positions['altitude'][i])
end_point = distance.Coordinate(positions['latitude'][i+1], positions['longtude'][i+1], positions['altitude'][i+1])
dst_temp = distance.Coordinate.distance(start_point, end_point)
dst_sum_temp += dst_temp
dst.append(dst_temp)
dst_sum.append(dst_sum_temp)
# Total distance plot
plt.xlabel('Time [*10 sec]')
plt.ylabel('Total distance[m]')
plt.plot(dst_sum)
plt.show()
# Altitude plot
plt.xlabel('Time [*10 sec]')
plt.ylabel('Altitude [m]')
plt.plot(positions['position'], positions['altitude'])
plt.show()

高度のグラフはこんな感じです。

SDカードにGPSのデータを保存できたことで、いろいろ面白いことが分かりました。何かGPSを使ったアイデア(悪い用途ではない)があればボチボチ考えていこうと思います。