LoginSignup
643
416

サイクルコンピューターをガチで作ってみたら、割とできてしまったという話

Last updated at Posted at 2019-04-25

github repository is here
https://github.com/hishizuka/pizero_bikecomputer

日々の細かいアップデートはTwitterStravaで発信しています。

(2023/1/6) HACKADAYで紹介されました。

(2022/12/8) アップデート多数により、記事も更新。走行テストは15,000kmを超えました

(2020/10/4) Maker Faire Tokyo2020に出展いたしました。多くの方にお越しいただき、ありがとうございました。

(2019/12/22)「ロードバイク Advent Calendar 2019」の22日目の投稿として、続編「Raspberry Pi Zero (W, WH)でサイクルコンピューターを作ってみよう」を書きました。詳しい作り方を書いています。

(2019/6/19)すごい反響を頂き、ありがとうございます。どこかのイベントで発表できる機会がないか探しています。また、5月で少し進化し、その成果をMIPカラー反射型液晶モジュールをRaspberry Pi Zeroで使うを公開しましたので、興味がある方は是非お試しください。

はじめに

Raspberry Pi Zero Wで、スポーツ自転車向けにサイクルコンピューターを作ってみました。
(I made a DIY GPS bike computer or cycling computer based on Raspberry Pi Zero W)

title03.png

スポーツ自転車用のANT+センサー、GPS、I2C各種センサーから取得したデータをリアルタイムに表示、記録し、Strava等の記録サイトにアップロードできる形式でログを書き出し・アップロード、といった基本的な流れはできるようになっています。また、地図やコースの表示も可能です。

system-01-202106.png
system-02.png

家の周りを適当に練習するだけではバグが出てこなくなったので、最近はストレステスト的なことに取り組み中です。なるべく距離を伸ばして、いろいろな地形を走って、データを集めています。

今までの最長データは、真夏に東京から日本海(新潟県上越市)まで走った314km(Stravaの走行ログ)になります。
202308_TOJ.png

市販品のGARMIN Edge Explore 2との比較です。記録された値が相応に正確なのと、15時間近く安定稼働しています。
2023_TOJ_compare.png

項目名 Edge Explore 2 Pi Zero Bikecomputer
距離 313.7 km 314.3 km
仕事量 3,889 kJ 3,926 kJ
実走行時間 (※1) 12時間3分 (※2) 12時間4分
獲得標高 (※3) 2,271 m 1,958 m

※1 いわゆる移動時間(moving time)です。休憩込みの所要時間(グロス時間)は15時間かかっています。
※2 Garmin Connectより。
※3 RWGPS地理院標高 - Chrome拡張機能を用いて正確に見積もると1,983 mです。

バッテリーの内装、ケースの作成、細かい機能の作り込み、市販品にはない機能の作成が十分にできておらず、まだ完成には至っていませんが、「意外と作れてしまい、驚き」というのが率直な感想です。
個人がそれぞれの嗜好に合わせてデバイスを作れる時代は、少しずつやってくるのかもしれません。
p2.png

hardware_top.png

なぜ作ろうとしたか

サイクリングという趣味を広く長く愉しむ過程、また、Linuxや多少のプログラミングの経験があるというバックグラウンドが合わさって、この形になりました。

サイクルコンピューターの進化

元々、サイクルコンピューターはモノクロ液晶にスピードや距離、時計を表示するものが大半で、機能が非常にシンプルな分、ボタン電池1個で鬼のように持つというのが特徴でした。

2010年よりちょっと前ぐらいでしょうか、サイクルコンピューターが高度化し始め、「高嶺の花」とも言える憧れのデバイスになります。

センサーがANT+規格により無線化

  • スピード&ケイデンスセンサーを始め、心拍計や、当時少しずつ広まりを見せ始めていたパワーメーターをまとめて扱えるように
  • トレーニングの観点が大幅に増え、データの蓄積や分析ができることから、練習熱心な層に人気が出ました

カラー液晶、バックライト、地図、ルート表示/ナビゲーション

  • 紙の地図やスマホいらずで、昼夜問わず進むべき道がわかるように
  • ブルベ等に参加する長距離ライダーや、ツーリングが好きな層に人気が出ました

いろいろな縁があって、ロードバイクを2006年から愉しんでいますが、パーツの交換はできることを広げるための重要な一要素です。今振り返ると、自分の体に合うサドル、ミドルグレード以上のホイール、地図付きサイクルコンピューターは行動範囲を大いに広げてくれました。

進化はどこへ向かう?

最近のサイクルコンピューター(略してサイコン)はスマホに影響されたのか、すっかりスマホのようになった感があります。

  • ナビ機能
  • Wifi、Bluetooth搭載
  • クラウド連携
  • アプリ連携
  • スマホの通知を表示
  • 同一機種間の連携機能
  • 独自アプリ対応 (GarminのConnect IQ)

処理量や消費電力の増加を受け、チップの高速化やバッテリー容量の大型化が進み、それでも稼働時間が短くなる場合は、画面の表示を切ってバッテリーを長持ちさせるパワーセーブ機能といった本末転倒な機能を持つ機種が登場し始めました。

さすがに、最大手メーカーがリリースした直近の機種では操作性やバッテリーの持ちといった基本的な機能は大幅に改善されています。ですが、新機能の方向性は疑問符を持つようになりました。少し便利になったけどなくても困らない機能が多い、というのが正直なところです。地図搭載ほどのインパクトはここ数年、全く感じなくなりました。

個人的に欲しい機能は別にあって、ツーリングの例を挙げます。

  • 悪天候の時は、雨雲の位置や風向きは常に知りたいので、それを見やすい形で表示してほしい
    • 天気予報は不要で、現在地点周辺における直近の履歴と数時間先までの推移が知りたい
    • 雨雲レーダーと風速の取り込みは達成、あとはUIでどう表現するか
  • 道の駅やコンビニ、見やすい等高線の表示に特化した地図
    • Garminの自作OSM地図でチューニングしきれば、Garminデバイスで一つの完成形を見ることはできるはず
    • 道の駅とコンビニはデータ取得済み、あとはどうハンドリングするか
    • 等高線は地図頼み

自分で作れそうな小型のハードが登場した

Intel Edison

2014年冬に知人の紹介でIntel Edisonに触れる機会がありました。切手サイズと言われた非常にコンパクトなサイズながら、CPUはx86互換、OSはLinux(Yocto Linux)、WifiとBluetoothを積んでいて、IoT時代の小型コンピューターと当時はよく宣伝されていました。

学生時代や仕事の中で、Linuxやプログラミングの経験が多少はあったので、ロードバイクに結びつくもの、すなわちサイクリングコンピューターを勉強がてら作ろうとしました。タッチスクリーン、ANT+、GPSがあれば一通りのことができるデバイスが出来上がります。

しかし、Yocto Linuxはパッケージの追加が容易ではない、システム容量が2GBしかないため空き容量がすぐになくなる、ハードの拡張性も悪い点に苦しめられ、挫折しました。(自分の過去の投稿に跡が残っています)

Raspberry Pi Zero

1年後の2015年冬、Raspberry Pi Zeroが発売され、その小ささからすぐに飛びつきました。Intel Edisonと比べると、OSやパッケージがよく整備され、pHAT等のハードウェアモジュールや、国内外の情報が比較対象にならないほど多いことに当時は少し感動していました。

そんな中、いろいろと弄っていたら、必要な要素を結びつけることができてしまいました。

  • Pythonで使用できるGUIライブラリのPyQt5で、ストップウォッチを作った
  • こちらを参照しました。感謝です。
  • GUIのサイズを調整し、タッチスクリーン(PiTFT 2.4)で全画面表示。ガワだけですが、それっぽく表示。
  • ANT+心拍センサーの値を読めるようにし、ストップウォッチに組み込んだ
    • ANT+スピード、ケイデンス、パワーの読み取りもその後実装
  • GPSやI2Cセンサー(まずは気圧センサー)を繋ぎ、表示できるようにした
  • 記録、書き出し機能をつけた
    • まずは実質XMLな.tcxファイル
    • .tcxファイルはサイズが膨らむので廃止し、標準的に使われているバイナリ形式の.fitファイルに対応

小型コンピュータボード、ディスプレイ、ANT+、GPS、記録と書き出しまで全て結び付けたものを未だに誰も作っていないので、これは自分が作るしか!と思い、道半ばですが今に至りました。まずは基本的な部分をしっかりと作りこみ、その上で欲しい機能の実装や他スポーツへの展開を考える、という段取りで進めています。

類似の作成例としては、古くはBuild a Readable Bicycle Computer、一番近いプロジェクトはOpen Cycling Computer、2021年に彗星の如く出現したX-TRACKあたりです。

Linuxとプログラミングの知識があれば、意外と作れる

当初、この手のものを作るのは、大学の工学科等、それなりのバックグラウンドがないとできないという先入観を持っていました。しかし、Raspberry Pi Zeroを使い始めてからは、Raspberry Piが持つエコシステムを大いに活用し、随分と敷居を下げてもらった印象があります。
Linuxとプログラミングの知識でここまで大体来れてしまったことは自分でも驚きでした。プログラミングとハードを一緒に勉強する形として、本当にありな形だと思っています。

手と頭と脚がバランスよく要りますが、いい感じに趣味が進化したと思っています。

image.png

実装した機能について

ここから細かい話に入ります。

ストップウォッチ機能

一式作ると結構な分量です。

  • ラップ・タイマー
  • オートストップ
  • 最大値・平均値
    • [全体 / ラップ / 直前ラップ] × [心拍 / スピード / ケイデンス / パワー]
  • 積算値
    • [全体 / ラップ / 直前ラップ] × [距離 / 仕事量 / 獲得標高(上昇/下降)]
  • 記録
    • sqlite3で常に記録
    • 中断、電源断を跨いだ再開も可。上記の最大/平均/積算も復元。
  • 書き出し
    • .fit形式
  • 送信(Strava / GarminConnect / Ride with GPS)

各種センサーとの通信

  • ANT+
    • 心拍、スピード、ケイデンス、パワー(キャリブレーションは未対応)、ライト(Bontrager Flare RTのみ対応)、Controls(Garmin Edge Remoteのみ対応)、気温計
    • センサーのスキャン・ペアリング機能
  • GPS
    • 緯度、経度、スピード (ANT+スピードセンサーが使用できない時に代替)
  • 各種センサー
    • 気圧・温度 (高度、獲得標高、斜度を求める)
    • 明るさ (バックライト自動点灯に使用)
    • 加速度 (移動検知)
    • 地磁気 (方位)
    • ジャイロ、湿度、紫外線、ガス(VOC)、いずれも未使用
    • バッテリー残量 (Pi Supply PiJuice HATまたはPiJuice Zeroのみ)

表示機能

地図

  • Tile形式の地図に対応。
    • キャッシュしてオフライン表示可能、またmbtiles形式にも対応。
  • 現在地点、.tcx形式のコースファイルの内容、今まで通ってきた軌跡を表示。
    • また、Ride with GPS等で作成されるデータにあるように、.tcxファイル内にコースポイントが埋め込まれていれば、それも表示し、簡単なナビ機能に。(いわゆるキューシートの表示)
  • 地図やコースの表示の実装は、グラフ表示ライブラリのPyQtGraph上で1から作ってしまったので、かなり苦労しました。。。
    • Y軸(緯度)方向に怪しげな座標変換をして、タイル画像と同じくX軸とY軸を同じ長さにするのがポイントです。
  • map-01

コースプロファイル

  • .tcx形式のルートファイルによるコースプロファイル、現在地点を表示
  • 登り区間を検出する機能もあります。
  • map-02

直近のパワー、心拍のグラフ

  • トレーニングで真面目に使いだすとサボれなくなる嫌な機能です。
    • 赤の折れ線グラフ(左軸)が心拍、青の棒グラフ(右軸)がパワーです。
  • ANT+センサーの複数人ペアリングを実装し、このグラフに表示したら、さらに嫌な機能になりそうな。。。
  • performance_graph-01

別の人のパワー、心拍を表示

  • スキャン機能を用いて、周囲の人を捕まえた順に3つずつ表示。
    • 下記スクリーンショットの中段、下段。上段は自分の値
    • パワーメーターのデータをしばらく取り続けていると、製造元も判定します。(右下329W)
  • image.png
  • 中身はANT+のcontinuous scanモードを使用
    • センサーIDと値がセットで取得可、心拍とパワーだけピックアップ
    • 同時に50センサーぐらいは処理できることは確認済み
  • 2~3名で走っている状態なら、安定して表示可
    • ただ、消費電力が激しいので長時間の使用は不向き
    • 普通に特定のセンサーを追加登録するという形でで2人目、3人目の表示機能の作成を検討中。

ハードウェア構成

現時点での部品の構成は以下です。かかる費用は、ディスプレイ以外の本体やセンサー類が5千〜1万円、ディスプレイが5千〜2万円です。

本体:Raspberry Pi Zero W ($10), Raspberry Pi Zero 2 W

  • 公式サイト
  • 互換品や別のモジュールは数あれど、サイズの小ささ、消費電力小、I/F豊富、wifi&BTあり、SDカード使用可から、これ一択
  • 残念なことにコロナ禍で入手困難になってしまいました。。。
  • 消費電力が大きそうですが、Radxa Zeroでも作れそうです。
  • pizero_2.png

ディスプレイ

屋外でストレスなく使うことを考えるなら、現時点では以下の2択

反射型液晶(カラー)

反射型液晶(モノクロ)

以下、おすすめはしませんが、使用可能です。

TFT液晶系

  • 流通量が多く、手ごろな値段で手に入るため、試しやすいです。
  • 推奨はAdafruit PiTFT 2.4
    • お値段は$35。
    • 横幅がジャスト。ボタンも4つあり、使いやすい。
  • 液晶のサイズが大きくなると、またTFT液晶ではなくIPS液晶になると、消費電力が激増。
  • 晴天下では暗すぎて見えないので(特にサングラス越し)、実用的ではありません。
    • バックライトを最大にせざるを得ないので、消費電力が増加。
    • 「反射型液晶(カラー)」の写真は直射日光に当てるように撮影していますが、TFT液晶だと真っ暗になります。
  • end-01.png

E-ink系

  • PaPiRus ePaper/eInk スクリーンハット

    • お値段は£70.00。
    • こちらも視認性抜群で、低消費電力。電源を落としても表示可。
    • 色数が1色なのと、秒間数フレームの描画程度しかできないことがネック。
    • サイクルコンピューターに使うなら、反射型液晶(モノクロ)の方が適する。間欠動作でよい別の用途で輝くはず。
    • papirus.png (Raspberry Pi 3Aによる試作品です)
  • DFRobot e-ink Display Module for Raspberry Pi 4B/3B+/Zero W

    • お値段は$22.9
    • 性能はPapirusと同じ
    • dfrobot.png (Raspberry Pi 3Aによる試作品です)

USB ANT+ドングル

GPSモジュール

センサー(I2C接続)

  • SparkFun Qwiic Connect SystemまたはAdafruit STTEMA QTによるQwiic接続センサーの対応を進めています。必要なセンサーを直列に繋ぐので、コンパクトな構成になります。
  • 2022/12時点で以下のセンサーに対応しています。
    • 気圧センサーはBMP280/BME280/BMP38X/BMP581/LPS33HW/LPS35HW/MS5637
    • 加速度・ジャイロ・地磁気センサーはLSM303/LSM6DS/LSM9DS1/LIS3MDL/ICM20948/BMX160/ISM330DHCX/MMC5983MA
    • 照度センサーはTCS3472/VCNL4040/TSL25911FN
    • 実験的にUVセンサーLTR390、ガスセンサーSGP40に対応
  • Enviro pHAT(¥2,000)が複数のセンサーを搭載し手頃でおすすめでしたが、廃盤になってしまいました。
    • 気圧、加速度、地磁気、照度を取得
    • waveshareEnvironment Sensor HATが、気圧、9軸IMU(加速度/地磁気/ジャイロ)、照度、UV、ガスと各種センサーあり。
  • I2C接続のボタンは、Button SHIMに対応。
  • バッテリー管理ができる電源ボードのPiJuice、PiJuice Zeroに対応しています。

今後

バッテリー内蔵と防水ケース作成に向け、最適解を検討中です。
今はTopeakのSmartPhone DryBagで代用していますが、これでも十分機能します。

バッテリーは現在モバイルバッテリーを使っていますが、ハブダイナモから半永久的に取得も検討しています。ディスクロード用にハブダイナモ付きのカーボンホイールをのむラボ様に組んでいただきました。

ソフトウェア構成

開発が実機上に閉じないように、クロスプラットフォームのものを念頭に選択しています。

Python (3系)

  • スクリプト言語でコンパイル不要、導入のしやすさ、守備範囲の広さより
  • ANT+の通信は openantforkしたものを使用
    • スキャン機能を追加
  • GPSは、gpsdをデーモンとして動作させ、gps3を用いて取得
  • I2Cは、パラメータの設定に問題なければ提供ライブラリを使用
  • 今回のEnviro pHATの例だとpimoroniが作成されたライブラリ。今後ははAdafruitが提供するCircuitPythonライブラリやSparkFun提供のQwiic用ライブラリを使用する予定。
  • ライブラリ丸投げは厳禁。取得間隔やフィルターの有無の設定は確認必要
  • グラフ描画は pyqtgraphforkしたものを使用
    • コースプロフィールや地図を高速に描画するために一部改変
  • 他は定番もの
    • numpy、sqlite3、標準ライブラリ等
    • Pythonだと処理時間がかかる箇所はCythonとC++の組み合わせでカバー。現在は.fitファイルの書き出しと、反射型液晶(カラー)使用時のディザリング処理が該当。

PyQt

  • クロスプラットフォームのGUIライブラリであるQtのPythonバインディング
    • GUIの画面を定期的に画像に変換しその画像を描画して、非X Window環境でもディスプレイデバイスに表示可能。オリジナルの描画ライブラリを1から作成する必要はなし。
  • 現在はQtWidgetsを使用だが、アニメーション操作が扱えるQMLも検討中
  • 別のGUIライブラリであるkivyも試す予定あり

起動まわり

  • コンソールからSPIを叩いて直接起動 or 起動をsystemdでサービス化
  • PiTFTのみデスクトップアプリという形での起動が可能
    • ただし、起動までの道のりが長すぎる
  • 最終的にはOSをRasbianではなく、組み込み向けLinuxのBuildrootを検討中

今後

何かしら判断してくれるもの

自分の走行データは10年分程度蓄積しているので、自分の考え方を再現させたいと考えています。(データの意味づけをどうするか、というところはありますが)

ツーリングの途中に、目的地までのペースや休憩箇所を、今までの消耗具合と残り行程の負荷で判定するエンジンを作りたいと考えています。

今までの消耗具合はANT+センサーのその日の値と過去一定期間の履歴、残り行程の負荷はコース情報と標高データ、風速データで判定できそうです。休憩箇所はコンビニと道の駅ですね。

雨雲、風速を地図に重ねて描画

まず、地図は任意のラスタータイル地図を描画できます。プリセットでは国土地理院tonerですが、タイルURLがわかれば設定で追加可能です。

雨雲、風速のオーバーレイ表示は実装されていてもいいかと思うのですが、意外とされていないので、実装しました。現時刻のみ表示でき、時系列の表示ができるよう改良中です。

map_overlay_weather_openportguide_de.png

Strava Heatmapを使ったルート検索

すごいことを考えている人が既にいます。
まずはStravaとRide with GPSのHeatmapの表示に対応しました。

map_overlay-strava

リアルタイムアップロード

ThingsBoard.io を用いていわゆるLiveatrack的な機能を実装しました。ブラウザ上に表示されるダッシュボードを通して、第三者がリアルタイムに走行状況を把握できる機能です。具体的には、

  • デバイスから一定間隔でデータをアップロード
    • BTテザリングの間欠動作、またはBLE経由(実装予定)でバッテリー消費を低減
  • 地図に現在位置と走ってきたルートを表示
    • コースを読み込んでいる場合は、走ってきた経路の代わりにコースを表示可
  • 心拍、パワー、距離、気温等の各種数値を表示

thingsboard-01 thingsboard-02

将来的には、ダッシュボードを見ている人と、または複数のデバイス間で協調する機能の実装を考えています。

  • ダッシュボードからのメッセージ送信、位置の指定
  • 複数デバイス間で互いに現在位置を共有
  • エンデューロのレースの例だと
    • 待機メンバーが走者の位置、パワー、心拍をリアルタイムに把握
    • 交代のメッセージ、「OK/NO」ボタン

別スポーツへの展開(パラグライダー)

パラグライダーでも、GPSバリオメーターというGPSと気圧高度計を積んだ小型のロガーが使われています。
サイクルコンピューターと同じく、まずは基本的な動作をしっかりと再現し、市販品にはない機能を作れないかチャレンジしてみたいと考えています。紹介をいただいた人によると、いろいろな情報を組み合わせて飛行中にサーマル(上昇風)の位置を予測をしたいとのこと。

スクリーンショット 2019-04-25 21.42.14.png

追加した項目

  • 上昇速度 (Vertical Speed)
  • 累積標高 (Accumulated Altitude): 自転車とは異なり、上昇分と下降分の総和
  • 滑空比 (Glide Ratio): 1m下降した時に進んだ水平距離。斜度の逆数

構築手順

Raspberry Pi Zero (W, WH)でサイクルコンピューターを作ってみよう

643
416
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
643
416