diff --git a/lambda/display.c b/lambda/display.c index cec6e23..2ee0b08 100644 --- a/lambda/display.c +++ b/lambda/display.c @@ -24,41 +24,18 @@ #define MENU_MAX_VALUES 2 uint8_t position = MENU_OFF; -char* hint = " "; -measurement measCur; + measurement measMin = {0, 20, 0, 20, 0, 2000}; measurement measMax = {0, 0, 0, 0, 0, 0}; -/** - * Cycles through the "menu" (display options) when the menu button is pressed. - */ -ISR(PCINT0_vect) { - if (bit_is_clear(PINB, PB0)) { - _delay_ms(30); - if (bit_is_clear(PINB, PB0)) { - cycle(); - } - } -} - void cycle(void) { position++; - if (position == MENU_MIN_VALUES) { - hint = " <"; - display(measMin); - } else if (position == MENU_MAX_VALUES) { - hint = " >"; - display(measMax); - } else { + if (position > MENU_MAX_VALUES) { position = MENU_OFF; - hint = " "; - display(measCur); } } void update(measurement meas) { - measCur = meas; - measMin.tempI = MIN(measMin.tempI, meas.tempI); measMin.tempO = MIN(measMin.tempO, meas.tempO); measMin.lambda = MIN(measMin.lambda, meas.lambda); @@ -67,21 +44,27 @@ measMax.tempO = MAX(measMax.tempO, meas.tempO); measMax.lambda = MAX(measMax.lambda, meas.lambda); - if (position == MENU_OFF) { - display(meas); + if (position == MENU_MIN_VALUES) { + display(measMin, " <"); + } else if (position == MENU_MAX_VALUES) { + display(measMax, " >"); + } else { + display(meas, " "); } } -void display(measurement meas) { - uint16_t lambdax100 = divRoundNearest(meas.lambda, 10); - div_t lambdaT = div(lambdax100, 100); - +void print(measurement meas) { char log[64]; snprintf(log, sizeof(log), - "Ti %3d C %4u - To %3d C %4u - L %4u %4u %s\r\n", + "Ti %3d C %4u - To %3d C %4u - L %4u %4u\r\n", meas.tempI, meas.tempIVoltage, meas.tempO, meas.tempOVoltage, - meas.lambda, meas.lambdaVoltage, hint); + meas.lambda, meas.lambdaVoltage); printString(log); +} + +void display(measurement meas, char hint[]) { + uint16_t lambdax100 = divRoundNearest(meas.lambda, 10); + div_t lambdaT = div(lambdax100, 100); char line0[17]; char line1[17]; diff --git a/lambda/display.h b/lambda/display.h index fcf1b66..2128f3d 100644 --- a/lambda/display.h +++ b/lambda/display.h @@ -15,14 +15,18 @@ /** * Updates the measurements, tracks min and max values since last start/reset - * and displays the current measurements unless the "menu" is active. + * and displays the selected measurement values. */ void update(measurement); /** - * Formats the given values, displays them on an 16x2 LCD - * and prints them over USART. + * Formats the given measurement values and prints them via USART. */ -void display(measurement); +void print(measurement); + +/** + * Formats the given measurement values and displays them on an 16x2 LCD. + */ +void display(measurement, char[]); #endif /* DISPLAY_H_ */ diff --git a/lambda/interrupts.c b/lambda/interrupts.c index c45d7ac..e2f330a 100644 --- a/lambda/interrupts.c +++ b/lambda/interrupts.c @@ -15,7 +15,7 @@ PORTB |= (1 << PB0); // PB1 as output - // DDRB |= (1 << PB1); + DDRB |= (1 << PB1); } void setupSleepMode(void) { @@ -27,9 +27,18 @@ ADCSRA |= (1 << ADIE); // enable PC interrupts - PCICR |= (1 << PCIE0); - PCMSK0 |= (1 << PB0); + // PCICR |= (1 << PCIE0); + // PCMSK0 |= (1 << PB0); + + // enable timer 0 overflow interrupt + TIMSK0 |= (1 << TOIE0); // enable global interrupts sei(); } + +void initTimers(void) { + // timer in normal mode is default + // timer clock prescaler /64 = 7.8 kHz overflowing every 32 ms + TCCR0B |= (1 << CS00) | (1 << CS01); +} diff --git a/lambda/interrupts.h b/lambda/interrupts.h index 2a14296..11efa34 100644 --- a/lambda/interrupts.h +++ b/lambda/interrupts.h @@ -23,4 +23,9 @@ */ void initInterrupts(void); +/** + * Inits the timers. + */ +void initTimers(void); + #endif /* INTERRUPTS_H_ */ diff --git a/lambda/lambda.c b/lambda/lambda.c index 3fe192b..e00635d 100644 --- a/lambda/lambda.c +++ b/lambda/lambda.c @@ -18,8 +18,10 @@ */ #include +#include #include #include +#include #include "USART.h" #include "lcdroutines.h" #include "adc.h" @@ -28,11 +30,28 @@ #include "integers.h" #include "display.h" +volatile bool buttonPressed = false; +volatile uint8_t updateCount = 0; +volatile uint8_t logCount = 0; + /** - * Initializes the USART transmitter and receiver, the lcd, sets up the ADC - * and sleep mode and then infinitely measures with a 1 second delay - * in between. - * TODO replace delay by a timer? + * Called every 16.32 ms. + */ +ISR(TIMER0_OVF_vect) { + updateCount++; + logCount++; + if (bit_is_clear(PINB, PB0) && ! buttonPressed) { + PORTB ^= (1 << PB1); + cycle(); + buttonPressed = true; + } else if (bit_is_set(PINB, PB0)) { + buttonPressed = false; + } +} + +/** + * Does initialization and measures, displays and logs the measurements + * infinitely. */ int main(void) { initUSART(); @@ -41,12 +60,19 @@ setupADC(); setupSleepMode(); initInterrupts(); + initTimers(); // main loop while (1) { - measurement meas = measure(); - update(meas); - _delay_ms(1000); + if (updateCount >= 6) { + updateCount = 0; + measurement meas = measure(); // about 50 ms + update(meas); // about 100 ms + if (logCount >= 61) { + logCount = 0; + print(meas); // about 400 ms + } + } } // never reached