diff --git a/lambda-test/command-test.c b/lambda-test/command-test.c index 6aaa59a..6187f5d 100644 --- a/lambda-test/command-test.c +++ b/lambda-test/command-test.c @@ -9,27 +9,78 @@ */ #include "avrjunit.h" +#include "alert.h" #include "command.h" +#include "display.h" +#include "interrupts.h" +#include "sensors.h" /* Module command */ bool testIsSimulation(void) { + extern bool updatePending; + + setupPorts(); + setHeatingOn(false); + assertFalse(isSimulation()); runCommand("se"); assertTrue(isSimulation()); + assertTrue(getTime() == 0); + assertTrue(isHeatingOn()); runCommand("sd"); assertFalse(isSimulation()); + assertTrue(getTime() == 0); + // assertFalse(isHeatingOn()); + + assertTrue(updatePending); return true; } bool testIsLogging(void) { + extern bool updatePending; + assertFalse(isLogging()); runCommand("le"); assertTrue(isLogging()); runCommand("ld"); assertFalse(isLogging()); + assertTrue(updatePending); + + return true; +} + +bool testHeating(void) { + extern bool updatePending; + + setupPorts(); + setHeatingOn(false); + + assertFalse(isHeatingOn()); + runCommand("he"); + assertTrue(isHeatingOn()); + runCommand("hd"); + assertFalse(isHeatingOn()); + + assertTrue(updatePending); + + return true; +} + +bool testCycleDisplay(void) { + extern uint8_t position; + extern bool updatePending; + + cancelAlert(true); + assertTrue(position == 0); + + cycleDisplay(); + assertTrue(position == 1); + + assertTrue(updatePending); + return true; } @@ -39,11 +90,15 @@ /* Test names */ static const char testIsSimulation_P[] PROGMEM = "testIsSimulation"; static const char testIsLogging_P[] PROGMEM = "testIsLogging"; +static const char testHeating_P[] PROGMEM = "testHeating"; +static const char testCycleDisplay_P[] PROGMEM = "testCycleDisplay"; /* Tests */ static TestCase const tests[] = { {class, testIsSimulation_P, testIsSimulation}, {class, testIsLogging_P, testIsLogging}, + {class, testHeating_P, testHeating}, + {class, testCycleDisplay_P, testCycleDisplay} }; TestClass commandClass = {tests, sizeof(tests) / sizeof(tests[0])}; diff --git a/lambda-test/display-test.c b/lambda-test/display-test.c index d1e7c7e..ce6be96 100644 --- a/lambda-test/display-test.c +++ b/lambda-test/display-test.c @@ -8,6 +8,7 @@ * */ +#include #include "avrjunit.h" #include "display.h" #include "sensors.h" @@ -23,6 +24,7 @@ extern uint16_t beepLength; cancelAlert(true); + position = 0; updatePending = false; assertTrue(position == 0); @@ -34,9 +36,12 @@ assertTrue(beepCount == 1); assertTrue(beepLength == 2); - cycleDisplay(); // 2 - cycleDisplay(); // 3 - cycleDisplay(); // 4 + cycleDisplay(); + assertTrue(position == 2); + cycleDisplay(); + assertTrue(position == 3); + cycleDisplay(); + assertTrue(position == 4); cycleDisplay(); // roll over to 0 assertTrue(position == 0); @@ -144,7 +149,6 @@ } bool testDisplayText(void) { - // won't actually display anything displayText("testDisplayText", "testDisplayTextLineTooLong"); return true; diff --git a/lambda-test/interrupts-test.c b/lambda-test/interrupts-test.c index af98d50..45fe032 100644 --- a/lambda-test/interrupts-test.c +++ b/lambda-test/interrupts-test.c @@ -8,6 +8,8 @@ * */ +#include +#include #include "avrjunit.h" #include "interrupts.h" @@ -77,6 +79,27 @@ return true; } +bool testTime(void) { + resetTime(); + assertTrue(getInts() == 0); + assertTrue(getTime() == 0); + + _delay_ms(1000); + + assertTrue(getInts() >= INTS_PER_SEC); + assertTrue(getTime() == 1); + + // add 1:11:10 + addInts(4270UL * INTS_PER_SEC); + + // HHHHH:MM:SS + char str[12]; + formatTime(str, sizeof(str)); + assertTrue(strcmp("1:11:11", str)); + + return true; +} + /* Test "class" */ static const char class[] PROGMEM = "interrupts"; @@ -85,6 +108,7 @@ static const char testSetupSleepMode_P[] PROGMEM = "testSetupSleepMode"; static const char testInitInterrupts_P[] PROGMEM = "testInitInterrupts"; static const char testInitTimers_P[] PROGMEM = "testInitTimers"; +static const char testTime_P[] PROGMEM = "testTime"; /* Tests */ static TestCase const tests[] = { @@ -92,6 +116,7 @@ {class, testSetupSleepMode_P, testSetupSleepMode}, {class, testInitInterrupts_P, testInitInterrupts}, {class, testInitTimers_P, testInitTimers}, + {class, testTime_P, testTime} }; TestClass interruptsClass = {tests, sizeof(tests) / sizeof(tests[0])}; diff --git a/lambda-test/sensors-test.c b/lambda-test/sensors-test.c index 736a59c..bfb20f1 100644 --- a/lambda-test/sensors-test.c +++ b/lambda-test/sensors-test.c @@ -17,6 +17,8 @@ #include "pins.h" #include "messages.h" +#include "usart.h" + static TableEntry const testTable[] = { {10, 10}, {20, 20} @@ -34,6 +36,8 @@ PORTC |= ((1 << ADC_TEMPI) | (1 << ADC_TEMPO) | (1 << ADC_LAMBDA) | (1 << ADC_HEATING)); + setHeatingState(HEATING_READY); + // do many measurements so the averaged voltages are near the measured // voltages (close to AREF) Measurement meas; @@ -46,7 +50,8 @@ assertTrue(meas.tempI >= 980 && meas.tempI <= 1000); assertTrue(meas.tempO == 400); assertTrue(meas.lambda >= 995 && meas.lambda <= 999); - assertTrue(meas.current >= 49000 && meas.current <= 50000); + // 5000 * (1000 / SHUNT_MILLIOHMS) = 45045 + assertTrue(meas.current >= 44500 && meas.current <= 45100); return true; } diff --git a/lambda/alert.h b/lambda/alert.h index 6aad976..b9cf38a 100644 --- a/lambda/alert.h +++ b/lambda/alert.h @@ -26,7 +26,8 @@ /** * Beeps the given number of beeps with the given length and tone and displays * the given two texts on the first and second line of the display, - * respectively, and keeps the alert active or not regardless of the beeps. + * respectively, and if keep is true, keeps the alert active until the next + * alert, when the button is pressed, only the beep stops. */ void alert(uint8_t beeps, uint8_t length, uint16_t tone, const char* line0, const char* line1, bool keep); diff --git a/lambda/interrupts.c b/lambda/interrupts.c index cb8b1fc..7993902 100644 --- a/lambda/interrupts.c +++ b/lambda/interrupts.c @@ -46,7 +46,7 @@ return atomicInts; } -void addInts(uint8_t const add) { +void addInts(uint32_t const add) { ATOMIC_BLOCK(ATOMIC_FORCEON) { ints += add; } diff --git a/lambda/interrupts.h b/lambda/interrupts.h index 8b7c6cb..c148fbb 100644 --- a/lambda/interrupts.h +++ b/lambda/interrupts.h @@ -24,7 +24,7 @@ * Adds the given number of interrupts to the interrupt counter * used as timebase. Useful only for simulation. */ -void addInts(uint8_t add); +void addInts(uint32_t add); /** * Returns the time in about seconds since last reset. diff --git a/lambda/messages.h b/lambda/messages.h index 3b04ec9..e08fbca 100644 --- a/lambda/messages.h +++ b/lambda/messages.h @@ -36,6 +36,8 @@ #define MSG_HEATING_READY_1 "ready" #define MSG_HEATING_FAULT_0 "Oxygen sensor" #define MSG_HEATING_FAULT_1 "heating fault!" + #define MSG_HEATING_OFF_0 "Oxygen sensor" + #define MSG_HEATING_OFF_1 "off" #define MSG_HEATING_CURRENT "Heater current" #define MSG_TIME_SINCE_START "Time since start" @@ -63,6 +65,8 @@ #define MSG_HEATING_READY_1 "bereit" #define MSG_HEATING_FAULT_0 "Lambdasonden-" #define MSG_HEATING_FAULT_1 "heizung Fehler!" + #define MSG_HEATING_OFF_0 "Oxygen sensor" + #define MSG_HEATING_OFF_1 "off" #define MSG_HEATING_CURRENT "Heizstrom" #define MSG_TIME_SINCE_START "Zeit seit Start" diff --git a/lambda/rules.c b/lambda/rules.c index 5376b51..778b24a 100644 --- a/lambda/rules.c +++ b/lambda/rules.c @@ -138,6 +138,8 @@ Measurement const meas) { if (isHeatingOn() && getTime() >= 10800 && meas.tempI < 400) { setHeatingOn(false); + alert_P(3, 10, TONE, PSTR(MSG_HEATING_OFF_0), + PSTR(MSG_HEATING_OFF_1), false); } } diff --git a/lambda/sensors.c b/lambda/sensors.c index 48ab4d8..b2ad47d 100644 --- a/lambda/sensors.c +++ b/lambda/sensors.c @@ -172,11 +172,11 @@ return value; } -int16_t linADC(uint16_t const mV) { +int32_t linADC(uint16_t const mV) { size_t size = sizeof(linADCTable) / sizeof(linADCTable[0]); int16_t dev = lookupLinInter(mV, linADCTable, size); - return (int16_t)mV - dev; + return (int32_t)mV - dev; } char* toInfo(uint16_t const lambda) { diff --git a/lambda/sensors.h b/lambda/sensors.h index a33a8b8..c6d6056 100644 --- a/lambda/sensors.h +++ b/lambda/sensors.h @@ -96,7 +96,7 @@ /** * Returns the given ADC measurement with compensated ADC non-linearity. */ -int16_t linADC(uint16_t mV); +int32_t linADC(uint16_t mV); /** * Returns a descriptive term such as "Lean" for the given lambda value x1000.