Arduinoで STOP WATCH
先日つくったストップウォッチの回路図とプログラム
作ったのはコレ。
回路図
Arduinoのシールドはかさばるので、ATmega328p-puを単体で動作。
電源スイッチ×1
入力のスイッチ×2
プログラム概要
・タイマ割り込みを使って7セグ4桁をダイナミック点灯制御
(7セグはカソードコモン)
・START/STOP と RESETボタンの入力もタイマ割込みで取得
・メインループでは待ち状態、計測状態のモード中処理を記述
#include
#define anode_a 18
#define anode_b 14
#define anode_c 11
#define anode_d 9
#define anode_e 8
#define anode_f 17
#define anode_g 12
#define kasode_com1 19
#define kasode_com2 16
#define kasode_com3 15
#define kasode_com4 13
#define st_sp 2
#define rst 7
char i,j,k,l;
int segdata=0;
int segcaunt=1;
int val=0;
int old_val=0;
int times=0;
int tm=0;
int old_tm=0;
int cnt=0;
int on_cnt = 0;
int off_cnt = 0;
boolean ini_flag = true;
int Rst_flag=0;
int mode = 0;
void setup(){
pinMode(3,INPUT);
pinMode(anode_a,OUTPUT);
pinMode(anode_b,OUTPUT);
pinMode(anode_c,OUTPUT);
pinMode(anode_d,OUTPUT);
pinMode(anode_e,OUTPUT);
pinMode(anode_f,OUTPUT);
pinMode(anode_g,OUTPUT);
pinMode(kasode_com1,OUTPUT);
pinMode(kasode_com2,OUTPUT);
pinMode(kasode_com3,OUTPUT);
pinMode(kasode_com4,OUTPUT);
pinMode(st_sp,INPUT);
pinMode(rst,INPUT);
digitalWrite(kasode_com1,HIGH);
digitalWrite(kasode_com2,HIGH);
digitalWrite(kasode_com3,HIGH);
digitalWrite(kasode_com4,HIGH);
digitalWrite(anode_a,LOW);
digitalWrite(anode_b,LOW);
digitalWrite(anode_c,LOW);
digitalWrite(anode_d,LOW);
digitalWrite(anode_e,LOW);
digitalWrite(anode_f,LOW);
digitalWrite(anode_g,LOW);
MsTimer2::set(4, flash); //4ミリ秒ごとにダイナミック点灯
MsTimer2::start();
delay(1000);
mode = 0;
}
void loop(){
switch (mode){
case 1: //計測状態
tm = millis();
times = (tm - old_tm);
if (times > 1000) { //カウントアップ
segdata=segdata+1;
old_tm=tm;
}
if (ini_flag == true){
segdata = 1;
ini_flag = false;
}
break;
case 2: //待ち状態
Rst_flag = digitalRead(rst); //リセットボタン読み取り →カウントRESET
if (Rst_flag == HIGH){
segdata = 0;
mode = 2;
on_cnt = 0;
off_cnt = 0;
ini_flag = true;
}
break;
}
}
//7×4セグメントのダイナミック点灯のための表示関数群
void flash(){ //MsTimerで一定時間ごとに7segを一桁ずつダイナミック表示していく
val = digitalRead(st_sp); //開始停止ボタン読み取り →START
if (mode == 0){
if (val == HIGH){
on_cnt = on_cnt + 1;
}
if *1{
mode = 1;
on_cnt = 0;
}
} else if(mode == 1) { //開始停止ボタン読み取り →STOP
if (val == HIGH){
off_cnt = off_cnt + 1;
}
if*2{
mode = 2;
off_cnt = 0;
}
} else if(mode == 2){
if (val == HIGH){
on_cnt = on_cnt + 1;
}
if *3{
mode = 1;
on_cnt = 0;
}
}
switch(segcaunt){
case 4://千の位
display_no();//LEDをすべて消灯
com_on(4);//4桁目を点灯準備
disp(i);//数字点灯
segcaunt=1;
segcal();//次のダイナミック表示の準備
break;
case 3://百の位
display_no();
com_on(3);
disp(j);
segcaunt=4;
break;
case 2://十の位
display_no();
com_on(2);
disp(k);
segcaunt=3;
break;
case 1://一の位
display_no();
com_on(1);
disp(l);
segcaunt=2;
break;
}
}
void segcal(){
//ダイナミック点灯させるためのデータ処理
int segcash=segdata;
if(segcash>=0){//数値が正の時
int m=segcash/600;
i=m;
int n=segcash%600;
j=n/60;
int r=segcash%60;
k=r/10;
int s=segcash%10;
l=s;
if(segdata<=599){
i='n';
}
if(segdata<=59){
j='n';
}
if(segdata<=9){
k='n';
}
if(segdata>=6000){
i='o';
j='o';
k='o';
l='o';
}
}
else{//負の時
segcash=abs(segcash);
i='i';
j=segcash/100;
segcash=segcash%100;
k=segcash/10;
segcash=segcash%10;
l=segcash;
if(segdata<=-1000){
i='u';
j='u';
k='u';
l='u';
}
if(segdata>=-100){j='n';}
if(segdata>=-10){k='n';}
}
}
void com_on(int com){
switch(com){
case 1://1桁目
digitalWrite(kasode_com1,HIGH);
digitalWrite(kasode_com2,HIGH);
digitalWrite(kasode_com3,HIGH);
digitalWrite(kasode_com4,LOW);
break;
case 2://2桁目
digitalWrite(kasode_com1,HIGH);
digitalWrite(kasode_com2,HIGH);
digitalWrite(kasode_com3,LOW);
digitalWrite(kasode_com4,HIGH);
break;
case 3:
digitalWrite(kasode_com1,HIGH);
digitalWrite(kasode_com2,LOW);
digitalWrite(kasode_com3,HIGH);
digitalWrite(kasode_com4,HIGH);
break;
case 4:
digitalWrite(kasode_com1,LOW);
digitalWrite(kasode_com2,HIGH);
digitalWrite(kasode_com3,HIGH);
digitalWrite(kasode_com4,HIGH);
break;
}
}
void disp(char namber){
switch(namber){
case 1://数字の1を表示
digitalWrite(anode_a, LOW);//消灯
digitalWrite(anode_b, HIGH);//点灯
digitalWrite(anode_c, HIGH);//点灯
digitalWrite(anode_d, LOW);//消灯
digitalWrite(anode_e, LOW);//消灯
digitalWrite(anode_f, LOW);//消灯
digitalWrite(anode_g, LOW);//消灯
break;
case 2://数字の2を表示
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, LOW);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, HIGH);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, HIGH);
break;
case 3:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, HIGH);
break;
case 4:
digitalWrite(anode_a, LOW);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, LOW);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, HIGH);
break;
case 5:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, HIGH);
break;
case 6:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, HIGH);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, HIGH);
break;
case 7:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, LOW);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, LOW);
break;
case 8:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, HIGH);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, HIGH);
break;
case 9:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, HIGH);
break;
case 0:
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, HIGH);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, LOW);
break;
case 'i'://マイナス表示(センターバー『-』)
digitalWrite(anode_a, LOW);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, LOW);
digitalWrite(anode_d, LOW);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, HIGH);
break;
case 'o'://オーバ表示(オーバーバー『 ̄』)
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, LOW);
digitalWrite(anode_d, LOW);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, LOW);
break;
case 'u'://マイナス超表示(アンダーバー『_』)
digitalWrite(anode_a, LOW);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, LOW);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, LOW);
break;
case 'n': //何も表示しない
digitalWrite(anode_a, LOW);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, LOW);
digitalWrite(anode_d, LOW);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, LOW);
break;
default://条件に合わないエラーが出た時に表示
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, LOW);
digitalWrite(anode_c, LOW);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, LOW);
digitalWrite(anode_f, LOW);
digitalWrite(anode_g, LOW);
break;
}
}
void display_no() {
digitalWrite(anode_a, HIGH);
digitalWrite(anode_b, HIGH);
digitalWrite(anode_c, HIGH);
digitalWrite(anode_d, HIGH);
digitalWrite(anode_e, HIGH);
digitalWrite(anode_f, HIGH);
digitalWrite(anode_g, HIGH);
}
ここまで
---------------------------------------------------------------------
7セグのダイナミック点灯で参考にしたサイト
http://spinelify.blog.fc2.com/blog-entry-57.html