diff --git a/lambda-test/.cproject b/lambda-test/.cproject
index 668c34f..1974a71 100644
--- a/lambda-test/.cproject
+++ b/lambda-test/.cproject
@@ -98,7 +98,6 @@
@@ -124,7 +123,9 @@
-
+
+
+
diff --git a/lambda-test/avrjunit.h b/lambda-test/avrjunit.h
index 6d7a838..ecd18fb 100644
--- a/lambda-test/avrjunit.h
+++ b/lambda-test/avrjunit.h
@@ -24,6 +24,8 @@
* DISCLAIMER: I'm experienced with Java and I like C, but I'm new here.
*/
+#include
+
#ifndef AVRJUNIT_H_
#define AVRJUNIT_H_
@@ -34,7 +36,7 @@
typedef struct {
char* class;
char* name;
- uint8_t (*test)(void);
+ bool (*test)(void);
} test;
/**
diff --git a/lambda-test/lambda-test.c b/lambda-test/lambda-test.c
index c0ad4a2..7c346ba 100644
--- a/lambda-test/lambda-test.c
+++ b/lambda-test/lambda-test.c
@@ -31,7 +31,9 @@
* http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
*/
+#include
#include
+#include
#include
#include
#include
@@ -49,18 +51,21 @@
/* Module adc */
-uint8_t testSetupADC(void) {
+bool testSetupADC(void) {
setupADC();
// AVCC is set as AREF
- return (ADMUX & (1 << REFS0)) == (1 << REFS0);
- // ADC clock prescaler/16
- return (ADCSRA & (1 << ADPS2)) == (1 << ADPS2);
+ if (! (ADMUX & (1 << REFS0)) == (1 << REFS0)) return false;
+ // ADC clock prescaler/8
+ uint8_t prescalerBy8 = (1 << ADPS1) | (1 << ADPS0);
+ if (! (ADCSRA & prescalerBy8) == prescalerBy8) return false;
// ADC enabled
- return (ADCSRA & (1 << ADEN)) == (1 << ADEN);
+ if (! (ADCSRA & (1 << ADEN)) == (1 << ADEN)) return false;
+
+ return true;
}
-uint8_t testSetupSleepMode(void) {
+bool testSetupSleepMode(void) {
setupSleepMode();
// don't know how to verify these
@@ -71,7 +76,7 @@
return (ADCSRA & (1 << ADIE)) == (1 << ADIE);
}
-uint8_t testGetVoltage(void) {
+bool testGetVoltage(void) {
setupADC();
setupSleepMode();
@@ -92,129 +97,159 @@
/* Module integers */
-uint8_t testDivRoundNearest(void) {
+bool testMeasure(void) {
+ setupADC();
+ setupSleepMode();
+
+ // enable pull-up resistor so the measured voltage
+ // should be (close to?) AREF
+ PORTC |= ((1 << PC5) | (1 << PC0) | (1 << PC2));
+
+ _delay_ms(10);
+
+ // do many measurements so the averaged voltages are near the measured
+ // voltages (close to AREF)
+ measurement meas;
+ for (uint8_t i = 0; i < 64; i++) {
+ meas = measure();
+ }
+
+ if (meas.tempIVoltage < 4900) return false;
+ if (meas.tempOVoltage < 4900) return false;
+ // lambdaVoltage is divided by the OP amplification factor 11
+ if (meas.lambdaVoltage < (4900 / 11)) return false;
+
+ // verify that temperatures and lambda are calculated correctly
+ if (meas.tempI != toTempI(meas.tempIVoltage)) return false;
+ if (meas.tempO != toTempO(meas.tempOVoltage)) return false;
+ if (meas.lambda != toLambda(meas.lambdaVoltage)) return false;
+
+ return true;
+}
+
+bool testDivRoundNearest(void) {
int32_t round = 0;
round = divRoundNearest(4, 2);
- if (round != 2) return 0;
+ if (round != 2) return false;
round = divRoundNearest(5, 2);
- if (round != 3) return 0;
+ if (round != 3) return false;
round = divRoundNearest(10, 3);
- if (round != 3) return 0;
+ if (round != 3) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundNearestNumNeg(void) {
+bool testDivRoundNearestNumNeg(void) {
int32_t round = 0;
round = divRoundNearest(-4, 2);
- if (round != -2) return 0;
+ if (round != -2) return false;
round = divRoundNearest(-5, 2);
- if (round != -3) return 0;
+ if (round != -3) return false;
round = divRoundNearest(-10, 3);
- if (round != -3) return 0;
+ if (round != -3) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundNearestDenNeg(void) {
+bool testDivRoundNearestDenNeg(void) {
int32_t round = 0;
round = divRoundNearest(4, -2);
- if (round != -2) return 0;
+ if (round != -2) return false;
round = divRoundNearest(5, -2);
- if (round != -3) return 0;
+ if (round != -3) return false;
round = divRoundNearest(10, -3);
- if (round != -3) return 0;
+ if (round != -3) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundNearestBothNeg(void) {
+bool testDivRoundNearestBothNeg(void) {
int32_t round = 0;
round = divRoundNearest(-4, -2);
- if (round != 2) return 0;
+ if (round != 2) return false;
round = divRoundNearest(-5, -2);
- if (round != 3) return 0;
+ if (round != 3) return false;
round = divRoundNearest(-10, -3);
- if (round != 3) return 0;
+ if (round != 3) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundUp(void) {
+bool testDivRoundUp(void) {
int32_t round = 0;
round = divRoundUp(4, 2);
- if (round != 2) return 0;
+ if (round != 2) return false;
round = divRoundUp(5, 2);
- if (round != 3) return 0;
+ if (round != 3) return false;
round = divRoundUp(10, 3);
- if (round != 4) return 0;
+ if (round != 4) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundUpNumNeg(void) {
+bool testDivRoundUpNumNeg(void) {
int32_t round = 0;
round = divRoundUp(-4, 2);
- if (round != -2) return 0;
+ if (round != -2) return false;
round = divRoundUp(-5, 2);
- if (round != -3) return 0;
+ if (round != -3) return false;
round = divRoundUp(-10, 3);
- if (round != -4) return 0;
+ if (round != -4) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundUpDenNeg(void) {
+bool testDivRoundUpDenNeg(void) {
int32_t round = 0;
round = divRoundUp(4, -2);
- if (round != -2) return 0;
+ if (round != -2) return false;
round = divRoundUp(5, -2);
- if (round != -3) return 0;
+ if (round != -3) return false;
round = divRoundUp(10, -3);
- if (round != -4) return 0;
+ if (round != -4) return false;
- return 1;
+ return true;
}
-uint8_t testDivRoundUpBothNeg(void) {
+bool testDivRoundUpBothNeg(void) {
int32_t round = 0;
round = divRoundUp(-4, -2);
- if (round != 2) return 0;
+ if (round != 2) return false;
round = divRoundUp(-5, -2);
- if (round != 3) return 0;
+ if (round != 3) return false;
round = divRoundUp(-10, -3);
- if (round != 4) return 0;
+ if (round != 4) return false;
- return 1;
+ return true;
}
/* Module sensors */
-uint8_t testAverageUp(void) {
+bool testAverageUp(void) {
int32_t value = 10;
int32_t avg = 0;
for (uint8_t i = 0; i < 14; i++) {
@@ -224,7 +259,7 @@
return divRoundNearest(avg, 16) == value;
}
-uint8_t testAverageDown(void) {
+bool testAverageDown(void) {
int32_t value = 0;
int32_t avg = (10 << 4);
for (uint8_t i = 0; i < 14; i++) {
@@ -234,73 +269,91 @@
return divRoundNearest(avg, 16) == value;
}
-uint8_t testAverageDoesNotWrap(void) {
+bool testAverageDoesNotWrap(void) {
int32_t value = 5000;
int32_t avg = (value << 4);
- avg = average((value << 4), avg, 8);
+ avg = average((value << 4), avg, 16);
return divRoundNearest(avg, 16) == value;
}
-uint8_t testToLambdaValue(void) {
+bool testToLambdaValue(void) {
int16_t lambda = toLambda(12);
return lambda == 1500;
}
-uint8_t testToLambdaInter(void) {
+bool testToLambdaInter(void) {
int16_t lambda = toLambda(50);
return lambda == 1073;
}
-uint8_t testToTempI(void) {
+bool testToTempI(void) {
int16_t temp = toTempI(100);
return temp == 20;
}
-uint8_t testToTempOValue(void) {
+bool testToTempOValue(void) {
int16_t temp = toTempO(454);
return temp == 0;
}
-uint8_t testToTempOInter(void) {
+bool testToTempOInter(void) {
int16_t temp = toTempO(929);
return temp == 50;
}
-uint8_t testLookupLinInterBelow(void) {
+bool testLookupLinInterBelow(void) {
int16_t value = lookupLinInter(-5, testTable, 2);
return value == 0;
}
-uint8_t testLookupLinInterAbove(void) {
+bool testLookupLinInterAbove(void) {
int16_t value = lookupLinInter(15, testTable, 2);
return value == 10;
}
-uint8_t testLookupLinInterValue(void) {
+bool testLookupLinInterValue(void) {
int16_t value = lookupLinInter(10, testTable, 2);
return value == 10;
}
-uint8_t testLookupLinInterInter(void) {
+bool testLookupLinInterInter(void) {
int16_t value = lookupLinInter(3, testTable, 2);
return value == 3;
}
+bool testToInfoLean(void) {
+ const char* info = toInfo(1600);
+
+ return ! strcmp(info, LEAN);
+}
+
+bool testToInfoIdeal(void) {
+ const char* info = toInfo(1400);
+
+ return ! strcmp(info, IDEAL);
+}
+
+bool testToInfoRich(void) {
+ const char* info = toInfo(1200);
+
+ return ! strcmp(info, RICH);
+}
+
// these long function names passed along as strings use a lot of memory
test tests[] = {
{"adc", "testSetupADC", testSetupADC},
- {"adc", "testGetVoltage", testGetVoltage},
{"adc", "testSetupSleepMode", testSetupSleepMode},
+ {"adc", "testGetVoltage", testGetVoltage},
{"integers", "testDivRoundNearest", testDivRoundNearest},
{"integers", "testDivRoundNearestNumNeg", testDivRoundNearestNumNeg},
{"integers", "testDivRoundNearestDenNeg", testDivRoundNearestDenNeg},
@@ -309,6 +362,7 @@
{"integers", "testDivRoundUpNumNeg", testDivRoundUpNumNeg},
{"integers", "testDivRoundUpDenNeg", testDivRoundUpDenNeg},
{"integers", "testDivRoundUpBothNeg", testDivRoundUpBothNeg},
+ {"sensors", "testMeasure", testMeasure},
{"sensors", "testAverageUp", testAverageUp},
{"sensors", "testAverageDown", testAverageDown},
{"sensors", "testAverageDoesNotWrap", testAverageDoesNotWrap},
@@ -320,7 +374,10 @@
{"sensors", "testLookupLinInterValue", testLookupLinInterValue},
{"sensors", "testLookupLinInterInter", testLookupLinInterInter},
{"sensors", "testLookupLinInterBelow", testLookupLinInterBelow},
- {"sensors", "testLookupLinInterAbove", testLookupLinInterAbove}
+ {"sensors", "testLookupLinInterAbove", testLookupLinInterAbove},
+ {"sensors", "testToInfoLean", testToInfoLean},
+ {"sensors", "testToInfoIdeal", testToInfoIdeal},
+ {"sensors", "testToInfoRich", testToInfoRich}
};
int main(void) {
diff --git a/lambda/.cproject b/lambda/.cproject
index 53d0420..2e6c620 100644
--- a/lambda/.cproject
+++ b/lambda/.cproject
@@ -63,7 +63,9 @@
-
+
+
+
@@ -85,7 +87,7 @@
-
@@ -93,9 +95,7 @@
-
+
diff --git a/lambda/adc.c b/lambda/adc.c
index b11adb7..913a6a4 100644
--- a/lambda/adc.c
+++ b/lambda/adc.c
@@ -34,10 +34,8 @@
void setupADC(void) {
// use AVCC as reference voltage
ADMUX |= (1 << REFS0);
- // ADC clock prescaler/64
- // ADCSRA |= (1 << ADPS1) | (1 << ADPS2);
- // ADC clock prescaler/16
- ADCSRA |= (1 << ADPS2);
+ // ADC clock prescaler/8
+ ADCSRA |= (1 << ADPS1) | (1 << ADPS0);
// enable ADC
ADCSRA |= (1 << ADEN);
}
diff --git a/lambda/lambda.c b/lambda/lambda.c
index 1e121fe..064d218 100644
--- a/lambda/lambda.c
+++ b/lambda/lambda.c
@@ -59,7 +59,8 @@
// main loop
while (1) {
- measure();
+ measurement meas = measure();
+ display(meas);
_delay_ms(1000);
}
diff --git a/lambda/sensors.c b/lambda/sensors.c
index a43375b..33383aa 100644
--- a/lambda/sensors.c
+++ b/lambda/sensors.c
@@ -82,49 +82,54 @@
/**
* Measures the "input" and "output" temperatures and the lambda value
* and displays the measured values.
- * TODO tests, with local implementation of getVoltage()?
*/
-void measure(void) {
- int16_t tempIVoltage = getVoltage(PC5);
+measurement measure(void) {
+ int32_t tempIVoltage = getVoltage(PC5);
tempIVoltageAvg = average((tempIVoltage << 4), tempIVoltageAvg, 4);
- int16_t tempOVoltage = getVoltage(PC0);
+ int32_t tempOVoltage = getVoltage(PC0);
tempOVoltageAvg = average((tempOVoltage << 4), tempOVoltageAvg, 4);
// OP factor is 11
- int16_t lambdaVoltage = divRoundNearest(getVoltage(PC2), 11);
+ int32_t lambdaVoltage = divRoundNearest(getVoltage(PC2), 11);
lambdaVoltageAvg = average((lambdaVoltage << 4), lambdaVoltageAvg, 4);
- int16_t tempIVoltageAvgDiv = divRoundNearest(tempIVoltageAvg, 16);
- int16_t tempOVoltageAvgDiv = divRoundNearest(tempOVoltageAvg, 16);
- int16_t lambdaVoltageAvgDiv = divRoundNearest(lambdaVoltageAvg, 16);
+ // TODO just for testing, remove at some point
+ char log[64];
+ snprintf(log, sizeof(log),
+ "Ti %3d C %4ld - To %3d C %4ld - L %4ld\r\n",
+ toTempI(tempIVoltage), tempIVoltage,
+ toTempO(tempOVoltage), tempOVoltage,
+ lambdaVoltage);
+ // printString(log);
- int16_t tempI = toTempI(tempIVoltageAvgDiv);
- int16_t tempO = toTempO(tempOVoltageAvgDiv);
- int16_t lambda = toLambda(lambdaVoltageAvgDiv);
+ measurement meas;
+ meas.tempIVoltage = divRoundNearest(tempIVoltageAvg, 16);
+ meas.tempOVoltage = divRoundNearest(tempOVoltageAvg, 16);
+ meas.lambdaVoltage = divRoundNearest(lambdaVoltageAvg, 16);
- display(tempIVoltageAvgDiv, tempI,
- tempOVoltageAvgDiv, tempO,
- lambdaVoltageAvgDiv, lambda);
+ meas.tempI = toTempI(meas.tempIVoltage);
+ meas.tempO = toTempO(meas.tempOVoltage);
+ meas.lambda = toLambda(meas.lambdaVoltage);
+
+ return meas;
}
-void display(
- int16_t tempIVoltage, int16_t tempI,
- int16_t tempOVoltage, int16_t tempO,
- int16_t lambdaVoltage, int16_t lambda) {
- div_t lambdaT = div(lambda, 1000);
+void display(measurement meas) {
+ div_t lambdaT = div(meas.lambda, 1000);
char log[64];
- 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);
+ snprintf(log, sizeof(log),
+ "Ti %3d C %4d - To %3d C %4d - L %d.%03d %4d\r\n",
+ meas.tempI, meas.tempIVoltage, meas.tempO, meas.tempOVoltage,
+ lambdaT.quot, abs(lambdaT.rem), meas.lambdaVoltage);
printString(log);
char line0[17];
char line1[17];
- snprintf(line0, sizeof(line0), "Ti %3dC To %3dC", tempI, tempO);
- snprintf(line1, sizeof(line1), "L %d.%03d %s",
- lambdaT.quot, abs(lambdaT.rem), toInfo(lambda));
+ snprintf(line0, sizeof(line0), "Ti %3dC To %3dC ", meas.tempI, meas.tempO);
+ snprintf(line1, sizeof(line1), "L %d.%03d %s ",
+ lambdaT.quot, abs(lambdaT.rem), toInfo(meas.lambda));
lcd_setcursor(0, 1);
lcd_string(line0);
lcd_setcursor(0, 2);
@@ -171,8 +176,8 @@
int16_t diffVoltage = table[i + 1].mV - table[i].mV;
int16_t diffValue = table[i + 1].value - table[i].value;
- int16_t value = table[i].value +
- divRoundNearest((int32_t)(mV - table[i].mV) * diffValue, diffVoltage);
+ int16_t value = table[i].value + divRoundNearest(
+ (int32_t)(mV - table[i].mV) * diffValue, diffVoltage);
return value;
}
diff --git a/lambda/sensors.h b/lambda/sensors.h
index 84fc027..a14991e 100644
--- a/lambda/sensors.h
+++ b/lambda/sensors.h
@@ -29,8 +29,8 @@
// TODO put in Makefile?
#define LEAN "Mager"
-#define IDEAL "Ideal";
-#define RICH "Fett!";
+#define IDEAL "Ideal"
+#define RICH "Fett!"
/**
* Entry for the lookup tables.
@@ -41,19 +41,28 @@
} tableEntry;
/**
+ * Measured values.
+ */
+typedef struct {
+ int16_t tempIVoltage;
+ int16_t tempI;
+ int16_t tempOVoltage;
+ int16_t tempO;
+ int16_t lambdaVoltage;
+ int16_t lambda;
+} measurement;
+
+/**
* Measures the "input" and "output" temperatures and the lambda value
* and displays the measured values.
*/
-void measure(void);
+measurement measure(void);
/**
* Formats the given values, displays them on an 16x2 LCD
* and prints them over USART.
*/
-void display(
- int16_t tempIVoltage, int16_t tempI,
- int16_t tempOVoltage, int16_t tempO,
- int16_t lambdaVoltage, int16_t lambda);
+void display(measurement);
/**
* Creates an exponential moving average of the given value and