diff --git a/lambda-test/Makefile b/lambda-test/Makefile index 8ae915a..232a947 100644 --- a/lambda-test/Makefile +++ b/lambda-test/Makefile @@ -22,7 +22,7 @@ ## Link to directory of project under test and its source files TEST_SOURCE_DIR = /data/Job/git/lambda-avr/lambda/ -TEST_SOURCE_FILES = sensors.c integers.c +TEST_SOURCE_FILES = adc.c sensors.c integers.c ##########------------------------------------------------------########## ########## Programmer Defaults ########## diff --git a/lambda-test/lambda-test.c b/lambda-test/lambda-test.c index 4de9c68..aee211f 100644 --- a/lambda-test/lambda-test.c +++ b/lambda-test/lambda-test.c @@ -7,8 +7,10 @@ */ #include -// #include +#include +#include #include "USART.h" +#include "adc.h" #include "sensors.h" #include "avrjunit.h" @@ -17,6 +19,22 @@ {10, 10} }; +uint8_t testGetVoltage(void) { + // enable pull-up resistor so the measured voltage + // should be (close to?) to AREF + PORTC |= (1 << PC1); + // PORTC = 0xff; + + // it seems that sleep_mode() causes some interference when called + // immediately after sending data over USART - some buffer not yet empty? + // loop_until_bit_is_set(UCSR0A, UDRE0); + _delay_ms(10); + + int16_t mV = getVoltage(PC1); + + return mV > 4950; +} + uint8_t testAverage(void) { int16_t avg = 0; avg = average(8, avg, 4); @@ -92,6 +110,7 @@ } test tests[] = { + {"testGetVoltage", testGetVoltage}, {"testAverage", testAverage}, {"testToLambdaValue", testToLambdaValue}, {"testToLambdaInter", testToLambdaInter}, @@ -105,6 +124,8 @@ }; int main(void) { + setupADC(); + setupSleepMode(); initUSART(); uint16_t count = sizeof(tests) / sizeof(tests[0]); diff --git a/lambda/Makefile b/lambda/Makefile index a8bc706..9f7d982 100644 --- a/lambda/Makefile +++ b/lambda/Makefile @@ -14,7 +14,7 @@ ## If you've split your program into multiple .c / .h files, ## include the additional source (in same directory) here -LOCAL_SOURCE = sensors.c integers.c +LOCAL_SOURCE = adc.c sensors.c integers.c ## Here you can link to one more directory (and multiple .c files) EXTRA_SOURCE_DIR = /data/Work/AVR/AVR-Programming-master/AVR-Programming-Library/ diff --git a/lambda/adc.c b/lambda/adc.c new file mode 100644 index 0000000..dd49254 --- /dev/null +++ b/lambda/adc.c @@ -0,0 +1,24 @@ +/* + * adc.c + * + * Created on: 11.03.2015 + * Author: dode@luniks.net + * + */ +#include +#include + +EMPTY_INTERRUPT(ADC_vect); + +void setupADC(void) { + ADMUX |= (1 << REFS0); // use AVCC as reference voltage + // ADCSRA |= (1 << ADPS1) | (1 << ADPS2); // ADC clock prescaler /64 + ADCSRA |= (1 << ADPS2); // ADC clock prescaler /16 + ADCSRA |= (1 << ADEN); // enable ADC +} + +void setupSleepMode(void) { + set_sleep_mode(SLEEP_MODE_ADC); + ADCSRA |= (1 << ADIE); // enable ADC interrupt + sei(); // enable global interrupts +} diff --git a/lambda/adc.h b/lambda/adc.h new file mode 100644 index 0000000..06db268 --- /dev/null +++ b/lambda/adc.h @@ -0,0 +1,16 @@ +/* + * adc.h + * + * Created on: 11.03.2015 + * Author: dode@luniks.net + */ + +/** + * Sets up reference voltage and clock prescaler of the ADC and enables it. + */ +void setupADC(void); + +/** + * Sets up sleep mode and enables ADC and global interrupts. + */ +void setupSleepMode(void); diff --git a/lambda/integers.h b/lambda/integers.h index c8f678b..feaf115 100644 --- a/lambda/integers.h +++ b/lambda/integers.h @@ -18,4 +18,5 @@ */ int32_t roundUp(int32_t num, int32_t den); +// TODO function to divide and return result as decimal string? // char* toDecimalString(int32_t num, int32_t den); diff --git a/lambda/lambda.c b/lambda/lambda.c index 6be140b..0052704 100644 --- a/lambda/lambda.c +++ b/lambda/lambda.c @@ -8,34 +8,12 @@ * TODO have a look at string.h */ #include -#include -#include #include #include "USART.h" +#include "adc.h" #include "sensors.h" #include "integers.h" -EMPTY_INTERRUPT(ADC_vect); - -/** - * Sets up reference voltage and clock prescaler of the ADC and enables it. - */ -void setupADC(void) { - ADMUX |= (1 << REFS0); // use AVCC as reference voltage - // ADCSRA |= (1 << ADPS1) | (1 << ADPS2); // ADC clock prescaler /64 - ADCSRA |= (1 << ADPS2); // ADC clock prescaler /16 - ADCSRA |= (1 << ADEN); // enable ADC -} - -/** - * Sets up sleep mode and enables ADC and global interrupts. - */ -void setupSleepMode(void) { - set_sleep_mode(SLEEP_MODE_ADC); - ADCSRA |= (1 << ADIE); // enable ADC interrupt - sei(); // enable global interrupts -} - /** * Initializes the USART transmitter and receiver, sets up the ADC * and sleep mode and then infinitely measures with a 1 second delay @@ -44,7 +22,6 @@ * TODO replace delay by an interrupt or something else more efficient? */ int main(void) { - initUSART(); setupADC(); setupSleepMode(); diff --git a/lambda/sensors.c b/lambda/sensors.c index 33b1932..35c72ab 100644 --- a/lambda/sensors.c +++ b/lambda/sensors.c @@ -4,7 +4,6 @@ * Created on: 02.03.2015 * Author: dode@luniks.net * - * TODO put defines in makefile */ #include #include @@ -83,10 +82,6 @@ display(tempIVoltageAvg, tempI, tempOVoltageAvg, tempO, lambdaVoltageAvg, lambda); } -int16_t average(int16_t value, int16_t average, uint8_t weight) { - return roundUp(value + (average * weight), weight + 1); -} - void display( int16_t tempIVoltage, int16_t tempI, int16_t tempOVoltage, int16_t tempO, @@ -116,6 +111,10 @@ return mV; } +int16_t average(int16_t value, int16_t average, uint8_t weight) { + return roundUp(value + (average * weight), weight + 1); +} + int16_t toTempI(int16_t mV) { int temp = roundNearest(mV, 5); diff --git a/lambda/sensors.h b/lambda/sensors.h index 618482a..19ce01a 100644 --- a/lambda/sensors.h +++ b/lambda/sensors.h @@ -5,19 +5,19 @@ * Author: dode@luniks.net */ -// TODO is this the right place for these definitions? Put in makefile? +// TODO right place for these definitions? Put in makefile? // #define AREF_MV 4850 #define AREF_MV 5000 #define ADC_OFFSET_MV 7 -// #define TMP_OP_OFFSET_MV 441 -#define TMP_OP_OFFSET_MV 454 +// #define TEMPO_OP_OFFSET_MV 441 +#define TEMPO_OP_OFFSET_MV 454 #define LEAN "Mager" #define IDEAL "Ideal"; #define RICH "Fett!"; /** - * Struct used as entries for the lookup tables. + * Entry for the lookup tables. */ typedef struct { const int16_t mV; @@ -31,12 +31,6 @@ void measure(void); /** - * 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); - -/** * Formats the given values, displays them on an 16x2 LCD * and prints them over USART. */ @@ -53,21 +47,33 @@ int16_t getVoltage(uint8_t port); /** + * 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); + +/** * 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. + * With the current circuit the measuring range is from about 3 to 990 °C + * at 5000 mV OP supply and ADC reference voltage. */ int16_t toTempI(int16_t mV); /** * Looks up the temperature in °C mapped to the given voltage measured at * the PT1000 using linear interpolation and returns it. + * With the current circuit and the LM358 the measuring range is from about + * -40 to 375°C at 5000 mV OP supply and ADV reference voltage. */ int16_t toTempO(int16_t mV); /** * Looks up the lambda value x1000 mapped to the given voltage measured at - * the oxygen sensor using linear interpolation and returns it. + * the LSM 11 oxygen sensor using linear interpolation and returns it. + * With the current circuit and the AD8551 the measuring range is from about + * lambda 1.0 to 2.0 at 5000 mV OP supply and ADC reference voltage. */ int16_t toLambda(int16_t mV); @@ -81,5 +87,7 @@ /** * Returns a descriptive term such as "Lean" for the given lambda value x1000. + * For a wood fire, residual oxygen between 5% and 7% (lambda 1.3 and 1.5) is + * a good value, below is rich and above is lean. */ const char* toInfo(int16_t lambda);