自転車用アナログ指針式スピードメーター
~マイコンを使ってクルマの電気式速度計をチャリに搭載~

自転車にカッコいい針のメーターを!
小学生時代からの空想が、
mbedマイコンでついに実現!

こちらは「交差コイル式」のクルマ用電気式メーターとマイコンを使用するバージョンです。
バイクの初期型電気式メーター(高角可動コイル式)を転用するだけの簡単(マイコンなし)なバージョンはこちら

ご紹介する回路には、
以下の3つの特徴があります。

アナログ指針表示 電気式(マイコン制御) 乾電池・速度センサ不要

まずは実験成功時の動画をご覧ください!

<目次>

<ハードとソフト>

本回路は、ダイナモから電源をとるのみならず、ダイナモの出力周波数は速度に比例することに着目しダイナモを速度センサとしても用いています。そのため、センサ不要、乾電池不要となりまります。
マイコンでは、周波数カウンタおよび交差コイルメータードライブの処理をしています。周波数を計測し、計測結果を車の交差コイルメーターを駆動するためのsin・cos成分に分解し、PWMで駆動します。

動画撮影時から改良を重ね、ドライブ回路や電源回路は大幅に変更されています。

回路図 ソフトウエアは「直接計数式(ゲート方式)周波数カウンタ」を用いています。ゲート方式とは、一定時間に何回パルスが来るか数える方式です。(ちなみに周期をタイマーで測るモードはレシプロカル方式と言います。)
LPC1114にはFPU(浮動小数点演算ユニット)が搭載されていないため、レシプロカル方式のアルゴリズムでは処理が追いつかず実用になりませんでした。
また、FPUがないため当然sin・cosの計算等にも時間がかかる為、フラグを立てて計算をする時と測定に専念する時に処理を分けています。
開発環境には mbed を使用しC言語で記述しています。

//LPC1114 チャリスピードメーター //ゲート方式 一定間隔内のゼロクロスを数える
//平均化処理しないと針がふらつく

#include "mbed.h"
#define f_rad_keisuu 0.03 //パルス周波数からradへの変換係数 ハブダイナモ = 0.03? ブロックダイナモ=0.004
#define kakudo_max 4.4 //メーターの最大振り角度(rad)
#define sampling_time 0.1 //サンプリング周期(秒) 0.05だと処理落ち、0.15だとガクガク 0.1がいい感じ


//内蔵LED
DigitalOut myled1(dp14);
DigitalOut myled2(dp28);

//信号入力
InterruptIn speed_sensor(dp26); //スピードセンサーからの車速パルス入力

//制御出力
PwmOut sin_coil(dp1); //sinコイル出力
PwmOut cos_coil(dp2); //cosコイル出力

//サンプリングゲートタイマー設定
Ticker sampling; //サンプリング用タイマ割り込み

//グローバル変数
int pulse; //パルスをカウントする変数
int gate; //ゲートフラグ(0:計算中 1:計測中 2:計測準備完了)
int data[10] = {0,0,0,0,0,0,0,0,0,0};

//角度を受け取って交差コイルにPWM出力する関数。pwmoutは0~1のため、0.5を中心にする。
void kousa_coil_output(float kakudo)
{
 myled2 = 0;
 if(0 <= kakudo && kakudo <= kakudo_max) //範囲内ならば交差コイルドライブ
 {
   sin_coil = 0.5 + 0.5 * sin(kakudo);
   cos_coil = 0.5 + 0.5 * cos(kakudo);
 }
 else //範囲外ならオーバーロードランプを付けメーターの更新をしない
 {
   myled2 = 1;
 }
 gate = 2; //振れ角の計算まで終わったら次の測定準備完了
}

void pulse_counter(void)
{
 pulse ++; //一回呼ばれる毎にパルス数変数をカウントアップするだけ
}


//パルス数からスピードを計算する関数(タイマ割り込みで呼ばれる)
void speed_calc(void)
{
 static float output = 0.0;

 if(gate == 1){
   gate = 0;
   data[0] = data[1];
   data[1] = data[2];
   data[2] = data[3];
   data[3] = data[4];
   data[4] = data[5];
   data[5] = data[6];
   data[6] = data[7];
   data[7] = data[8];
   data[8] = data[9];
   data[9] = pulse;

   output = (data[0]+data[1]+data[2]+data[3]+data[4]+data[5]+data[6]+data[7]+data[8]+data[9]) * f_rad_keisuu;
   //10回平均後に係数をかけてメーターの振れ角度に計算

   kousa_coil_output(output);//交差コイルドライブ関数に角度(rad)を出力
 }
 if(gate == 2)
 {
   pulse = 0;
   gate = 1;
 }
}

int main() {
 sin_coil.period_us(1000.0);//pwmは1kHz
 cos_coil.period_us(1000.0);//pwmは1kHz
 speed_sensor.fall(&pulse_counter);//立下りピン変化割り込みでパルスカウンターを呼ぶように設定
 sampling.attach(&speed_calc , sampling_time);//タイマ割り込みで速度計算関数を呼ぶ
 myled1 = 1;//ledをつけて準備完了
 gate = 2;//測定準備モードにセット
 while(1) {
 }
}

<スピードセンサー不要の原理>

このメーターの特徴の一つとしてライト用ダイナモをセンサー代わりに使用することで、スピードセンサーが不要であることがあります。その原理を説明します。
図に、ライト用ダイナモの原理図を示します。
ライト用ダイナモの模式図 自転車のライト用ダイナモは、発電機の世界では「永久磁石式交流同期発電機」という仲間に入ります。これは、永久磁石をコイルの前で回転させて、コイルに誘導起電力を起こす発電機です。コイルの前をS極、N極が交互に通過しますが、整流子を持たないため出力は交流となります。
自転車のスピードを上げるとライトが明るくなることから発電機の回転数と電圧に関係があることは誰でも体験的に知っていますが、実は発電周波数と回転数にも関係があります。自転車ダイナモでは、電気角(発電出力の角周波数)と、機械角(ダイナモを機械的に回転させる角速度、つまり回転数)が一対一に対応、つまり同期します。それがライト用ダイナモが「同期発電機」の仲間に入る理由です。
つまりライト用ダイナモの発電周波数を測定すると自転車のスピードが分かる!ということになります。
マイコンで発電機の周波数を測定し、交差コイルメーターをドライブすることでスピードメーターを実現しています。わかりやすく言ってしまえば、周波数カウンタの表示部をアナログ指針表示にしただけです。

メーターの電源もライト用ダイナモからとりますので乾電池も不要です。ダイナモが電源兼スピードセンサーとなっています。
ダイナモからの電源の取り出しについては、こちらをご覧ください。
※リンク先の自転車発電の記事では倍電圧整流を使用していますが、鉛蓄電池を併用しない場合は高速走行時にOPアンプが過電圧で壊れますので、冒頭の動画のようにブリッジ整流としてください。

<交差コイルメーターの入手及び使用法>

メーターの例
さて、このメーターはどちらのメーターが使用できるでしょうか?

交差コイルメーターの例
まず、交差コイルメーターとは直角に交差するコイルの中に針を取り付けた棒磁石を設置したメーターで、車・バイクの電気式メーターに使われています。
それぞれのコイルに指針を振らせたい角度の正弦・余弦の電流を流すと、振らせたい角度方向の磁界ベクトルが発生します。その時、3平方の定理とsin^2+cos^2=1より、合成磁界ベクトルの大きさは変わらないため、棒磁石を目的の方向を向かせることができます。
構造としては2相の交流同期電動機と同じ形をしていますので、どちらかというとメーターというよりモーターの仲間に入ります。

メーターの例
これを入手するにはオークションもしくは自動車リサイクル工場で車の電気式メーターを買えばよいのですが、いくつか注意点があります。電気子でも必ずしも使用できるわけではありません

まず、アラゴの円盤を用いた使えない機械式スピードメーターは、写真のように後ろに大きなカップリングが出ていますので見間違えることはないと思いますが、ステッピングモーターを使用したメーターはパッと見では区別がつかないため間違て購入してしまったら残念でしたということになります。
ステッピングモーターを避けるには、90年代後半~00年代前半のメーターを狙うと良いでしょう。

ちなみに写真のタコメーターは交差コイル式でした。

最も紛らわしいタイプは2相ステッピングモーターを使用したタイプで、交差コイルと同じ4端子のアクチュエーターのため区別がつきません。外車のメーターに使われていることがあります。私はアウディのメーターで見事に外れを引いてしまいました・・・
2相ステッピングモーターは構造が交差コイルですので、間違って買ってしまった場合はギアを取っ払って針をモーターに直接取り付ける改造を施すしかありません。
※3相以上のステッピングモーター方式メーターを間違って買ってしまった場合は、マイコンに制御プログラムを書けば降らせることはできます。ステッピングモーターのドライブプログラムについては、ロボット工作系サイトが詳しいのでそちらを検索してください。

タウンエースノアの交差コイル
参考として、選択肢は狭まりますが確実性を求めるならば、「”針のシャフトを取り囲むようにきれいに並んだ4本のネジ”でメーターアクチュエータに配線されている、見るからに交差コイル」というのを選べば外れが少なくなります。
針を取り囲んでいてもきれいに並んでいないネジや3本の場合は車速信号や電源を内部基板へ送って駆動するタイプですので、ステッピングを引く可能性が多少ありますが、年代的に古いものならばほぼ大丈夫でしょう。
例えば写真のタウンエースノアのメーターはタコメータ・スピードメーターともに交差コイルです。

<車のメーターに元々ついている制御回路を使わない理由>

車のメーターを触ったことがある方でしたら、車のメーターは車速パルス信号を得て交差コイルをドライブしているため、ダイナモ出力を波形整形してそのまま入れればよいのでは?という疑問がわくと思います。私も初めはその方法を考えました。しかし、実験してみるとどうも都合が悪いのです。
以上のような理由から、マイコンで制御プログラムを書いてしまったほうが楽という結論に至りました。