Arduinoで自作するタコメーター CD50
バイクに乗っているとタコメーターが欲しくなってくるものです。
自分のバイクにも以前は付いていたのですが、一つは安物の不良品?で動かず、もう一つは半年足らずで壊れてしまいました。(レース用のデジタルタコメーターだったからもろいのはしょうがないか)
やはり安物は良くないのか、しかしタケガワやらデイトナやらのメーカーでタコメーターを買おうとすると、高い!10000~15000円位
機械式(ケーブルで動くやつ)は5000円くらいで買えるのですが、これをCDやらモンキーのカブ系エンジンにつけるとなると、それ専用のアダプターを買わないといけない、するとそれが15000円とかする訳で……結局費用がかさむわけです。
それならば、自作するしかない!!
この頃は休日とくにすることもなし、いい暇つぶしになりそうです。
どこにでも先人はいるもので、こちらのサイト様を参考にさせて頂きました。
そんでもって完成したのがコチラ!!
前付けてたタコメーターもこのくらいの数値だったと思うので
表示も大体あってそうです(大体!)
動画もあります
サイズがやけにでかいのは、自分のはんだ付けが下手なせいで、回路は至ってシンプルです^^;
そして、やっていることは思いのほか単純
1.CDIから出ている青/黄の線を分岐する
ここにフライホイールからの点火信号がきています。
テスターで測ってみると0.3~0.5Vくらいの電圧がきていると思います
2.上の信号(青/黄)をマイコンで読取り、回転数を割り出す
パルス信号は電圧が低いので、自分は1kΩの抵抗を間にかませ、電圧を上げて信号を 強化しています。もう少し大きい抵抗でもいいかもしれません。
回転数の計算は、参考記事のブログを参考に
・250msの間に何回信号がきているか測る
・その信号をrpmに変換(今回は 250×4×60 でrpmになる)
3.計算結果を出力
4桁の7セグLEDに出力します。1の位は邪魔なのでとばします。
と、これだけです。
しかし!!描いてみれば簡単ですが実行するのが大変で……自分が困った所の参考サイトを貼っておきます
・まずArduinoに書き込んだプログラムを外部のマイコンに書き込まなくてはならない
(Arduinoを直接バイクにくっつける訳にもいかないでしょ)
(ちなみにArduinoとはAVRマイコンに手軽にプログラムを書き込んで遊ぶことのできるものです)
電子工作といえば、ハードルが高いイメージですが、Arduinoなら初心者向けのサイトが充実しており、電子工作入門に向いているのではないでしょうか。
・4桁の7セグLEDの処理!
ダイナミック点灯??なにそれ??の自分にはかなりの難関でした。
丁寧に解説して下さっているサイトがあって本当に助かりました
・ソースコードの作成
これも大変、色々と検索しまくりました。検索すれば答えが出るのが幸いです。
さいごに
自分なりのソースコードです。その筋の人から見ればまだまだ改良の余地がありそうですが
さて、ブログでよく見るソースコードだけ色分けされてるやつは表示方法がよくわからなかったので、見にくいですがそのまんまコピペです。
//arduino 4,5,6,7,8,9,10,11 8桁
//OSL4056 1,2,3,4,5,7,10,11
// uint8_t( 1バイトの符号なし整数)
uint8_t anode = {4,5,6,7,8,9,10,11};
//アノード(+)に接続するピン番号
uint8_t cathode = {14,15,16,17};
// OSL 12, 9, 8, 6
//カソード(ー)に接続するピン番号
uint8_t num = sizeof(anode) / sizeof(anode[0]);
//アノード配列の要素数を求める。
uint8_t num2 = sizeof(cathode) / sizeof(cathode[0]);
//カソード配列の要素数を求める。
byte d = 0;
byte ichi = 0;
byte to = 0;
byte hilyaku = 0;
byte sen = 0;
uint8_t digits[] = {
0b11101011, // 0bをつけると2進数
// 11,10,7,5,4,3,2,1 逆から出力 数値に対応する値
0b00101000, // 1
0b10110011, // 2
0b10111010, // 3
0b01111000, // 4
0b11011010, // 5
0b11011011, // 6
0b11101000, // 7
0b11111011, // 8
0b11111010, // 9
};
byte pulse = 3;
int rpm = 0;
int taco = 0;
int count = 0;
int old_count = 0;
unsigned long ti = 0;
void setup() {
pinMode(pulse, INPUT) ;
pinMode(led, OUTPUT) ;
for (int i = 0; i < num; i++) {
pinMode(anode[i], OUTPUT); // anodeを出力モードに設定する
}
for (int i = 0; i < num2; i++) {
pinMode(cathode[i], OUTPUT); // cathodeを出力モードに設定する
digitalWrite(cathode[i], HIGH);
}
}
void loop() {
taco = 0;
ti = millis() ;
while (millis() - ti <= 250) //250msの間ループ
{
digitalWrite(cathode[3], LOW);
display_number(ichi);
allOff();
digitalWrite(cathode[3], HIGH);
/////////////////////////////////
digitalWrite(cathode[2], LOW);
display_number(to);
allOff();
digitalWrite(cathode[2], HIGH);
/////////////////////////////////_
digitalWrite(cathode[1], LOW);
display_number(hilyaku);
allOff();
digitalWrite(cathode[1], HIGH);
//////////////////////////////////
digitalWrite(cathode[0], LOW);
display_number(sen);
allOff();
digitalWrite(cathode[0], HIGH);
///////////////////////////////////
count = digitalRead(pulse);
if (count == HIGH && old_count == LOW) {
taco++;
// digitalWrite(led, HIGH);
}
old_count = count;
}
// Serial.println(taco);
rpm = taco * 240;
// Serial.println(rpm);
////////////////////////////////////////////ここから出力
ichi = (rpm / 10 ) % 10; //桁分離
to = (rpm / 100 ) % 10;
hilyaku = (rpm / 1000 ) % 10;
sen = (rpm / 10000 ) % 10;
}
void display_number (int n) {
for (int i = 0; i < num; i++) {
digitalWrite(anode[i], digits[n] & (1 << i) ? HIGH : LOW);
}
}
void allOff(){ //すべてオフにすることで移行時に伴うゴーストの削除
for (int i = 0; i < num; i++) {
digitalWrite(anode[i],LOW);
}
}
つぎは油温計を作りたいですね。
PS.動かないと嘆いていた安物のタコメーター、どうやら自分の配線ミスだったらしく、きちんと動作してくれました。ごめんね!!!
(黄/黒の配線に接続してたみたいです。そりゃ動かんよ……)