Maker Faire 2014出展情報4 ハルロック 無駄時間可視化ツール改

ハルロック本家が猫twitterなどで出展されるのでおこがましいのですが
ひっそりと展示しときます。
今のところ今回自分(sakehito)の唯一の作品なので。


・仕様
作中の解説と脳内保管から機能仕様は下記にしました。

・ボタン押下で時間計測をON/OFFし、計測値はATtiny45内のEEPROMに保存する
・計測結果の確認はAttiny45を取り外して、ライター環境で読み出すことで、取得する
 =>長押しで2進数でEEPROMデータ表示(追加機能!)
・1週間バッテリー交換無で動作すること
・未計測時はパワーセーブモードに移行して省電力化すること

・回路図

・部品表

・結果
https://docs.google.com/spreadsheets/d/1EGX-QOQUUa8TQil_8735L1fB2xrmEzw_FKDFe1B-3QM/edit#gid=0

・ソフト
Attiny45をArduino化して下記のように書いてます。
あまりきれいなコードではないですが参考に。

//HARUROCK 9ohm
//2014.7.24
//長押し時に毎回binを点滅表示
//sakehito@ngitigadget

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <EEPROM.h>

//外部割込み端子(D2)にタクトスイッチ接続
#define SW 2  
#define LED 1

#define LOOP_WAIT 1
#define BUTTON_COUNT 40
#define BUTTON_WAIT 32
#define BUTTON_LONGWAIT 150
#define STOP 0
#define START 1
#define EEPADD 0

unsigned long now1 = 0, now2 = 0;
unsigned long wastetime = 0;
unsigned long newtime = 0;
unsigned char swcount = 0, initial_flag = 0;
byte hours = 0;
byte minutes = 0;
byte seconds = 0;
boolean ledblink = 0; 
byte status = START;
int blink_counter = 0;

volatile unsigned int sw = 1;

unsigned char i = 0, j = 0;
byte eeptemp=0;
boolean eep1bit=0;
unsigned long ledwait =0;

//Timer1
void initTimerCounter1(void);

void setup() {
  //EEPROM initiarize
  //00:hour,01:minute,02:secondに割り当て
  //00がFFなら、出荷時かMAX値と判断して、3byte00に初期化
  if ( EEPROM.read(EEPADD) == 0xFF) 
    initial_flag = 1;
      else initial_flag = 0;  
  if (initial_flag)  {
     for (i=EEPADD ; i<EEPADD+3 ; i++) {
       EEPROM.write(i,0x00);
     }
  }  

  // Pin initiarize
  pinMode(SW, INPUT);
  digitalWrite(SW,HIGH);
  pinMode(LED, OUTPUT);
  digitalWrite(LED,HIGH);

   //timer1
  initTimerCounter1(); 

  //Sleep initiarize
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

  delay(500);
  attachInterrupt(0, wakeup,  LOW);  //割り込み開始
  sleep_mode(); //sleepに移行
}


//Timer1設定
void initTimerCounter1(void)
{
    TCCR1 = 0;                  //stop the timer
    TCNT1 = 0;                  //zero the timer
    GTCCR = _BV(PSR1);          //reset the prescaler
    OCR1A = 243;                //set the compare value 1sec
    TIMSK &= ~0x40;  
    TCCR1 = _BV(CTC1) | _BV(CS13) | _BV(CS12); 
}

//LED極性反転
ISR(TIMER1_COMPA_vect)
{
      ledblink = ~ledblink;
      digitalWrite(LED,ledblink);     
}

//LED消灯
void off()
{
  digitalWrite(LED,HIGH);
}

//外部割込みピンに繋がったタクトスイッチでsleepから復帰)
void wakeup(){
}

//swが押されている期間をカウント
void switched(){ 
  for(i=0;i<BUTTON_COUNT;i++){
    sw = digitalRead(SW);
    if (sw ==0) swcount++;
      else swcount =0;
  }
}

//EEPROMの内容をLED点滅で表示
void bin_display()  {
  for(i=0;i<3;i++){
    eeptemp = EEPROM.read(i);
     for(j=0;j<8;j++){
      eep1bit = bitRead(eeptemp, 7-j) ;
      if (eep1bit) ledwait = 1000; else ledwait = 300;
      digitalWrite(LED,LOW);
      delay(ledwait);
      digitalWrite(LED,HIGH);
      delay(1000);
      }
    delay(2000);
  }
}


void loop() {
  delay(LOOP_WAIT); 
  // check SW and avoid chatterin  
  switched();

  if(swcount >= BUTTON_LONGWAIT){
    TIMSK &= ~0x40; 
    bin_display();
    off();  
    swcount = 0;
	}

  if(swcount >= BUTTON_WAIT){

    switch(status){
      
    case START:
      //割り込み停止
      detachInterrupt(0);  
      now1 = millis();
      hours = EEPROM.read(EEPADD);
      minutes = EEPROM.read(EEPADD+1);
      seconds = EEPROM.read(EEPADD+2);
      delay(10); 
      wastetime = hours * 3600 + minutes*60 + seconds;
      //割り込み再開
      attachInterrupt(0, wakeup,  LOW);
       //Timer1 active
      TIMSK |= 0x40; 
      delay(100);
      status = STOP;
      break;
      
    case STOP:
      detachInterrupt(0);
      off();
      TIMSK &= ~0x40; //Timer1 nonactive
      now2 = millis();  
      newtime = wastetime + (now2 - now1)/1000;
      //秒を時、分、秒に変換
      hours = newtime / 3600;
      minutes = (newtime - (hours * 3600) ) / 60;
      seconds = newtime - ( hours * 3600 ) -( minutes *60 );
      //EEPROM WRITE
      EEPROM.write(EEPADD,hours);
      EEPROM.write(EEPADD+1,minutes);
      EEPROM.write(EEPADD+2,seconds);   
      attachInterrupt(0, wakeup,  LOW);
      delay(100); 
      
      status = START;
      sleep_mode();
      break;

      }

  }

}