スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Tag:スポンサー広告 

タコメータ製作 ほぼ完成!

タコメータを製作しようと思ってから、早1年ちょい・・・

この土日、ようやくほぼ完成しました!!
やっぱりオシロで波形が確認出来ると、効率がグンと上がるね!

まず先週の段階で波形が確認出来て、パルス取り込み回路も目処がついたので、この週末はマイコンのプログラムを完成させようと思ってた。
で、いそいそとトライ&エラーを繰り返していたのだが、なぜだかこの週末は頭がキレキレで、試したプログラムがダメでもすぐにアイデアが浮かんできた。

完成が見えてきていたので、「テンションあがってきたwww」状態だったのか?ww

そして土曜日にプログラムが完成、今度は回路図起こして実体配線図を作成し、土日にかけてハンダ付け。

まず回路図。あんまり回路図なんて書かないのでセンスがないが、分かればおk。
2313_tachometer.jpg
ピックアップコイルからのパルスを、フォトカプラ(TLP512)で受けて5Vに変換。
7,500rpmぐらいでピークが15Vぐらいだったので、フォトカプラ内のLEDが壊れないように抵抗を決めた。
ただ、15V~-20Vとマイナス方向にもかなり振れていたので、念のため抵抗の前にダイオードを入れといた。(回路図にはないけど)
あと10kの抵抗は、フォトカプラがオープンコレクタなので単にプルアップ。
従って、パルスが入ってないときは5V、パルス入ったら0V。
そのパルスは、PD6(インプットキャプチャ)にIN。

あとは7セグにつないでるだけ。
4桁をダイナミック点灯で回してるので、2SC1815を4つ。

ピンがちょっと余ってしまったのがもったいないが、仕方ない。

2313_tachometer_haisen.jpg
実体配線図はこんな感じに。緑がジャンパー線。まあ自分が分かれば良いww
実はフォトカプラ前の抵抗を入れ忘れ、若干泣きを見たのは秘密。

次にプログラム。
Tiny2313は8bitのタイマー0と16bitのタイマー1の2つがあるが、
タイマー0は7セグのダイナミック点灯用で、タイマー1がタコメータ用。
タイマー0は1MHzの8分周でオーバーフローさせて、約2msで割り込み。

タイマー1も8分周で、パルスが入ってきたときの割り込みと、オーバーフロー割り込みの2つ。
パルス割り込みは、前のパルスが入ってきた時のカウントと、次にパルスが入ってきた時のカウントの差から計算して、回転数を算出。
オーバーフロー割り込みは、もしパルスが入ってこなかったら「-」と表示させるためのもの。

あとオマケで、電源投入時にCD90と表示させるようにしてみた。
DSC_0211.jpg  DSC_0212.jpg
左は、表示の桁を間違えて左右逆になってしまったもの。
このミス、よくやりますww 右が正解。

そんなところでハンダ付け。これがめんどくさかった。。。。
5時間とか平気でやってたと思う。幸い、配線ミスとかはなかった。
DSC_0214.jpg
んで完成して、1,000rpm(16.67Hz)のパルスを与えてるところ。
こんぐらいの誤差ならなんてことはない。

そして実車での確認。
DSC_0215~01
ちょいと分かりにくいが、1500と表示されている。それっぽいぞ!

あとは配線と、ケースに入れて取り付けるだけ。
それはまだ構想段階www何せこんなトントンで進むと思わなかったからw

それにしても、自分で言うのもなんだが、飽きやすい性格の中よく作ったなぁと思う。
まあ回路設計とかプログラムは、正直動けば良いレベルだが・・・

あとは配線と取り付け方法を考えて、ツーリングに行くぞ!!

※誰も参考にする人いないと思うけど、備忘録も兼ねて続きを読むにプログラムを置いとく。
--------------タコメータプログラム--------------
#include
#include
#include

#define OPC 0b00111001 //オープニングで使うC
#define OPD 0b01011110 //オープニングで使うD
#define OP9 0b01101111 //オープニングで使う9
#define OP0 0b00111111 //オープニングで使う0

/*
マイコン:ATTiny2313
 10がGND、20がVcc
 PD6(ICP)にフォトカプラからパルスIN、立下りで割り込み
 空きピン:PA0,PA1,PD2,PD3,PB7

トランジスタ:2SC1815
 PD0に1桁目、PD1に2桁目、PD4に3桁目、PD5に4桁目のベース(10kΩ抵抗を介して)
 1桁目のコレクタは7セグの6へ、2桁目は8へ、3桁目は9へ、4桁目は12へ
 エミッタはGND

7セグ:OSL40562-LRA カソードコモン Vf=2.1V 20mA MAX
PB0~6にA~Gを接続(1kΩを介して)
PB0:11、PB1:7、PB2:4、PB3:2、PB4:1、PB5:10、PB6:5

*/

volatile unsigned int cnt = 0; //パルスが入ってきたときのカウントと、前に入ったときのカウントの差
volatile unsigned int cnt0 = 0; //前回のカウント
volatile unsigned int cnt1 = 0; //今回のカウント
volatile unsigned int rpm = 0; //回転数
volatile unsigned char ofmae = 0; //オーバーフロー数のカウント
volatile unsigned char nosignal = 0;//オーバーフローが連続2回だった時のフラグ
volatile unsigned char seg[10] = {0b00111111, 0b00000110,
0b01011011, 0b01001111,
0b01100110, 0b01101101,
0b01111101, 0b00100111,
0b01111111, 0b01101111}; //数字のパターン
volatile unsigned char sel; //桁数選択用
volatile unsigned char dig1,dig10,dig100,dig1000; //1~100の位の分解した値用
volatile unsigned char i=0; //ループ用


ISR (TIMER1_CAPT_vect){ //割り込み発生時に呼び出される

cnt1 = ICR1;
ofmae = 0; //信号が入ってきたら、オーバーフローフラグクリア

if(cnt0 == 0){ //もし前のカウントが0だったら、そのままcntに入れる
cnt = cnt1;
}else if(cnt1 cnt = (0xffff - cnt0) + cnt1;
}else{
cnt = cnt1 - cnt0; //今回のカウントの方が多かったら、普通に計算
}

cnt0 = cnt1;

}

ISR(TIMER1_OVF_vect){ //タイマー1がOVFしたら(524ms)

if(ofmae == 1){ //オーバーフローが連続2回目だったら
nosignal = 1; //信号無フラグを1にする
}else{
nosignal = 0; //オーバーフローが初回だったら、信号無フラグは立てない
}

ofmae = 1; //オーバーフローフラグを立てる

}

ISR (TIMER0_OVF_vect){ //0.008*255 = 2.04ms毎に割り込み

i++;

if(i==245){ //約500ms毎に表示更新

if(nosignal == 1){ //信号無フラグが1(=OVFが連続2回)だったら、rpmは0に
rpm = 0;
}else{
rpm = 7500000 / cnt; //計算(60/(cnt*8/1000000)を簡略化
}
i = 0;

}

if(rpm>15000){ //rpmが15000以上はありえないので、rpmは0にする
rpm = 0;
}

dig1 = seg[rpm % 10]; //10で割ったときの余り
dig10 = seg[(rpm / 10) % 10]; //10で割った値の10で割ったときの余り
dig100 = seg[(rpm / 100) % 10]; //100で割った値の10で割ったときの余り
dig1000= seg[(rpm / 1000) % 10];

switch(sel){ //7セグ表示桁数がどれかの時の処理
case 0: PORTD = 0b00000001; //1の位(Tr)
if(rpm==0){ //rpmが0だったら、1桁目に-を表示
PORTB = 0b01000000;
}else{
PORTB = dig1;
}
break;
case 1: if(rpm<10){ //rpmが<10だったら、表示しない
PORTD = 0;
}else{
PORTD = 0b00000010; //10の位(Tr)
}
PORTB = dig10;
break;
case 2: if(rpm<100){ //rpmが<100だったら、表示しない
PORTD = 0;
}else{
PORTD = 0b00010000; //100の位(Tr)
}
PORTB = dig100;
break;
case 3: if(rpm<1000){ //rpmが<1000だったら、表示しない
PORTD = 0;
}else{
PORTD = 0b00100000; //1000の位(Tr)
}
PORTB = dig1000;
break;

}
sel++; //7セグ表示桁数を上げる
if(sel == 4) sel = 0; //桁数が3になったら、0に戻す

}


int main(void){

DDRB = 0b11111111; //ポートBを全て出力(7セグ)
PORTB = 0b00000000; //ポートBを初期化
DDRD = 0b00110011; //ポートD0,1,4,5を出力(Tr)
PORTD = 0b00000000; //ポートDを初期化

/*7セグ用タイマー0設定*/
TCCR0B = 0b00000010; //8分周

/*計測用タイマー1設定*/
TCCR1B = 0b00000010; //ICP立ち上がり、タイマー1 8分周
TIMSK = 0b10001010; //ICP割り込み許可、T0OVF割り込み許可

/*オープニング*/
/*1秒間 Cd90 と表示する*/

for(i = 0;i < 200; i++){

switch(sel){ //7セグ表示桁数がどれかの時の処理
case 0: PORTD = 0b00000001; //1の位(Tr)
PORTB = OP0;
break;
case 1: PORTD = 0b00000010; //10の位(Tr)
PORTB = OP9;
break;
case 2: PORTD = 0b00010000; //100の位(Tr)
PORTB = OPD;
break;
case 3: PORTD = 0b00100000; //1000の位(Tr)
PORTB = OPC;
break;
}

_delay_ms(5);

sel++; //7セグ表示桁数を上げる
if(sel == 4) sel = 0; //桁数が3になったら、0に戻す

}

i = 0;
sel = 0;

sei(); //割り込み許可

while(1){

}

}
--------------プログラムここまで--------------

Tag:電子工作  Trackback:0 comment:2 

Comment

シュンケイ URL
#o8CpO/SA Edit  2013.07.02 Tue00:05
何やってるのかさっぱりだけど、すげえ!!
そういえば前から、こういうの得意だったよね。
edia URL|
#PeE7jyuk Edit  2013.07.02 Tue21:41
>シュンケイ
サンクス!
あと数年したら、俺も分かんなくなってると思うww

高校の頃から、電子工作はちょこちょこやっていたが、
マイコン使ったりはしてなかったね。
せいぜいチャリのライトをLEDに替えるぐらいだったぜ。
comment form
(編集・削除用):
管理者にだけ表示を許可
プロフィール

edia@あると

By edia@あると
山に囲まれた県でひっそりと生きる会社員

F1/車/電子工作(AVR)/ゲームなどが趣味

※画像は丹精こめて描いたまっくろくろすけ

カレンダー、月別アーカイブ
プルダウン 降順 昇順 年別

09月 | 2017年10月 | 11月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -


ブログ内検索
Twitter
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。