2011年1月21日金曜日

LEDバーサライタの制作


試験前の少しの空き時間を利用してAVRマイコンでLEDバーサライタを作ってみました。
バーサライタとは残像を利用して文字列(に限らないが)を表示するシステムです。
(写真はMASAKと表示されています)
製作費は180(マイコン)+5x9(LED9個)+1(カーボン抵抗1個)で、250円程度です。

マイコンは知ってる方も多いと思いますがマイクロコントローラ、
またはマイクロコンピュータと呼ばれる小さなコンピュータで
内部に記憶装置、メモリ、CPUなどが内蔵されています。


構造はLEDを直列に並べ、その点滅で象るものです。
(写真はブレッドボードに置いた状態。撮影の都合上横に並んでます。)


「T」と表示したいなら、
○→●●●●●→
○→○○●○○→
○→○○●○○→
○→○○●○○→
○→○○●○○→

縦にLEDが5つ並んでいて、それを5回点滅させながら右にスライドさせます。
白丸は消灯、黒丸は点灯です。
矢印の方向にスライドすると図のような感じになります。


点滅の速度は一眼カメラなどのシャッターを開きっぱなしにするなら
どれだけの時間でもいいんですけど、人間の目であればコンマ数秒で残像は消えてしまうので
「出来るだけ短い時間で点滅させる」ことが重要になってきます。
(あまり遅すぎると、2つ目の縦のラインが点滅したときに1つ目のラインは消えてしまう)

けどあまりにも早すぎると、スライドさせる速度が間に合わなくなってしまって
ライトが重なり、文字が判別できなくなります。

いろいろ試してみたところ1回の点滅は5ms(ミリ秒・0.005秒)
くらいがちょうどいいという結果になりました。
もっともこれはスライドさせる速度などによって上下します。

そしてマイコンなどの応答速度によって、あまり速い速度だと点滅が上手くいかないかもしれません。


以下制作の手順をまとめてみました。

1、マイコン本体やライタ、LED、カーボン抵抗、電池などを準備。
マイコンはatmel社のAVRマイコンatmega88pを使用。
atmega88pの仕様書は以下に。(直リンク失礼)
http://www.atmel.com/dyn/resources/prod_documents/8025s.pdf

ライタは純正品を使っています。
書き込み方などは省略します。


2、プログラムを考える。
といってもLEDの点灯はHighかLowしかない(操作上は)ので、2進で制御しました。

大きさをある程度確保したかったので縦9列になっていますが、
ちょうどいいフォントがなかったので全て手打ちです。(これが一番きつかったかも)

そしてひと固まりのポート(PORTDなど)は8個ひと組なので
一番上のLEDだけはPORTBで動かしています。

マイコン自体の操作はニコニコの方がわかりやすい解説をされているので省略。
「電子工作のススメ」で検索すればHITするかと思います。

プログラムは下部に乗っけときます。


3、回路を考える。
省略します…と言いたいくらい簡単です。
PORTD0~7、PORTB0のみの使用で、あとは電源への4本くらいです。
PORTには簡略化のためすべてLED直付けなので迷うことはありません。
ブスっといっちゃいましょう。極性には気をつけてね(´・ω・`)

プルアップ?そんなの分かんない




そして初めて回路図書いてみました。


ちょっと書き方が気持ち悪いですけど、間違ってはいないはず…。
自分がわからなかったところを考慮してVCCとかGND(接地)とかいう記号は使ってません。
ちなみに上側が半円の切欠のある方です。

これでボードからライタを取り外せば(ここ重要)めでたく完成となります。
USBにライタをつながずにライタからボードにつながっていた場合、動作しません。
自分もはじめのころここで迷ったんだよなー。
だってライタ外すと再接続しなきゃいけないじゃない
ISPケーブルをライタから抜けばそれで大丈夫です。(説明がわかりづらい)

基本的なところはこれくらいにして以下プログラム。
お好きにspace分のdelayとかいれればいいとおもいます。

お疲れ様でした。

#include<avr/io.h>
#include<util/delay.h>

void A_line();
void B_line();
void C_line();
void D_line();
void E_line();
void F_line();
void G_line();
void H_line();
void I_line();
void J_line();
void K_line();
void L_line();
void M_line();
void N_line();
void O_line();
void P_line();
void Q_line();
void R_line();
void S_line();
void T_line();
void U_line();
void V_line();
void W_line();
void X_line();
void Y_line();
void Z_line();

int main(void){

DDRB = 0b11111111;
DDRD = 0b11111111;

while(1){

H_line();
E_line();
L_line();
L_line();
O_line();

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}
}

void A_line(){
PORTB = 0b00000000;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00001000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00001000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00001000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00001000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11111111;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void B_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11101110;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void C_line(){
PORTB = 0b00000000;
PORTD = 0b11111110;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b10000010;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void D_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b10000010;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01000100;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void E_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void F_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000000;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void G_line(){
PORTB = 0b00000000;
PORTD = 0b11111110;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00001001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b10001110;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void H_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void I_line(){
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void J_line(){
PORTB = 0b00000000;
PORTD = 0b00000110;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111110;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void K_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00101000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01000100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b10000010;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void L_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void M_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11000000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01110000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01110000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11000000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void N_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11000000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01110000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00011100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000110;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void O_line(){
PORTB = 0b00000000;
PORTD = 0b11111110;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11111110;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void P_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11100000;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void Q_line(){
PORTB = 0b00000000;
PORTD = 0b11111110;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000101;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000011;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11111111;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void R_line(){
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00011000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b11100011;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void S_line(){
PORTB = 0b00000000;
PORTD = 0b11100010;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00010001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01001110;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void T_line(){
PORTB = 0b00000001;
PORTD = 0b00000000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00000000;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void U_line(){
PORTB = 0b00000001;
PORTD = 0b11111110;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111110;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void V_line(){
PORTB = 0b00000001;
PORTD = 0b11111000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000110;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000001;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000110;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111000;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void W_line(){
PORTB = 0b00000001;
PORTD = 0b11111100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00111100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00111100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00000111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11111100;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void X_line(){
PORTB = 0b00000001;
PORTD = 0b10000011;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01000100;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00111000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00111000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b01000100;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b10000011;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void Y_line(){
PORTB = 0b00000001;
PORTD = 0b11000000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00100000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00011111;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00010000;
_delay_ms(5);
PORTB = 0b00000000;
PORTD = 0b00100000;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11000000;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}

void Z_line(){
PORTB = 0b00000001;
PORTD = 0b00000111;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00001101;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00011001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b00110001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b01100001;
_delay_ms(5);
PORTB = 0b00000001;
PORTD = 0b11000001;
_delay_ms(5);

PORTB = 0b00000000;
PORTD = 0b00000000;//space
_delay_ms(5);
}




5 件のコメント:

zaty さんのコメント...

すごい!

Hamachi さんのコメント...

ありがうございます!

zaty さんのコメント...

;)

先生にバーサライターを作ってて言われて、検索したら、このブログを見つけました!どうやって作るのか分からないので、参考になります!(^^)

Hamachi さんのコメント...

:-D
AVRというマイコンで作っているのでよくあるPICとは少しコードが違うかもしれませんが^^;

何かの参考になれば。

zaty さんのコメント...

この前ATMEGA8使ってました!(^0^)/

でもプログラムの書き方はちょっと違う(^^;;

コメントを投稿