TOP工作

TT250R用 デジタルタコメーターの製作 (5.LED表示への変更)
■7セグメントLED表示化



前回までで
 ・ピックアップパルスの整形
 ・PICでのカウント
 ・回転数への変換
まではうまくいったわけだから、ここからは早いはず。

とりあえず表示器を7セグに置き換えた回路図を書く。

(1)バーグラフ表示用には、秋月で買える10連のバーLEDを1桁あたり3個合体させて使うことにした。
(分解能1000rpmで9000rpmまでなので3*9=27とし、残る3素子は未接続とする)
詳細は後述するが、大きい面発光のLED素子は入手しづらい上に高価なのである。

(2)7セグ、バーLED共に発光量をPWM制御し、周囲が暗い時に減光する構造とした。明るさの検出にはCdsセルを使用。Cdsセルは名前の通り硫化カドミウムを使用したデバイスだから、このタコメータはRohs対応できません(笑


クリックで拡大



とりあえず秋葉原へ行って足りない部品を買出し。ついつい余計な部品も買ってしまうのは、誰でも同じはず・・。


■面発光LEDを探し回る



走行中に、数字を読んで「ああ、いま○○rpmなんだな」と考える余裕は無いと思うので、何がしかグラフィカルな表示にしないと使いづらい。10*10mm程度で面発光するLEDをどこかのWebサイトで見たことがあるのだけど、名前がわからず。

散々探し回った結果、スタンレーまたはKingbrightというメーカが出している物で、秋葉原だと調べた限り唯一マルツパーツ館で取り扱いがあった。


Kingbright製
KB-A100SRW (超硬輝度 赤) @\126
KB-2500SGD (高輝度 緑) @\100
(Webサイトの製品カテゴリ別検索で LED DISPLAY > Light Bar と行けば色々見れる)

呼び名としては「面発光LEDアレイ」とかが正しいようだ。意外と需要がありそうなのだが、取り扱っている店がやたらと少ないのはなぜ??(だれか秋葉原で他に扱っている店を知っていれば教えてください)


左から
・秋月で現品処分していた角型LED(詳細不明)×2
・超硬輝度赤
・高輝度緑
いずれもIf=20mA程度流している。

写真で見ると赤が超高輝度だけあってまばゆいばかりだが、実際にはそうでもない。人間の目は赤の波長に対して感度が低いので、カメラで撮った時と実際に見たときでは全然違うのである。

色々考えてこいつの赤を9桁分並べようかとも思ったのだけど、ちょっとコスト的に断念。結局上記の秋月10連アレイの3個使いに落ち着いた。

RSオンラインでは各種取り扱いをしているようなので、いずれ2号機を作る時には使用を検討したいところ。


■ブレッドボードで仮組み




とりあえず上記回路をブレッドボードに組んでみる。恐らく今までで一番の大作・・。
バーLEDは回路上特に難しい点でもないので1つに省略。(写真はすでにプログラムのテスト中の写真)


やはり12V→5Vの変換は無駄が大きいらしく、レギュレータの発熱が想像以上に多い。本体内の内蔵は断念した方がよさそう。

表示器をLCDから7セグメントLEDに置き換えると共に、
・PWMによる輝度コントロール
・数値表示の書き換えを5回/秒へ(Timer0による割り込みを利用)
の変更を加えて、おおむねプログラムは完成。

もちろん途中あちこちつまづいたものの、機能を一つずつ確認しながら開発しているのでデバッグが楽で思いのほかスムーズに進んだ。


■いよいよ、基板へ



ブレッドボード上でうまく動いたので、あとは基板を起こしてケースに組み込むのみ。
大きな部品であるバーLEDと7セグLEDの大きさを考慮すると、テイシン電機というメーカのTB-57(W110*D65*H20)というケースになんとか押し込めそう。


うーむ、、、入るか・・・?

パターン側を考慮しつつ、問題ない抵抗は縦にしてスペースを節約し、(自分的には)ぎっしり詰めて何とか収めた。ピン間は通しまくり、パターン幅もかなり細い、挑戦的な基板となってしまった。(最小クリアランスは10mil。当然片面基板)


なんとか無理やり押し込む。



未配線は5本。これはあきらめて後で手配線する。(クリックで拡大)

ちなみに、GNDは左右で分断されているし、パスコンの位置はむちゃくちゃだし、見る人が見るとひどい基板だと思う・・が、とりあえず今回はねじ込む事を第一優先で作ってみた。(ブレッドボード状態で車載して特別問題が起きなかったから、ノイズ対策なんかどうでも良いんじゃねぇの?とややナメての挑戦)



ああ・・・・。またやってしまった、逆焼きを・・ 俺はアホだ・・



結局また基板を作り直し、とりあえず実装まで完了。OHPシートに色々なフォントで数字を印字し、


LEDアレイに貼り付ける。

基板の右側が足りていないのは、基板サイズをケチったから。(サンハヤトの10Kという最小サイズに収めたかった)
はみ出しているのは未配線のところなので特に問題なし。



裏面はこんな感じ。未配線分を手で配線。
通常はジュンフロンかUEW線で配線するところだが、一応振動環境下なので撚り線で配線してみる。



これは小技なのだけど、今回のように詰めすぎでインサーキットでプログラムの書き換えができない場合、頻繁にPICの抜き差しが発生する。そんな時はICソケットを2段重ねにするとPICの破損防止に役立つ。ICソケット同士の抜き差しはスッと抜けて楽なのである。



テスト信号を入れて正常動作することを確認。良かった・・・。


■ケース側加工



テイシン電機製TB-57(W110*D65*H20)ケースをちまちまと加工する。


フタ部分にEAGLEで出力した紙を両面テープで貼り付け、対象部分を穴あけ。



穴あけはかなり適当に行い、表面に同じサイズにカットしたスモークアクリル板を貼り付ける。アクリルを貼ってしまうとほとんど見えないので加工は適当。(といっても、綺麗に開けようとしても適切な工具は無いのだけど。)



収まりもぴっちり完璧。
初めてPCB-CADをつかったけど、これは一度使うと手放せないね。



動作チェック。特に問題なし。

いよいよ、残すはバイクへの取り付けのみ。


<4.ソフト製作(試作1号完成)  6.バイクへの取り付け>


■資料


最終版のソースファイルは下記。
貼り付け時に半角、タブ等全て無視されていているため、読みづらいのはご勘弁を。
'**********************************************
'Tachometer For PIC16F886 20MHz by Magokoro
'This program measure frequency of pulse
'for INT pin and show it on 7seg and bar LED.
'Ver.1.0 (Release:2009-10-02)
'**********************************************
program Tachometer3

dim TMR1VALUE as longword 'Timer1 count value (32bit)
dim INPUT_FLAG as byte
dim COUNT as word 'Buffer for count value
dim DISP as word[4]
dim AD as word
dim PWM_STATUS as byte
dim TMR0_COUNT as byte

'***********************************************
' BAR LED GRAPH control PROCEDURE
'***********************************************
sub procedure bar_led
select case DISP[3]
case 0
PORTB = %00000000
PORTC.0 = 0
PORTC.1 = 0
case 1
PORTB = %00000010
PORTC.0 = 0
PORTC.1 = 0
case 2
PORTB = %00000110
PORTC.0 = 0
PORTC.1 = 0
case 3
PORTB = %00001110
PORTC.0 = 0
PORTC.1 = 0
case 4
PORTB = %00011110
PORTC.0 = 0
PORTC.1 = 0
case 5
PORTB = %00111110
PORTC.0 = 0
PORTC.1 = 0
case 6
PORTB = %01111110
PORTC.0 = 0
PORTC.1 = 0
case 7
PORTB = %11111110
PORTC.0 = 0
PORTC.1 = 0
case 8
PORTB = %11111110
PORTC.0 = 1
PORTC.1 = 0
case 9
PORTB = %11111110
PORTC.0 = 1
PORTC.1 = 1
end select
end sub

'***********************************************
' 7segment LED control PROCEDURE
'***********************************************
sub procedure segment_led
PORTC.4 = 0
PORTA = DISP[3]
PORTC.7 = 1
delay_ms(3)

PORTC.7 = 0
PORTA = DISP[2]
PORTC.6 = 1
delay_ms(3)

PORTC.6 = 0
PORTA = DISP[1]
PORTC.5 = 1
delay_ms(3)

PORTC.5 = 0
PORTA = DISP[0]
PORTC.4 = 1
delay_ms(2)
end sub

'***********************************************
' Devide count value to each digits PROCEDURE
'***********************************************
sub procedure devide_digit
'DIGIT 1000
DISP[3] = COUNT / 1000
'DIGIT 100
DISP[2] = COUNT - (DISP[3]*1000)
DISP[2] = DISP[2] / 100
'DIGIT 10
DISP[1] = COUNT - (DISP[3]*1000)
DISP[1] = DISP[1] - (DISP[2]*100)
DISP[1] = DISP[1] / 10
'DIGIT 1
DISP[0] = COUNT - (DISP[3]*1000)
DISP[0] = DISP[0] - (DISP[2]*100)
DISP[0] = DISP[0] - (DISP[1]*10)
end sub

'***********************************************
' INTERRUPT PROCEDURE
'***********************************************
sub procedure interrupt
INTCON.7 = 0 'Interrupt is disable

if INTCON.1 = 1
then 'In case of INT interrupt
if INPUT_FLAG = 0
then
T1CON = %00110001 'Timer1 start (prescaler 1:8)
INPUT_FLAG = 1
else
T1CON = %00000000 'Timer1 stop
TMR1VALUE = TMR1H
TMR1VALUE = TMR1VALUE << 8
TMR1VALUE = TMR1VALUE + TMR1L
TMR1VALUE = TMR1VALUE * 16
TMR1VALUE = 100000000 / TMR1VALUE
TMR1VALUE = TMR1VALUE * 6
COUNT = TMR1VALUE 'Type convert: word <- longword

INPUT_FLAG = 0
TMR1H = 0
TMR1L = 0
end if

else 'In case of TMR0 overflow interrupt
if TMR0_COUNT < 15
then
TMR0_COUNT = TMR0_COUNT + 1
else
TMR0_COUNT = 0
devide_digit 'Devide count value to each digit
end if
end if

INTCON.1 = 0 'INT Interrupt flag clear
INTCON.2 = 0 'TMR0 Interrupt flag clear
INTCON.7 = 1 'Interrupt is enable
end sub

'***********************************************
' MAIN PROGRAM
'***********************************************
main:

'*** Resistor setup ****************************
ADCON1 = %10000000 ' Configure analog inputs and Vref
ANSEL = %00010000 'A/D Converter disable except AN4
ANSELH = 0 'A/D Converter disable

OPTION_REG.6 = 1 'Interrupt on rising edge of INT pin.
OPTION_REG.5 = 0 'TMR0 OSC:Internal instruction cycle clock (FOSC/4)
OPTION_REG.3 = 0 'Prescaler is assigned to the Timer0 module
OPTION_REG.2 = 1 'Prescaler Rate 1:256 (Bit 2,1,0)
OPTION_REG.1 = 1
OPTION_REG.0 = 1

INTCON.4 = 1 'INT pin interrupt enable
INTCON.5 = 1 'TMR0 interrupt enable
INTCON.7 = 1 'Interrupt enable

TRISA.0 = 0
TRISA.1 = 0
TRISA.2 = 0
TRISA.3 = 0
TRISA.4 = 0
TRISA.6 = 0
TRISA.7 = 0

TRISB.1 = 0
TRISB.2 = 0
TRISB.3 = 0
TRISB.4 = 0
TRISB.5 = 0
TRISB.6 = 0
TRISB.7 = 0

TRISC = 0 'All output

'*** Clear all values ***************************
PORTA = 0
PORTB = 0
PORTC = 0
INPUT_FLAG = 0
PWM_STATUS = 0
COUNT = 0
TMR0_COUNT = 0

'*** Setup TIMER2 for PWM ***********************
Pwm1_init(78120) 'PWM1 init Fq=78.120kHz
Pwm1_Start
Pwm1_Change_Duty(100)



while TRUE 'Endless loop

'*** Set LED Brightness *************************
AD = Adc_Read(4)
if PWM_STATUS = 0
then
if AD > 900
then
Pwm1_Change_Duty(35)
PWM_STATUS = 1
end if
else
if AD < 800
then
Pwm1_Change_Duty(255)
PWM_STATUS = 0
end if
end if

bar_led 'Bar LED control procedure
segment_led '7 segment LED control procedure

wend 'Endless loop

end.
'***********************************************
' END OF PROGRAM
'***********************************************


おことわり


※1 記事を書きながら製作・勉強しています。誤っている箇所やアドバイスありましたら教えてください。質問も分かる範囲でお答えします。一緒に勉強しましょう。

TOP工作


SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送