読者です 読者をやめる 読者になる 読者になる

PointCloud

ものづくりに関すること。3Dプリンター、レーザーカッター、3Dスキャナー、3DCAD、RaspberryPi、Arudionoとか。

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

*1: on_cnt >= 30)&&(val == LOW

*2: off_cnt >= 30)&&(val == LOW

*3: on_cnt >= 30)&&(val == LOW