diff --git a/lambda-test/Makefile b/lambda-test/Makefile index a533629..d5fcefd 100644 --- a/lambda-test/Makefile +++ b/lambda-test/Makefile @@ -28,7 +28,7 @@ PROGRAMMER_TYPE = avrisp # extra arguments to avrdude: baud rate, chip type, -F flag, etc. -PROGRAMMER_ARGS = -b 19200 -P /dev/ttyACM0 +PROGRAMMER_ARGS = -b 19200 -P /dev/ttyACM3 ##########------------------------------------------------------########## ########## Makefile Magic! ########## diff --git a/lambda-test/avrjunit.c b/lambda-test/avrjunit.c index 6177d9c..dd177eb 100644 --- a/lambda-test/avrjunit.c +++ b/lambda-test/avrjunit.c @@ -46,7 +46,7 @@ printString(tcbuf); if (! result) { // failure - printString("Test failed\n"); + printString("failed\n"); } printString("\n"); } diff --git a/lambda-test/lambda-test.c b/lambda-test/lambda-test.c index 56b55f5..c0ad4a2 100644 --- a/lambda-test/lambda-test.c +++ b/lambda-test/lambda-test.c @@ -87,7 +87,7 @@ int16_t mV = getVoltage(PC1); - return mV > 4950; + return mV > 4900; } /* Module integers */ @@ -214,24 +214,32 @@ /* Module sensors */ -uint8_t testAverage(void) { - int16_t avg = 0; - avg = average(8, avg, 4); - if (avg != 2) { return 0; } - avg = average(8, avg, 4); - if (avg != 4) { return 0; } - avg = average(8, avg, 4); - if (avg != 5) { return 0; } - avg = average(8, avg, 4); - if (avg != 6) { return 0; } - avg = average(8, avg, 4); - if (avg != 7) { return 0; } - avg = average(8, avg, 4); - if (avg != 8) { return 0; } - avg = average(8, avg, 4); - if (avg != 8) { return 0; } +uint8_t testAverageUp(void) { + int32_t value = 10; + int32_t avg = 0; + for (uint8_t i = 0; i < 14; i++) { + avg = average((value << 4), avg, 4); + } - return 1; + return divRoundNearest(avg, 16) == value; +} + +uint8_t testAverageDown(void) { + int32_t value = 0; + int32_t avg = (10 << 4); + for (uint8_t i = 0; i < 14; i++) { + avg = average((value << 4), avg, 4); + } + + return divRoundNearest(avg, 16) == value; +} + +uint8_t testAverageDoesNotWrap(void) { + int32_t value = 5000; + int32_t avg = (value << 4); + avg = average((value << 4), avg, 8); + + return divRoundNearest(avg, 16) == value; } uint8_t testToLambdaValue(void) { @@ -288,6 +296,7 @@ return value == 3; } +// these long function names passed along as strings use a lot of memory test tests[] = { {"adc", "testSetupADC", testSetupADC}, {"adc", "testGetVoltage", testGetVoltage}, @@ -300,7 +309,9 @@ {"integers", "testDivRoundUpNumNeg", testDivRoundUpNumNeg}, {"integers", "testDivRoundUpDenNeg", testDivRoundUpDenNeg}, {"integers", "testDivRoundUpBothNeg", testDivRoundUpBothNeg}, - {"sensors", "testAverage", testAverage}, + {"sensors", "testAverageUp", testAverageUp}, + {"sensors", "testAverageDown", testAverageDown}, + {"sensors", "testAverageDoesNotWrap", testAverageDoesNotWrap}, {"sensors", "testToLambdaValue", testToLambdaValue}, {"sensors", "testToLambdaInter", testToLambdaInter}, {"sensors", "testToTempI", testToTempI}, diff --git a/lambda/sensors.c b/lambda/sensors.c index 71a8bbb..a43375b 100644 --- a/lambda/sensors.c +++ b/lambda/sensors.c @@ -75,9 +75,9 @@ /** * Global variables holding averaged voltages. */ -int16_t lambdaVoltageAvg = 0; -int16_t tempIVoltageAvg = 0; -int16_t tempOVoltageAvg = 0; +int32_t lambdaVoltageAvg = 0; +int32_t tempIVoltageAvg = 0; +int32_t tempOVoltageAvg = 0; /** * Measures the "input" and "output" temperatures and the lambda value @@ -86,30 +86,26 @@ */ void measure(void) { int16_t tempIVoltage = getVoltage(PC5); - tempIVoltageAvg = average(tempIVoltage, tempIVoltageAvg, 8); + tempIVoltageAvg = average((tempIVoltage << 4), tempIVoltageAvg, 4); int16_t tempOVoltage = getVoltage(PC0); - tempOVoltageAvg = average(tempOVoltage, tempOVoltageAvg, 4); + tempOVoltageAvg = average((tempOVoltage << 4), tempOVoltageAvg, 4); // OP factor is 11 int16_t lambdaVoltage = divRoundNearest(getVoltage(PC2), 11); - lambdaVoltageAvg = average(lambdaVoltage, lambdaVoltageAvg, 4); + lambdaVoltageAvg = average((lambdaVoltage << 4), lambdaVoltageAvg, 4); - // TODO just for testing, remove at some point - char log[64]; - snprintf(log, sizeof(log), "Direct: Ti %3d C %4d - To %3d C %4d - L %4d\r\n", - toTempI(tempIVoltage), tempIVoltage, - toTempO(tempOVoltage), tempOVoltage, - lambdaVoltage); - printString(log); + int16_t tempIVoltageAvgDiv = divRoundNearest(tempIVoltageAvg, 16); + int16_t tempOVoltageAvgDiv = divRoundNearest(tempOVoltageAvg, 16); + int16_t lambdaVoltageAvgDiv = divRoundNearest(lambdaVoltageAvg, 16); - int16_t tempI = toTempI(tempIVoltageAvg); - int16_t tempO = toTempO(tempOVoltageAvg); - int16_t lambda = toLambda(lambdaVoltageAvg); + int16_t tempI = toTempI(tempIVoltageAvgDiv); + int16_t tempO = toTempO(tempOVoltageAvgDiv); + int16_t lambda = toLambda(lambdaVoltageAvgDiv); - display(tempIVoltageAvg, tempI, - tempOVoltageAvg, tempO, - lambdaVoltageAvg, lambda); + display(tempIVoltageAvgDiv, tempI, + tempOVoltageAvgDiv, tempO, + lambdaVoltageAvgDiv, lambda); } void display( @@ -119,7 +115,7 @@ div_t lambdaT = div(lambda, 1000); char log[64]; - snprintf(log, sizeof(log), "Averag: Ti %3d C %4d - To %3d C %4d - L %d.%03d %4d\r\n", + snprintf(log, sizeof(log), "Ti %3d C %4d - To %3d C %4d - L %d.%03d %4d\r\n", tempI, tempIVoltage, tempO, tempOVoltage, lambdaT.quot, abs(lambdaT.rem), lambdaVoltage); printString(log); @@ -135,8 +131,8 @@ lcd_string(line1); } -int16_t average(int16_t value, int16_t average, uint8_t weight) { - return divRoundUp(value + (average * weight), weight + 1); +int32_t average(int32_t value, int32_t average, uint8_t weight) { + return divRoundNearest(value + (average * weight), weight + 1); } int16_t toTempI(int16_t mV) { diff --git a/lambda/sensors.h b/lambda/sensors.h index 2f6fd4a..84fc027 100644 --- a/lambda/sensors.h +++ b/lambda/sensors.h @@ -59,7 +59,7 @@ * Creates an exponential moving average of the given value and * average weighted by the given weight. */ -int16_t average(int16_t value, int16_t average, uint8_t weight); +int32_t average(int32_t value, int32_t average, uint8_t weight); /** * Returns the temperature for the given voltage of a type K thermocouple