diff --git a/stm-firmware/calibration.c b/stm-firmware/calibration.c index a7f64dc..1b570ed 100644 --- a/stm-firmware/calibration.c +++ b/stm-firmware/calibration.c @@ -19,9 +19,11 @@ #include #include +#include #include #include #include +#include void calibration_calculate(float low_measured, float low_setpoint, float high_measured, float high_setpoint, float *sens_deviation, float *sens_corrected_offset) @@ -44,23 +46,24 @@ void calibration_calculate(float low_measured, float low_setpoint, float high_me -int calibration_acquire_data(float *mu, float *sigma, uint32_t count) +int calibration_acquire_data(float *mu, float *max_dev, uint32_t count) { int status; float *stream_mem; + float min_val = FLT_MAX; + float max_val = -FLT_MAX; + uint32_t i; + int ret_val = 0; static volatile int flag = 0; - if (!mu || !sigma || !count) + if (!mu || !max_dev || !count) return -1000; stream_mem = (float *)calloc(count, sizeof(float)); if (!stream_mem) return -2; - /* Clear errors of PT1000 reading */ - adc_pt1000_clear_error(); - status = adc_pt1000_stream_raw_value_to_memory(stream_mem, count, &flag); if (status) return status; @@ -70,7 +73,8 @@ int calibration_acquire_data(float *mu, float *sigma, uint32_t count) if (flag != 1) { /* Error */ - return -1; + ret_val = -1; + goto ret_free_mem; } /* Convert the stream memory to Ohm readings */ @@ -79,10 +83,87 @@ int calibration_acquire_data(float *mu, float *sigma, uint32_t count) /* Do not compute std-deviation. Too imprecise * arm_std_f32(stream_mem, count, sigma); */ - *sigma = 0; arm_mean_f32(stream_mem, count, mu); + /* Find min and max values of array */ + for (i = 0U; i < count; i++) { + min_val = MIN(min_val, stream_mem[i]); + max_val = MAX(max_val, stream_mem[i]); + } + + /* Compute maximum deviation range */ + *max_dev = max_val - min_val; + +ret_free_mem: free(stream_mem); + return ret_val; +} + +static void wait_for_uart_enter() +{ + int enter_received = 0; + const char *recv_data; + size_t recv_len; + size_t iter; + int uart_recv_status; + + do { + uart_recv_status = uart_receive_data_with_dma(&recv_data, &recv_len); + if (uart_recv_status >= 1) { + for (iter = 0; iter < recv_len; iter++) { + if (recv_data[iter] == '\n' || recv_data[iter] == '\r') + enter_received = 1; + } + } + } while (enter_received == 0); +} + +int calibration_sequence_shell_cmd(shellmatta_handle_t shell) +{ + float mu, mu2, dev, dev2; + float sens_dev, offset; + + /* Clear errors of PT1000 reading */ + adc_pt1000_clear_error(); + + shellmatta_printf(shell, "Starting calibration: Insert 1000 Ohm calibration resistor and press ENTER\r\n"); + wait_for_uart_enter(); + shellmatta_printf(shell, "Measurement...\r\n"); + + /* Clear errors of PT1000 reading */ + adc_pt1000_clear_error(); + calibration_acquire_data(&mu, &dev, 512UL); + shellmatta_printf(shell, "R=%.2f, Noise peak-peak: %.2f\r\n", mu, dev); + if (adc_pt1000_check_error() != ADC_PT1000_NO_ERR) { + shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error()); + return -1; + } + + /* Measure 2nd calibration point */ + shellmatta_printf(shell, "Insert 2000 Ohm calibration resistor and press ENTER\r\n"); + wait_for_uart_enter(); + shellmatta_printf(shell, "Measurement...\r\n"); + + /* Clear errors of PT1000 reading */ + adc_pt1000_clear_error(); + calibration_acquire_data(&mu2, &dev2, 512UL); + shellmatta_printf(shell, "R=%.2f, Noise peak-peak: %.2f\r\n", mu2, dev2); + if (adc_pt1000_check_error() != ADC_PT1000_NO_ERR) { + shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error()); + return -2; + } + + /* Check noise values */ + if (dev > CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM || dev2 > CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM) { + shellmatta_printf(shell, "Calibration failed! Too much noise. Check you're hardware.\r\n"); + return -3; + } + + /* Calculate calibration */ + calibration_calculate(mu, 1000.0f, mu2, 2000.0f, &sens_dev, &offset); + + shellmatta_printf(shell, "Calibration done:\r\n\tSENS_DEVIATION: %.4f\r\n\tOFFSET_CORR: %.2f\r\n", sens_dev, offset); + adc_pt1000_set_resistance_calibration(offset, sens_dev, true); return 0; } diff --git a/stm-firmware/include/helper-macros/helper-macros.h b/stm-firmware/include/helper-macros/helper-macros.h index 8cf7d58..9dc9ac9 100644 --- a/stm-firmware/include/helper-macros/helper-macros.h +++ b/stm-firmware/include/helper-macros/helper-macros.h @@ -11,4 +11,7 @@ #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + #endif /* __HELPER_MACROS_H__ */ diff --git a/stm-firmware/include/reflow-controller/calibration.h b/stm-firmware/include/reflow-controller/calibration.h index 3160309..0d55a9f 100644 --- a/stm-firmware/include/reflow-controller/calibration.h +++ b/stm-firmware/include/reflow-controller/calibration.h @@ -20,13 +20,16 @@ #ifndef __CALIBRATION_H__ #define __CALIBRATION_H__ -#define CALIBRATION_MAX_STDDEV_OHM 1.0f +#define CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM 8.0f #include +#include void calibration_calculate(float low_measured, float low_setpoint, float high_measured, float high_setpoint, float *sens_deviation, float *sens_corrected_offset); -int calibration_acquire_data(float *mu, float *sigma, uint32_t count); +int calibration_acquire_data(float *mu, float *max_dev, uint32_t count); + +int calibration_sequence_shell_cmd(shellmatta_handle_t shell); #endif /* __CALIBRATION_H__ */ diff --git a/stm-firmware/include/stm-periph/dma-ring-buffer.h b/stm-firmware/include/stm-periph/dma-ring-buffer.h index a8cd1bd..4693bf3 100644 --- a/stm-firmware/include/stm-periph/dma-ring-buffer.h +++ b/stm-firmware/include/stm-periph/dma-ring-buffer.h @@ -51,7 +51,7 @@ int dma_ring_buffer_periph_to_mem_initialize(struct dma_ring_buffer_to_mem *dma_ * @param[in] buff Ring buffer structure * @param[out] data_buff Pointer to set to new data. This must not be modified! * @param[out] len Length in elements - * @return 0 if successful (data, no data), -1 if error, and 1 if data with wrap around. Call function again in this case to retrieve rest after wrap around. + * @return 0 if successful, but no data), -1 if error, 1 if data, and 2 if data with wrap around. Call function again in this case to retrieve rest after wrap around. */ int dma_ring_buffer_periph_to_mem_get_data(struct dma_ring_buffer_to_mem *buff, const void **data_buff, size_t *len); diff --git a/stm-firmware/main.c b/stm-firmware/main.c index b6c9d10..7795793 100644 --- a/stm-firmware/main.c +++ b/stm-firmware/main.c @@ -31,6 +31,7 @@ int main() const char *uart_input; size_t uart_input_len; shellmatta_handle_t shell_handle; + int uart_receive_status; setup_nvic_priorities(); systick_setup(); @@ -51,10 +52,9 @@ int main() while(1) { pt1000_value_status = adc_pt1000_get_current_resistance(&pt1000_value); - if (uart_receive_data_with_dma(&uart_input, &uart_input_len) >= 0) { + uart_receive_status = uart_receive_data_with_dma(&uart_input, &uart_input_len); + if (uart_receive_status >= 1) shell_handle_input(shell_handle, uart_input, uart_input_len); - } - //systick_wait_ms(300); } } diff --git a/stm-firmware/shell.c b/stm-firmware/shell.c index fe6251c..ca8e00e 100644 --- a/stm-firmware/shell.c +++ b/stm-firmware/shell.c @@ -152,14 +152,14 @@ static shellmatta_retCode_t shell_cmd_uptime(const shellmatta_handle_t handle, return SHELLMATTA_OK; } -static shellmatta_retCode_t shell_cmd_acquire_val(const shellmatta_handle_t handle, +static shellmatta_retCode_t shell_cmd_cal(const shellmatta_handle_t handle, const char *arguments, uint32_t length) { - float mu, sigma; + (void)arguments; + (void)length; - calibration_acquire_data(&mu, &sigma, 128U); - shellmatta_printf(handle, "mu: %.2f\r\nsigma: %.3f\r\n", mu, sigma); + calibration_sequence_shell_cmd(handle); return SHELLMATTA_OK; } //typedef struct shellmatta_cmd @@ -222,11 +222,11 @@ static shellmatta_cmd_t cmd[7] = { .next = &cmd[6], }, { - .cmd = "pt1000-acquire", - .cmdAlias = "ptac", - .helpText = "Acquire 128 samples", + .cmd = "calibrate", + .cmdAlias = "cal", + .helpText = "Calibrate resistance measurement", .usageText = "", - .cmdFct = shell_cmd_acquire_val, + .cmdFct = shell_cmd_cal, .next = NULL, } }; diff --git a/stm-firmware/stm-periph/dma-ring-buffer.c b/stm-firmware/stm-periph/dma-ring-buffer.c index f130892..289b587 100644 --- a/stm-firmware/stm-periph/dma-ring-buffer.c +++ b/stm-firmware/stm-periph/dma-ring-buffer.c @@ -81,11 +81,12 @@ int dma_ring_buffer_periph_to_mem_get_data(struct dma_ring_buffer_to_mem *buff, *data_buff = &(((char *)buff->data_ptr)[buff->get_idx * buff->element_size]); *len = buff->buffer_count - buff->get_idx; buff->get_idx = 0; - ret_code = 1; + ret_code = 2; } else if (put_idx > buff->get_idx) { *data_buff = &(((char *)buff->data_ptr)[buff->get_idx * buff->element_size]); *len = put_idx - buff->get_idx; buff->get_idx += *len; + ret_code = 1; } else { /* No new data */ *len = 0; diff --git a/stm-firmware/syscalls.c b/stm-firmware/syscalls.c index 40d8f12..876fc20 100644 --- a/stm-firmware/syscalls.c +++ b/stm-firmware/syscalls.c @@ -67,6 +67,6 @@ int _read(void) int _write(int fd, const void *buf, int count) { if (fd == 1) - uart_send_array((char*)buf, count); + uart_send_array_with_dma((char*)buf, count); return count; }