diff options
author | Christian Franke <nobody@nowhere.ws> | 2013-12-10 07:01:52 +0100 |
---|---|---|
committer | Christian Franke <nobody@nowhere.ws> | 2013-12-10 07:01:52 +0100 |
commit | 4265af272a962ce1df1f6a975fdc8210f889760a (patch) | |
tree | 5aa10060c5c76ad99d5ab6e36fd81413d72a24cb | |
parent | ee3f9c98681127496101900d65d05c8520b16732 (diff) |
Luckily, this ATMega is grossly oversized, so we can
just throw in floating point arithmetic.
-rw-r--r-- | command.c | 8 | ||||
-rw-r--r-- | controller.c | 47 | ||||
-rw-r--r-- | controller.h | 4 | ||||
-rw-r--r-- | fit.py | 23 |
4 files changed, 71 insertions, 11 deletions
@@ -14,7 +14,7 @@ static void handle_set(char *buffer, uint16_t len) const char *success_msg = "OK Temperature set.\r\n"; const char *input; char *endptr; - long temperature; + double temperature; if (len < 2) { serial_send(error_msg, strlen(error_msg), 0); @@ -22,7 +22,7 @@ static void handle_set(char *buffer, uint16_t len) } input = buffer + 1; - temperature = strtol(input, &endptr, 10); + temperature = strtod(input, &endptr); if (input[0] == '\r' || input[0] == '\n' || (endptr[0] != '\r' && endptr[0] != '\n')) { serial_send(error_msg, strlen(error_msg), 0); @@ -48,8 +48,10 @@ static void handle_off(char *buffer, uint16_t len) static void handle_get(char *buffer, uint16_t len) { char response[128]; + long temp = 10 * controller_get(); - snprintf(response, sizeof(response), "OK t=%ld\r\n", controller_get()); + /* printf won't print doubles on avr */ + snprintf(response, sizeof(response), "OK t=%ld.%ld\r\n", temp/10, temp%10); serial_send(response, strlen(response), 0); } diff --git a/controller.c b/controller.c index bde2cac..6dee4da 100644 --- a/controller.c +++ b/controller.c @@ -1,9 +1,13 @@ #include <avr/io.h> #include <avr/interrupt.h> +#include <math.h> +#include <stdio.h> +#include <string.h> #include "controller.h" #include "bridge.h" +#include "serial.h" static void adc_init(void) { @@ -40,20 +44,43 @@ void controller_init(void) timer_init(); } -int controller_set(long target) +static long celsius_to_adc(double target_temp) { - if (target < 50 || target > 974) + long rv; + + rv = 1203.59290 * exp(-0.0686201496 * target_temp) + 413.59437; + if (rv > 1017) + return 1017; + if (rv < 450) + return 450; + return rv; +} + +static double adc_to_celsius(long adc) +{ + double rv; + + rv = adc - 413.59437; + rv /= 1203.59290; + rv = log(rv); + rv /= -0.0686201496; + return rv; +} + +int controller_set(double target) +{ + if (target < 8.0 || target > 42.0) return 1; - controller_target_temp = target; + controller_target_temp = celsius_to_adc(target); controller_num_iterations = 1; controller_active = 1; return 0; } -long controller_get(void) +double controller_get(void) { - return controller_measured_temp; + return adc_to_celsius(controller_measured_temp); } void controller_off(void) @@ -82,8 +109,16 @@ ISR(ADC_vect) return; controller_num_iterations--; - if (controller_num_iterations) + if (controller_num_iterations) { +#if 0 + char buffer[128]; + snprintf(buffer, sizeof(buffer), "DEBUG adc==%ld adc_target=%ld\r\n", + (long int)controller_measured_temp, + controller_target_temp); + serial_send(buffer, strlen(buffer), 0); +#endif return; + } controller_num_iterations = 60; diff --git a/controller.h b/controller.h index 0b65a73..70e7f30 100644 --- a/controller.h +++ b/controller.h @@ -2,8 +2,8 @@ #define CONTROLLER_H void controller_init(void); -int controller_set(long target); -long controller_get(void); +int controller_set(double target); +double controller_get(void); void controller_off(void); #endif @@ -0,0 +1,23 @@ +from scipy.optimize import curve_fit +import numpy +import matplotlib.pyplot as pyplot + + +data_x = numpy.array([ 10, 13, 17, 21, 24, 31, 36, 41 ]) +data_y = numpy.array([ 1017, 898, 810, 715, 620, 547, 510, 500 ]) + +def func(x, a, b, c): + return a * numpy.exp(-b*x)-c + +popt, pcov = curve_fit(func, data_x, data_y, maxfev=5000) +trial_x = numpy.linspace(0, 50, 200) +trial_y = func(trial_x, *popt) + +print popt + +pyplot.figure() +pyplot.plot(data_x, data_y, 'ro', label='Data') +pyplot.plot(trial_x, trial_y, 'b-', label="Exp Fit") +pyplot.legend() +pyplot.show() + |