diff --git a/lambda-test/avrjunit.c b/lambda-test/avrjunit.c index f86e0bc..dd3e11a 100644 --- a/lambda-test/avrjunit.c +++ b/lambda-test/avrjunit.c @@ -9,15 +9,15 @@ #include "USART.h" #include "avrjunit.h" -void runTests(char* suite, char* class, test tests[], int count) { +void runTests(char* suite, char* class, test tests[], uint16_t count) { printString("\n"); - char tsbuf[64]; + char tsbuf[128]; snprintf(tsbuf, sizeof(tsbuf), "\n", suite, count); printString(tsbuf); - for (int i = 0; i < count; i++) { + for (uint16_t i = 0; i < count; i++) { int result = (*tests[i].test)(); - char tcbuf[64]; + char tcbuf[128]; snprintf(tcbuf, sizeof(tcbuf), "\n", class, tests[i].name); printString(tcbuf); if (! result) { diff --git a/lambda-test/avrjunit.h b/lambda-test/avrjunit.h index 12a3b2b..a201fcc 100644 --- a/lambda-test/avrjunit.h +++ b/lambda-test/avrjunit.h @@ -11,7 +11,7 @@ */ typedef struct { char* name; - int (*test)(void); + uint8_t (*test)(void); } test; /** @@ -23,4 +23,4 @@ * on the receiving side with a command like: * (stty sane; cat > tests.xml) < /dev/ttyUSB0 */ -void runTests(char* suite, char* class, test tests[], int count); +void runTests(char* suite, char* class, test tests[], uint16_t count); diff --git a/lambda-test/lambda-test.c b/lambda-test/lambda-test.c index 077a6f1..8131aad 100644 --- a/lambda-test/lambda-test.c +++ b/lambda-test/lambda-test.c @@ -17,56 +17,56 @@ {10, 10} }; -int testToLambdaValue(void) { - float lambda = toLambda(12); +uint8_t testToLambdaValue(void) { + int16_t lambda = toLambda(12); - return lambda == 1.5; + return lambda == 1500; } -int testToLambdaInter(void) { - float lambda = toLambda(50); +uint8_t testToLambdaInter(void) { + int16_t lambda = toLambda(50); - return round(lambda * 1000) == 1073; + return lambda == 1073; } -int testToTempI(void) { - int temp = toTempI(100); +uint8_t testToTempI(void) { + int16_t temp = toTempI(100); return temp == 20; } -int testToTempOValue(void) { - int temp = toTempO(454); +uint8_t testToTempOValue(void) { + int16_t temp = toTempO(454); return temp == 0; } -int testToTempOInter(void) { - int temp = toTempO(928); +uint8_t testToTempOInter(void) { + int16_t temp = toTempO(929); return temp == 50; } -int testLookupLinInterBelow(void) { - float value = lookupLinInter(-5, testTable, 2); +uint8_t testLookupLinInterBelow(void) { + int16_t value = lookupLinInter(-5, testTable, 2); return value == 0; } -int testLookupLinInterAbove(void) { - float value = lookupLinInter(15, testTable, 2); +uint8_t testLookupLinInterAbove(void) { + int16_t value = lookupLinInter(15, testTable, 2); return value == 10; } -int testLookupLinInterValue(void) { - float value = lookupLinInter(10, testTable, 2); +uint8_t testLookupLinInterValue(void) { + int16_t value = lookupLinInter(10, testTable, 2); return value == 10; } -int testLookupLinInterInter(void) { - float value = lookupLinInter(3, testTable, 2); +uint8_t testLookupLinInterInter(void) { + int16_t value = lookupLinInter(3, testTable, 2); return value == 3; } @@ -86,7 +86,7 @@ int main(void) { initUSART(); - int count = sizeof(tests) / sizeof(tests[0]); + uint16_t count = sizeof(tests) / sizeof(tests[0]); runTests("lambda", "sensors", tests, count); return 0; diff --git a/lambda/.gitignore b/lambda/.gitignore index 35dd070..afd821e 100644 --- a/lambda/.gitignore +++ b/lambda/.gitignore @@ -1,4 +1,4 @@ /Debug/ /Release/ -/lambda-test.elf -/lambda-test.hex +/lambda.elf +/lambda.hex diff --git a/lambda/lambda.c b/lambda/lambda.c index fee76b1..9a98d9c 100644 --- a/lambda/lambda.c +++ b/lambda/lambda.c @@ -4,12 +4,9 @@ * Created on: 22.02.2015 * Author: dode@luniks.net * - * TODO try starting ADC sample manually and wait for it to finish - * TODO try to remove floating points - * TODO refactoring - module? * TODO comments, attribution * TODO DIDR? - * TODO unit tests, Jenkins? + * TODO How to round integer divisions half up? */ #include #include @@ -21,9 +18,9 @@ #include "USART.h" #include "sensors.h" -float lambdaVoltageAvg = 0.0; -float tempIVoltageAvg = 0.0; -float tempOVoltageAvg = 0.0; +int16_t lambdaVoltageAvg = 0; +int16_t tempIVoltageAvg = 0; +int16_t tempOVoltageAvg = 0; EMPTY_INTERRUPT(ADC_vect); @@ -41,38 +38,36 @@ } void display( - int tempIVoltage, int tempI, - int tempOVoltage, int tempO, - float lambdaVoltage, float lambda) { - char lambdaStr[13]; - dtostrf(lambda, 5, 3, lambdaStr); - char lambdaVoltageStr[13]; - dtostrf(lambdaVoltage, 5, 3, lambdaVoltageStr); + int16_t tempIVoltage, int16_t tempI, + int16_t tempOVoltage, int16_t tempO, + int16_t lambdaVoltage, int16_t lambda) { + int8_t lambdaI = lambda / 1000; + int16_t lambdaR = lambda % 1000; + // TODO chars per line 16 char line0[40]; char line1[40]; snprintf(line0, sizeof(line0), "Ti %3d C %d To %3d C %d\r\n", tempI, tempIVoltage, tempO, tempOVoltage); - snprintf(line1, sizeof(line1), "L %s (%s)\r\n", lambdaStr, lambdaVoltageStr); + snprintf(line1, sizeof(line1), "L %d.%03d %d\r\n", lambdaI, lambdaR, lambdaVoltage); printString(line0); printString(line1); } void measure(void) { - float lambdaVoltage = getVoltage(PC2) / 11.0; - lambdaVoltageAvg = (lambdaVoltage + lambdaVoltageAvg * 8) / 9; + int16_t tempIVoltage = getVoltage(PC5); + tempIVoltageAvg = (tempIVoltage + (tempIVoltageAvg << 1)) / 3; - int tempIVoltage = getVoltage(PC5); - tempIVoltageAvg = (tempIVoltage + tempIVoltageAvg * 2) / 3; + int16_t tempOVoltage = getVoltage(PC0); + tempOVoltageAvg = (tempOVoltage + (tempOVoltageAvg << 1)) / 3; - int tempOVoltage = getVoltage(PC0); - tempOVoltageAvg = (tempOVoltage + tempOVoltageAvg * 2) / 3; + int16_t lambdaVoltage = getVoltage(PC2) / 11; + lambdaVoltageAvg = (lambdaVoltage + (lambdaVoltageAvg << 3)) / 9; - int tempI = toTempI(tempIVoltage); - int tempO = toTempO(tempOVoltage); - float lambda = toLambda(lambdaVoltage); - // round(lambda * 10) / 10.0; + int16_t tempI = toTempI(tempIVoltageAvg); + int16_t tempO = toTempO(tempOVoltageAvg); + int16_t lambda = toLambda(lambdaVoltageAvg); - display(tempIVoltage, tempI, tempOVoltage, tempO, lambdaVoltage, lambda); + display(tempIVoltageAvg, tempI, tempOVoltageAvg, tempO, lambdaVoltageAvg, lambda); } int main(void) { diff --git a/lambda/sensors.c b/lambda/sensors.c index 1b42962..b2b1eca 100644 --- a/lambda/sensors.c +++ b/lambda/sensors.c @@ -12,6 +12,9 @@ #include #include "sensors.h" +#include +#include "USART.h" + // #define AREF_MV 4850 #define AREF_MV 5000 #define ADC_OFFSET_MV 7 @@ -29,21 +32,21 @@ * TODO equation? real table? */ static const tableEntry lambdaTable[] = { - { 4, 2.0 }, - { 5, 1.9 }, - { 6, 1.8 }, - { 8, 1.7 }, - { 10, 1.6 }, - { 12, 1.5 }, - { 15, 1.4 }, - { 20, 1.3 }, - { 28, 1.2 }, - { 40, 1.1 }, - { 68, 1.025 }, - { 400, 1.0 }, - { 800, 0.98 }, - { 860, 0.9 }, - { 880, 0.8 } + { 4, 2000 }, + { 5, 1900 }, + { 6, 1800 }, + { 8, 1700 }, + { 10, 1600 }, + { 12, 1500 }, + { 15, 1400 }, + { 20, 1300 }, + { 28, 1200 }, + { 40, 1100 }, + { 68, 1025 }, + { 400, 1000 }, + { 800, 980 }, + { 860, 900 }, + { 880, 800 } }; static const tableEntry tempOTable[] = { @@ -55,67 +58,66 @@ { 3762, 400 } }; -int getVoltage(int port) { +int16_t getVoltage(uint8_t port) { ADMUX = (0b11110000 & ADMUX) | port; - unsigned long overValue = 0; - for (int i = 0; i < 16; i++) { + uint32_t overValue = 0; + for (uint8_t i = 0; i < 16; i++) { sleep_mode(); overValue += ADC; } - float mV = ((overValue >> 2) * AREF_MV / 4096) + ADC_OFFSET_MV; + int16_t mV = ((overValue >> 2) * AREF_MV / 4096) + ADC_OFFSET_MV; return mV; } -float toLambda(float mV) { - int length = sizeof(lambdaTable) / sizeof(lambdaTable[0]); - float lambda = lookupLinInter(mV, lambdaTable, length); +int16_t toLambda(int16_t mV) { + uint8_t length = sizeof(lambdaTable) / sizeof(lambdaTable[0]); + int16_t lambda = lookupLinInter(mV, lambdaTable, length); return lambda; } -int toTempI(float mV) { - int temp = round(mV / 5); +int16_t toTempI(int16_t mV) { + int temp = mV / 5; return temp; } -int toTempO(float mV) { - int length = sizeof(tempOTable) / sizeof(tempOTable[0]); - float c = lookupLinInter(mV, tempOTable, length); - int temp = round(c); +int16_t toTempO(int16_t mV) { + uint8_t length = sizeof(tempOTable) / sizeof(tempOTable[0]); + int16_t temp = lookupLinInter(mV, tempOTable, length); return temp; } -float lookupLinInter(float mV, const tableEntry table[], int length) { +int16_t lookupLinInter(int16_t mV, const tableEntry table[], uint8_t length) { if (mV < table[0].mV) { return table[0].value; } else if (mV > table[length - 1].mV) { return table[length - 1].value; } - int i = 0; + uint8_t i = 0; for (; i < length - 1; i++) { if (table[i + 1].mV > mV) { break; } } - float diffVoltage = table[i + 1].mV - table[i].mV; - float diffValue = table[i + 1].value - table[i].value; - float value = table[i].value + - (mV - table[i].mV) * diffValue / diffVoltage; + int16_t diffVoltage = table[i + 1].mV - table[i].mV; + int32_t diffValue = table[i + 1].value - table[i].value; + int16_t value = table[i].value + + (((mV - table[i].mV) * (diffValue << 10) / diffVoltage) >> 10); return value; } -const char* toInfo(float lambda) { - if (lambda > 1.5) { +const char* toInfo(int16_t lambda) { + if (lambda > 1500) { return lean; - } else if (lambda > 1.3 && lambda <= 1.5) { + } else if (lambda > 1300 && lambda <= 1500) { return ideal; } else { return rich; diff --git a/lambda/sensors.h b/lambda/sensors.h index 03536cc..6a84d25 100644 --- a/lambda/sensors.h +++ b/lambda/sensors.h @@ -5,22 +5,22 @@ * Author: dode@luniks.net */ typedef struct { - const int mV; - const float value; + const int16_t mV; + const int16_t value; } tableEntry; -int getVoltage(int port); +int16_t getVoltage(uint8_t port); -float toLambda(float mV); +int16_t toLambda(int16_t mV); /** * Returns the temperature for the given voltage of a type K thermocouple * amplified with an AD8495 (5 mV/°C). Type K thermocouple voltages are * about linear between 0 and 800°C. */ -int toTempI(float mV); +int16_t toTempI(int16_t mV); -int toTempO(float mV); +int16_t toTempO(int16_t mV); /** * Returns the value corresponding to the given voltage @@ -28,6 +28,6 @@ * Thanks to http://stackoverflow.com/a/7091629/709426 and * http://en.wikipedia.org/wiki/Linear_interpolation */ -float lookupLinInter(float mV, const tableEntry table[], int length); +int16_t lookupLinInter(int16_t mV, const tableEntry table[], uint8_t length); -const char* toInfo(float lambda); +const char* toInfo(int16_t lambda);