Tachometer

                Never    
C/C++
       
#include <avr/io.h>
#include <avr/interrupt.h>

class math{
	public:
	uint8_t rDigit(uint8_t digit, uint16_t total){
		uint16_t exp10 = 1;
		for(uint8_t i = 0; i < digit; i++){
			exp10 *= 10;
		}
		total %= exp10;
		return total/(exp10/10);
	}
};
math M;

class disp{
	public:
	void initDisplay(){
		DDRD |= 0xFF;
		DDRC |= 0x0F;
	}
	
	void setSegment(uint16_t val){
		for(uint8_t i = 0; i <= 3; i++){
			segment[i] = numbers[M.rDigit(i+1, val)];
		}
	}
	void setSegment(uint8_t seg, uint8_t i){
		segment[i] = seg;
	}
	
	void refreshDisp(){
		PORTC &= 0xF0;
		PORTD = segment[frame];
		PORTC |= (1 << (3 - frame));
		if(frame == 3){
			frame = 0;
			}else{
			frame++;
		}
	}
	
	
	private:
	uint8_t segment[4]{
		0xFF,
		0xFF,
		0xFF,
		0xFF
	};
	
	uint8_t frame {0};
	
	const int8_t numbers[10] {
		~0b00111111,//0
		~0b00000110,//1
		~0b01011011,//2
		~0b01001111,//3
		~0b01100110,//4
		~0b01101101,//5
		~0b01111101,//6
		~0b00000111,//7
		~0b01111111,//8
		~0b01100111 //9
	};
};
disp D;

class counter{
	public: 
	void inc(){
		count++;
	}
	
	void clr(){
		count = 0;
	}
	
	uint32_t getCount(){
		return count;
	}
	private:
	uint32_t count{0};
};
counter fanC;
counter timerC;

class fan{
	public:
	void setRpm(uint16_t x){
		rpm = x;
	}
	uint16_t getRpm(){
		return rpm;
	}
	
	private:
	uint16_t rpm;
};
fan F;

void initTimer1(){
	OCR1A = 1250;
	TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10);
	TIMSK1 |= (1 << OCIE1A);
}

void initPCINT13(){
	PCICR |= (1 << PCIE1);
	PCMSK1 |= (1 << PCINT13);
}

ISR(TIMER1_COMPA_vect){	
	D.refreshDisp();
	timerC.inc();
}

ISR(PCINT1_vect){
	PORTB ^= (1 << 5);
	fanC.inc();
	if(timerC.getCount() >= 50){
		F.setRpm(((double)fanC.getCount()/4)*4*60);
		D.setSegment(F.getRpm());
		fanC.clr();
		timerC.clr();
	}
}


int main(void)
{
	DDRB |= (1 << 5);
	D.initDisplay();
	initTimer1();
	initPCINT13();
	sei();
    while (1) 
    {
    }
}

Raw Text