piątek, 6 maja 2016

Fun with Fan part 4

Teoria już za nami - czas na kodzik!

Na dobry początek rozważmy rozwiązanie wykorzystujące mechanizm przerwań i timer. Sygnał tacho podepniemy pod zewnętrzne przerwanie INT2 (PD3 w mojej Atmedze), a timer skonfigurujemy tak, by generował przerwanie co 1 sekundę. W obsłudze przerwania INT2 będziemy zliczać impulsy, a co sekundę, dzięki timerowi policzymy, ile obrotów wykonał nasz wentylator. Wiemy, że na pełen obrót składają się 2 impulsy, dlatego sumę impulsów podzielimy przez 2.

Żeby mieć jako takie pojęcie o tym, co się dzieje na pokładzie mikrokontrolera, wyślemy ilość obrotów na minutę USARTem przez bluetooth'a wprost do aplikacji terminala odpalonej na telefonie z Androidem. Informację o prędkości będziemy wysyłać również co sekundę. Skąd będziemy wiedzieć kiedy dokładnie? Ustawimy flagę send w obsłudze przerwania!

Do dzieła!


volatile uint8_t command;
volatile uint8_t fanSpeed;
volatile uint8_t send = 0;
volatile uint16_t roundsCounter = 0;
volatile uint16_t roundsPerSecond = 0;
volatile uint16_t roundsPerMinute = 0;
int main(void)
{
uint8_t maxFanSpeed = 255;
uint8_t minFanSpeed = 80;
fanSpeed = minFanSpeed;
double minTemperature = 23.5;
double maxTemperature = 24.6875;
DDRB |= (1 << PB1);
// set pd3 (INT1) as input
DDRD &= ~(1 << PD3);
// pull-up for pd2
PORTD |= (1 << PD3);
// Fast PWM mode
TCCR0 |= (1 << WGM01) | (1 << WGM00);
// OC0 enabled, clear on match
TCCR0 |= (1 << COM01) | (1 << COM00);
// timer0 clock source prescaler
TCCR0 |= (1 << CS00);
// pin OC0 as output
DDRB |= (1 << PB0);
STRONG_PULL_UP_DDR |= (1 << STRONG_PULL_UP_PIN);
// enable INT1 interrupt
GICR |= (1 << INT1);
TCCR1B |= (1 << WGM12) | (1 << CS12);
OCR1A = 32500;
TIMSK|=(1<<OCIE1A); //Output compare 1A interrupt enable
USART0Init();
// initialize interrupts
sei();
while(1)
{
PORTC &= ~(1 << 1);
ReadTemperature();
if (temperature < minTemperature && fanSpeed > minFanSpeed)
{
fanSpeed -= 1;
}
else if (temperature > maxTemperature && fanSpeed < maxFanSpeed - 20)
{
fanSpeed += 1;
}
OCR0 = 255 - fanSpeed;
if (send)
{
dtostrf(roundsCounter, 0,0, str);
UsartWrite(str);
UsartWrite("\r\n");
send = 0;
}
}
return 0;
}
ISR(INT1_vect)
{
roundsCounter++;
}
ISR(TIMER1_COMPA_vect)
{
DDRB ^= (1 << PB1);
roundsPerSecond = roundsCounter / 2;
roundsPerMinute = roundsPerSecond * 60;
roundsCounter = 0;
send = 1;
}
// onUsart
ISR(USART0_RXC_vect)
{
command = UDR0;
}
view raw rpm-interrupt.c hosted with ❤ by GitHub

Brak komentarzy:

Prześlij komentarz