使用したパーツ
- GPS受信モジュール:秋月電子通商GPS受信機キット
- 4桁 7セグメントLED:0.56インチ 4桁チューブLEDセグメントモジュール
表示部幅50mmの大ぶりのLED表示器
使用したライブラリ
使用したマイコン
今回はRaspberry Pi Picoを使いましたが、ESP32やSTM32等、MicroPythonが使えるマイコンであればどれでもできます。使用するマイコンに合わせてGPIOピンを変更してください。
スピードの求め方
ハバーサイン(Haversine)の公式を用いて、2地点の緯度・経度と移動時間から対地速度(km/h)を計算します。
GPSモジュールから、1秒間隔で現時点の緯度・経度が得られるので、これを利用します。
Pythonコード
import math
import time
from tm1637 import TM1637
from machine import Pin
from machine import UART
from micropyGPS import MicropyGPS
import gc
gps = MicropyGPS(local_offset=9, location_formatting='dd')
uart = UART(0, 9600) # TX:GP0, RX:GP1
tmClkPin = Pin(2, Pin.IN)
tmDioPin = Pin(3, Pin.IN)
tm = TM1637(clk=tmClkPin, dio=tmDioPin)
def calculate_ground_speed(lat1, lon1, lat2, lon2, seconds=1):
"""
2地点の緯度・経度と移動時間から対地速度(km/h)を計算する関数
(Haversineの公式を使用)
"""
# 地球の平均半径 (km)
R = 6371.008
# 緯度・経度をラジアンに変換
lat1_rad = math.radians(lat1)
lon1_rad = math.radians(lon1)
lat2_rad = math.radians(lat2)
lon2_rad = math.radians(lon2)
# 緯度・経度の差分
dlat = lat2_rad - lat1_rad
dlon = lon2_rad - lon1_rad
# Haversineの公式による2点間の球面距離計算
a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance_km = R * c
# 秒速(km/s)を時速(km/h)に変換 (1h = 3600s)
ground_speed_kmh = (distance_km / seconds) * 3600
return ground_speed_kmh
prev_lat, prev_lon = 0, 0
tm.write(tm.encode_string('----'))
smoother = SmootherMicro(window_size=3)
def received_message(uart):
global prev_lat, prev_lon
received_txt = uart.read()
if received_txt is None: return
#print(received_txt)
for char in received_txt:
state = gps.update(chr(char))
if state == 'GPGGA':
dt, ts = gps.date, gps.timestamp
yy = "" if dt[2]==0 else "19" if dt[2]>79 else "20"
print('------------------')
print(f'{yy}{dt[2]:02d}/{dt[1]:02d}/{dt[0]:02d} {ts[0]:02d}:{ts[1]:02d}:{ts[2]:04.1f}')
print(f'latitude: {gps.latitude[0]}, longitude: {gps.longitude[0]}, altitude: {gps.altitude}')
print("satellites_used:", gps.satellites_used)
if prev_lat != 0 and prev_lon != 0:
spd = calculate_ground_speed(prev_lat, prev_lon, gps.latitude[0], gps.longitude[0])
spd = min(999.0, spd)
print(spd, 'km/h')
tm.number(int(spd))
else:
tm.write(tm.encode_string('----'))
prev_lat, prev_lon = gps.latitude[0], gps.longitude[0]
uart.irq(handler=received_message, trigger=UART.IRQ_RXIDLE)
while True:
time.sleep(10)
gc.collect()
実行ログ
屋内で実行:緯度・経度が暴れる(測位誤差)ため、速度>0のときがあります
(小数点以下は伏せています)
------------------
2026/07/19 16:40:22.0
latitude: 35.9999 , longitude: 139.9999 , altitude: 21.9
satellites_used: [24, 10, 23, 25]
0.0 km/h
------------------
2026/07/19 16:40:23.0
latitude: 35.9999 , longitude: 139.999 , altitude: 21.9
satellites_used: [24, 10, 23, 25]
1.36707 km/h
------------------
2026/07/19 16:40:24.0
latitude: 35.9999 , longitude: 139.999 , altitude: 21.9
satellites_used: [24, 10, 23, 25]
1.36707 km/h
------------------
2026/07/19 16:40:25.0
latitude: 35.9999 , longitude: 139.999 , altitude: 21.9
satellites_used: [24, 10, 23, 25]
0.0 km/h
------------------
2026/07/19 16:40:26.0
latitude: 35.9999 , longitude: 139.999 , altitude: 21.9
satellites_used: [24, 10, 23, 25]
0.0 km/h
------------------
2026/07/19 16:40:27.0
latitude: 35.9999 , longitude: 139.999 , altitude: 21.9
satellites_used: [24, 10, 23, 25]
2.73414 km/h
GPSのデータシートによると『測位確度 : 2m』となっていますが、屋内での利用では精度が落ちるのだと思います。
DOTは使えない
今回使用した4桁7セグLEDは、各桁にDOT(DP)が見えるが、光りません。
左から2桁目のDOTを指定すると、中央のコロン(:)が光ります。
使われているLED表示器は5643BGという型番です。データシートを見ると、各桁のDOTと中央のコロンは、すべて 5番ピンに接続されている回路図となっています。
この結線が本当ならDOTも光るハズです。
(TM1637を通さずに)直接ピンに信号を与えて確認したが、どの桁のDOTも光らなかった(DIG2のDPのみ中央のコロンが光った)。上記回路図の誤りではないか、と推測します。
DOTが使えるLED表示器
一例だが、次の商品が見つかった。
- 0.56インチ:★0.56★7セグLED表示器 [5x61] 5461BG
- 普通サイズ:4桁緑色7セグメントLED表示器(コロン付) (時刻用のコロンも独立して点灯できる)
使われているLED表示器は5643BGという型番です。
Pinoutが同じ5461BGに入れ替えてみました。
問題なく、各桁のDOTを独立して光らせることができました。
tm1637.pyライブラリを使って浮動小数点を表示する場合は、前述のコードを少し変更する必要があります。
- from tm1637 import TM1637
+ from tm1637 import TM1637Decimal
- tm = TM1637(clk=tmClkPin, dio=tmDioPin)
+ tm = TM1637Decimal(clk=tmClkPin, dio=tmDioPin)
- tm.number(int(spd))
+ tm.write(tm.encode_string(f'{spd:5.1f}'))
自動車なら少数点以下は不要でしょうが、徒歩やマラソンなら知りたいかも??
追伸;
この装置を屋外に持ち出して歩いてみましたが、晴天昼間だとLEDが光っているのか見づらく視認性が低いです。
以上


