#include #include // DONG_PULSE_LEN if the time the relay is energized in milliseconds // DELAY_BETW_DONGS if pause between dongs in milliseconds #define DONG_PULSE_LEN 120 #define DELAY_BETW_DONGS 1500 #define INIT_TIMER_COUNT 6 #define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT #define CONTROL_PORT PORTB #define SWITCH_PORT PINB #define CONTROL_DDR DDRB #define RELAY PB0 #define HR_SET PB2 #define MIN_SET PB3 #define SR_DIN PB4 #define SR_CLK PB5 int int_counter = 0; volatile int second = 45; volatile int minute = 59; volatile int hour = 10; volatile int digit = 0; volatile int rintocchi = 0; volatile int min_pb_was_pressed = 0; volatile int hour_pb_was_pressed = 0; int oldSecond = 0; long oldmillis = 0; // Aruino runs at 16 Mhz, so we have 1000 Overflows per second... // 1/ ((16000000 / 64) / 256) = 1 / 1000 ISR(TIMER2_OVF_vect) { RESET_TIMER2; int_counter += 1; if (int_counter == 1000) { int_counter = 0; do_clock(); } // do_alarm(); do_switch(); do_display(); }; void do_clock(){ second++; if(second > 59){ second = 0; minute++; if(minute == 30) rintocchi = -1; // half hour if(minute > 59){ minute = 0; hour++; if(hour > 23){ hour = 0; } rintocchi = hour; if (rintocchi == 0) rintocchi = 12; if (rintocchi > 12) rintocchi -= 12; } } } void do_switch(){ if(bit_is_clear(SWITCH_PORT, HR_SET)){ if(hour_pb_was_pressed == 0){ hour_pb_was_pressed = 1; hour++; if(hour > 23) hour = 0; } } else hour_pb_was_pressed = 0; if(bit_is_clear(SWITCH_PORT, MIN_SET)){ if(min_pb_was_pressed == 0){ min_pb_was_pressed = 1; minute++; second = 0; if(minute > 59) minute = 0; } } else min_pb_was_pressed = 0; } void do_display(){ switch(digit){ case 0: digit_wr (((hour / 10) == 0 ? 10 : hour / 10), 0, digit); break; case 1: digit_wr (hour % 10, int_counter < 500 ? 1:0, digit); break; case 2: digit_wr (minute / 10, 0, digit); break; case 3: digit_wr (minute % 10, 0, digit); break; } digit++; digit &= 0x03; } void setup() { // Serial.begin(9600); // Serial.println("Initializing timerinterrupt"); //Timer2 Settings: Timer Prescaler /64, TCCR2B |= (1< 0) && (rintocchi <13)){ // strike hours CONTROL_PORT |= _BV(RELAY); // close relay: dong! delay(DONG_PULSE_LEN); CONTROL_PORT &= ~_BV(RELAY); // release relay. delay(DELAY_BETW_DONGS); rintocchi--; } if (rintocchi == -1){ // strike half hour rintocchi = 0; CONTROL_PORT |= _BV(RELAY); // close relay: dong! delay(DONG_PULSE_LEN); CONTROL_PORT &= ~_BV(RELAY); // release relay. } } void wr_one(){ // write a bit 1 to the shift register but no transfer yet CONTROL_PORT |= _BV(SR_DIN); CONTROL_PORT |= _BV(SR_CLK); CONTROL_PORT &= ~_BV(SR_DIN); CONTROL_PORT &= ~_BV(SR_CLK); // Din == 0 => no transfer (BU2090) } void wr_zero(){ // write a bit 0 to the shift register but no transfer yet CONTROL_PORT &= ~_BV(SR_DIN); CONTROL_PORT |= _BV(SR_CLK); CONTROL_PORT &= ~_BV(SR_CLK); // Din == 0 => no transfer (BU2090) } void wr_one_tr(){ // write a bit 1 to the shift register and transfer CONTROL_PORT |= _BV(SR_DIN); CONTROL_PORT |= _BV(SR_CLK); CONTROL_PORT &= ~_BV(SR_CLK); // Din == 1 => transfer (BU2090) } void wr_zero_tr(){ // write a bit 0 to the shift register and transfer CONTROL_PORT &= ~_BV(SR_DIN); CONTROL_PORT |= _BV(SR_CLK); CONTROL_PORT |= _BV(SR_DIN); CONTROL_PORT &= ~_BV(SR_CLK); // Din == 1 => transfer (BU2090) } void digit_wr (int val, int dot, int digit){ switch (digit){ case 0: // decine ore wr_zero(); wr_one(); wr_one(); wr_one(); break; case 1: // unita' ore wr_one(); wr_zero(); wr_one(); wr_one(); break; case 2: // decine min wr_one(); wr_one(); wr_zero(); wr_one(); break; case 3: // decine ore wr_one(); wr_one(); wr_one(); wr_zero(); break; default: break; } if(dot) wr_zero(); else wr_one(); switch(val){ case(0): wr_one(); wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_zero_tr(); break; case(1): wr_one(); wr_one(); wr_one(); wr_one(); wr_zero(); wr_zero(); wr_one_tr(); break; case(2): wr_zero(); wr_one(); wr_zero(); wr_zero(); wr_one(); wr_zero(); wr_zero_tr(); break; case(3): wr_zero(); wr_one(); wr_one(); wr_zero(); wr_zero(); wr_zero(); wr_zero_tr(); break; case(4): wr_zero(); wr_zero(); wr_one(); wr_one(); wr_zero(); wr_zero(); wr_one_tr(); break; case(5): wr_zero(); wr_zero(); wr_one(); wr_zero(); wr_zero(); wr_one(); wr_zero_tr(); break; case(6): wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_one(); wr_one_tr(); break; case(7): wr_one(); wr_one(); wr_one(); wr_one(); wr_zero(); wr_zero(); wr_zero_tr(); break; case(8): wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_zero(); wr_zero_tr(); break; case(9): wr_zero(); wr_zero(); wr_one(); wr_one(); wr_zero(); wr_zero(); wr_zero_tr(); break; default: // blank wr_one(); wr_one(); wr_one(); wr_one(); wr_one(); wr_one(); wr_one_tr(); break; } }