#define IN1 2 #define IN2 3 #define IN3 4 #define IN4 5 uint8_t taste, taste_alt, pulselimit; uint16_t counter=0; bool limit_pulses; void setup() { sei(); // allow interrupts TIMSK1 = 0 | (1 << OCIE1B); resetTimer1(); pinMode(IN1, INPUT_PULLUP); pinMode(IN2, INPUT_PULLUP); pinMode(IN3, INPUT_PULLUP); pinMode(IN4, INPUT_PULLUP); pinMode(13, OUTPUT); digitalWrite(13, HIGH); // VCC close to PB6 for indicator LED active LOW PORTB |= (1 << PB6); // PulsePin HIGH DDRB |= (1 << PB6); // Enable OUTPUT PB6 DDRF = B11111111; PORTF = 0; } void loop() { taste = 0; if(!digitalRead(IN1)) taste = 1; // highest priority else if(!digitalRead(IN2)) taste = 2; else if(!digitalRead(IN3)) taste = 3; else if(!digitalRead(IN4)) taste = 4; // lowest priority if (taste != taste_alt) { switch (taste) { case 1: initTimer1(80, 160, 1, 1, 2); break; case 2: initTimer1(640, 3200, 1, 0, 0); break; case 3: initTimer1(2500, 25000, 1024, 1, 5); break; case 4: resetTimer1(); PORTB &= (0 << PB6); break; default: resetTimer1(); break; } taste_alt = taste; } delay(5); } void initTimer1 (uint16_t duty, uint16_t periode, uint16_t prescaler, bool limit_pulses_in, uint16_t pulselimit_in) { //uint16_t periode = periode in ms / prescaler * 16.000 //uint16_t duty = duty in ms * prescaler / 16.000 //duty <= periode pulselimit = pulselimit_in; limit_pulses = limit_pulses_in; PORTB |= (1 << PB6); // PulsePin HIGH resetTimer1(); TCCR1A = (1 << WGM11) | (1 << WGM10) | (1 << COM1B0) | (1 << COM1B1); TCCR1B = (1 << WGM13) | (1 << WGM12); OCR1A = periode-1; OCR1B = duty-1; switch (prescaler) { case 1 : TCCR1B |= (1 << CS10); break; // prescaler 1 case 8 : TCCR1B |= (1 << CS11); break; // prescaler 8 case 64 : TCCR1B |= (1 << CS11) | (1 << CS10); break; // prescaler 64 case 256 : TCCR1B |= (1 << CS12); break; // prescaler 256 case 1024 : TCCR1B |= (1 << CS12) | (1 << CS10); break; // prescaler 1024 default : resetTimer1(); break; // otherwise timer remains stopped } } void resetTimer1 () { PORTF = 2; //D1 high TCCR1B = 0; // Reset, stop timer first TCCR1A = 0 | (1 << COM1B0) | (1 << COM1B1); // Set on match TCCR1C = (1 << FOC1B); // Force match PORTF = 16; //D2 high TCCR1A = 0; // Reset OCR1A = 0; // Reset periode OCR1B = 0; // Reset duty TCNT1 = 0; // initialize counter value to 0 //Serial.println(counter); // Print counter value counter = 0; // Reset counter PORTF = 0; //Dn low } ISR(TIMER1_COMPB_vect) { // Interrupt if duty is reached PORTF = 1; //D0 high counter++; PORTF = 0; if(limit_pulses == 1 & counter >= pulselimit){ resetTimer1(); } }