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