自転車用インホイールサイクルコンピュータの製作


最近、夜自転車に乗る事が増えたので安全確保のためにLEDを付けていますが、せっかくなので少し変わった事をしてみようと思いサイクルコンピュータを作ってみました。

原理

ホイールの回転に合わせて一定の位置でLEDを点灯させることで残像を使って文字にします。

構造

ホイール側には、7個のLED、MCとセンサーを組み込んだプリント基板を電池と一緒に取り付けています。
フレーム側には、タイミング用のセンサーを反応させるための磁石が付いています。
センサーは単純なリードスイッチです。

回路

LED1個当たりの電流がだいたい5〜10mAになるよな適当な制限抵抗を計算した後に、点灯比率30%とした時の消費電流の平均値は10*7*0.3=21mAになります。
MCの消費電流3mAを加算しても合計約25mAなので単4電池3本にしました。アルカリ乾電池(900mAh)で36時間は使えそうな感じです。
最高60km/hでも処理できる条件で設計しました。24インチの自転車なのでホイール1周は1756mmです。
回転速度は60000m/3600s/1.756m=約10回転/秒の速さで回転するので、1度当たりの処理時間は100ms/360=約300μsecです。
最初は内部クロックの4MHzにしようかと思いましたが、300μsec間隔で処理しながら他の処理も必要なので、余裕を見て手持ちの16MHzのセラロックを使いました。
300μsecの時間でのクロック数は、300/(1/16)=4800となり、割り込み処理内で500クロックを消費したとしても90%はメイン処理で使えます。
これでまず問題は無いはずです。

ソフトウェア

開発言語はC言語を使って組みました。
書き込み装置は、秋月電子で売っているPICライターです。(筆者は地方なので全部品を秋月電子で買いました。)
おおまかな構成は次のようになっています。

項目 処理内容
1.初期化 ・MCの信号の入出力方向や内部のタイマーを設定します。
・測定スピードや距離が記憶されるメモリーをゼロにします。
・割り込み処理ができるように設定します。
2.測長 走行距離を積算するために、1回転毎に1756mmずつ加算してゆきます。
しかしこのままmm単位で加算していくと、1km進んだだけで100万mmとなってしまうため、1000mmを超えたら、メートル管理の別に用意したメモリーに1を加算し、mmで演算しているメモリーから1000を引きます。
このように処理することでmm単位で誤差が発生しない積算ができます。
3.誤カウント防止 1回転で信号が1回ONするのが理想ですが、センサーがリードスイッチなのでONしたとき接点が機械的に振動します。
すると高速で何回かON/OFFを繰り返した状態となる(チャタリング)ので1回信号が入ってから50msec間は信号を受け付けないような処理を入れます。
4.時間計測 ・速度算出用の1secの基準時間を計測します。
・MCの動作を停止させて消費電流を抑えるために、動いたか止まっているのかを2秒間監視します。
・誤カウント防止用のチャタリング除去の50msecを計測します。
・ホイール1回転の時間計測をします。
・1列ずつ表示するための時間を計測します。
5.LED出力 1文字の構成は、縦7ドット、横5ドットとし、最大13文字をホイールの120°の範囲で収める設計にしました。
横は5ドットですが文字間の2ドットを加算して、7*13=91の全7×91ドットのビットマップと考えました。(メモリーは91Byte使用)
センサーが磁石の前を通過し信号を検出した直後に、1回転に要した時間の1/3回転の時間を91で割り、算出した時間間隔で表示メモリーの内容に従いLEDを1列ずつ点灯していきます。
磁石の位置がチェーンステーに近いので通過を検出した直後のLEDの位置は路面に近いので、表示を上に持ってくるために、算出した時間間隔を用いて210°分の遅延時間を設けた後に表示を開始します。
1回転の時間算出を回転ごとに計算すると計算結果が微妙に異なるため、遅延時間に誤差が生じ文字が左右にぶれて見えます。
表示ぶれを抑制するために、1回転に要した時間の算出は5回分の測定値の移動平均値を採用しています。
このメーターは進行方向に向かって左側から読み取れる仕様にしましたので、見る側からのホイールの回転方向は左回転となるので、最後の文字の一番右端の列から表示してゆきます。
算出した時間間隔が約15km/hを下回ったときは、綺麗に表示されないので全消灯状態にします。
6.キャラクタジェネレータ
エクセルを使ってひとつずつ表示に必要な文字を作ります。
縦の7個を2進数のデータとしてプログラミングします。
(最初の列は、1000010で10進数では66です。)
21の行がホイールの外周側のLEDに相当します。
後に出てくるキャラクターコードが、この7*5のひとかたまりのデータを示しています。
7.速度算出 1秒ごとに移動したメートル数を6回記録します。その6回を全て加算して60倍すれば1時間に移動した距離つまり時速になります。
問題無いのですが60倍しているためxx.xxKM/Hと表示すると、小数点第2桁目は必ず0になります。
精度は落ちますが、5回記録し72倍しても360(1時間の1/10の時間)になるのでこれだと0以外の値も取るためもっともらしくなるのでこっちを選んでいます。
8.最大速度算出 前回の速度と比較して最大値を保存しているだけです。
9.平均速度算出 1分ごとに走行距離を経過した時間(分)で割って1分当りの走行mを算出し結果を6倍することで時速を算出します。
10.文字列変換 内部のデータは2進数で処理しているので、そのまま表示はできません。そこで文字コード(キャラクターコード)に変換します。
11.ビットマップへのデータの転送 変換したキャラクターコードが示すキャラクタージェネレータのデータをビットマップメモリーへ転送します。
この転送をビットマップデータの右端から始めると、右から左に文字が現れたように見えます。
最下位の1列目の91点に転送すると、下から上に文字が現れたように見えます。
12.表示シーケンス制御 速度・最高速度・平均速度・走行距離とデータ転送を順番に切り替えて表示全体を処理します。
13.動作停止検出 2秒間ホイールが回転していなければ、MCの動作を止めてスリープ(OFFに近い)状態にして電池寿命を延ばします。

これらの処理を次のタイミングで実行します。

・1の処理は最初の1回だけ実行します。
・2,3は回転センサーが反応した時に実行します。
・4は10msec毎に実行します。
・5は数百μsec〜数msec毎に実行します。
・6はデータだけなので参照されるだけです。
・7,8,9は1sec毎に実行します。
・10,11,12,は数百msec毎に実行します。
・13は常時実行します。