Make claibration routine non blocking
This commit is contained in:
parent
b9857745b1
commit
2614cea431
@ -27,7 +27,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
extern struct stm_uart shell_uart;
|
enum calibration_shell_state {CAL_START = 0, CAL_WAIT_RES1, CAL_MEAS_RES1, CAL_WAIT_RES2, CAL_MEAS_RES2};
|
||||||
|
|
||||||
void calibration_calculate(float low_measured, float low_setpoint, float high_measured, float high_setpoint,
|
void calibration_calculate(float low_measured, float low_setpoint, float high_measured, float high_setpoint,
|
||||||
float *sens_deviation, float *sens_corrected_offset)
|
float *sens_deviation, float *sens_corrected_offset)
|
||||||
@ -50,124 +50,217 @@ void calibration_calculate(float low_measured, float low_setpoint, float high_me
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int calibration_acquire_data(float *mu, float *max_dev, uint32_t count)
|
float *calibration_acquire_data_start(uint32_t count, volatile int *flag)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
float *stream_mem;
|
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 (!count)
|
||||||
|
return NULL;
|
||||||
if (!mu || !max_dev || !count)
|
|
||||||
return -1000;
|
|
||||||
|
|
||||||
stream_mem = (float *)calloc(count, sizeof(float));
|
stream_mem = (float *)calloc(count, sizeof(float));
|
||||||
if (!stream_mem)
|
if (!stream_mem)
|
||||||
return -2;
|
return stream_mem;
|
||||||
|
|
||||||
status = adc_pt1000_stream_raw_value_to_memory(stream_mem, count, &flag);
|
*flag = 0;
|
||||||
|
status = adc_pt1000_stream_raw_value_to_memory(stream_mem, count, flag);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
goto free_mem;
|
||||||
|
|
||||||
/* Wait for data to be transferred */
|
|
||||||
while (flag == 0);
|
|
||||||
|
|
||||||
if (flag != 1) {
|
return stream_mem;
|
||||||
|
free_mem:
|
||||||
|
free(stream_mem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calibration_poll_data_acquisition(float *mem_array, uint32_t count, volatile int *flag, float *mu, float *max_dev)
|
||||||
|
{
|
||||||
|
int ret_val = 0;
|
||||||
|
float min_val = FLT_MAX;
|
||||||
|
float max_val = -FLT_MAX;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (!flag || !mem_array || !mu || !max_dev)
|
||||||
|
return -1000;
|
||||||
|
|
||||||
|
if (*flag == 0) {
|
||||||
|
/* Continue polling */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*flag != 1) {
|
||||||
/* Error */
|
/* Error */
|
||||||
ret_val = -1;
|
ret_val = -1;
|
||||||
goto ret_free_mem;
|
goto ret_free_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the stream memory to Ohm readings */
|
/* Convert the stream memory to Ohm readings */
|
||||||
adc_pt1000_convert_raw_value_array_to_resistance(NULL, stream_mem, count);
|
adc_pt1000_convert_raw_value_array_to_resistance(NULL, mem_array, count);
|
||||||
|
|
||||||
/* Do not compute std-deviation. Too imprecise
|
/* Do not compute std-deviation. Too imprecise
|
||||||
* arm_std_f32(stream_mem, count, sigma);
|
* arm_std_f32(stream_mem, count, sigma);
|
||||||
*/
|
*/
|
||||||
arm_mean_f32(stream_mem, count, mu);
|
arm_mean_f32(mem_array, count, mu);
|
||||||
|
|
||||||
/* Find min and max values of array */
|
/* Find min and max values of array */
|
||||||
for (i = 0U; i < count; i++) {
|
for (i = 0U; i < count; i++) {
|
||||||
min_val = MIN(min_val, stream_mem[i]);
|
min_val = MIN(min_val, mem_array[i]);
|
||||||
max_val = MAX(max_val, stream_mem[i]);
|
max_val = MAX(max_val, mem_array[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute maximum deviation range */
|
/* Compute maximum deviation range */
|
||||||
*max_dev = max_val - min_val;
|
*max_dev = max_val - min_val;
|
||||||
|
|
||||||
ret_free_mem:
|
ret_free_mem:
|
||||||
free(stream_mem);
|
free(mem_array);
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_for_uart_enter()
|
shellmatta_retCode_t calibration_sequence_shell_cmd(shellmatta_handle_t shell, const char *arg, uint32_t len)
|
||||||
{
|
{
|
||||||
int enter_received = 0;
|
(void)arg;
|
||||||
const char *recv_data;
|
(void)len;
|
||||||
size_t recv_len;
|
|
||||||
size_t iter;
|
|
||||||
int uart_recv_status;
|
|
||||||
|
|
||||||
do {
|
/* This stores the current state of the calibration process */
|
||||||
uart_recv_status = uart_receive_data_with_dma(&shell_uart, &recv_data, &recv_len);
|
static enum calibration_shell_state cal_state = CAL_START;
|
||||||
if (uart_recv_status >= 1) {
|
shellmatta_retCode_t ret_val = SHELLMATTA_BUSY;
|
||||||
for (iter = 0; iter < recv_len; iter++) {
|
uint32_t i;
|
||||||
if (recv_data[iter] == '\n' || recv_data[iter] == '\r')
|
int res;
|
||||||
enter_received = 1;
|
|
||||||
|
static float mu = 0.0f, mu2 = 0.0f, dev = 0.0f, dev2 = 0.0f;
|
||||||
|
float sens_dev, offset;
|
||||||
|
static float *data_buffer = NULL;
|
||||||
|
static volatile int flag;
|
||||||
|
char *stdin_data;
|
||||||
|
uint32_t stdin_len;
|
||||||
|
|
||||||
|
|
||||||
|
switch (cal_state) {
|
||||||
|
case CAL_START:
|
||||||
|
/* Clear errors of PT1000 reading */
|
||||||
|
adc_pt1000_clear_error();
|
||||||
|
shellmatta_printf(shell, "Starting calibration: Insert 1000 Ohm calibration resistor and press ENTER\r\n");
|
||||||
|
cal_state = CAL_WAIT_RES1;
|
||||||
|
ret_val = SHELLMATTA_CONTINUE;
|
||||||
|
break;
|
||||||
|
case CAL_WAIT_RES1:
|
||||||
|
cal_state = CAL_WAIT_RES1;
|
||||||
|
ret_val = SHELLMATTA_CONTINUE;
|
||||||
|
shellmatta_read(shell, &stdin_data, &stdin_len);
|
||||||
|
if (stdin_len > 0) {
|
||||||
|
for (i = 0; i < stdin_len; i++) {
|
||||||
|
if (stdin_data[i] == '\r') {
|
||||||
|
cal_state = CAL_MEAS_RES1;
|
||||||
|
ret_val = SHELLMATTA_BUSY;
|
||||||
|
shellmatta_printf(shell, "Measurement...\r\n");
|
||||||
|
adc_pt1000_clear_error();
|
||||||
|
data_buffer = calibration_acquire_data_start(512UL, &flag);
|
||||||
|
break;
|
||||||
|
} else if (stdin_data[i] == '\x03') {
|
||||||
|
cal_state = CAL_START;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (enter_received == 0);
|
|
||||||
}
|
break;
|
||||||
|
case CAL_MEAS_RES1:
|
||||||
int calibration_sequence_shell_cmd(shellmatta_handle_t shell)
|
if (!data_buffer) {
|
||||||
{
|
shellmatta_printf(shell, "Data acquisition failed!\r\n");
|
||||||
float mu, mu2, dev, dev2;
|
ret_val = SHELLMATTA_OK;
|
||||||
float sens_dev, offset;
|
cal_state = CAL_START;
|
||||||
|
break;
|
||||||
/* Clear errors of PT1000 reading */
|
}
|
||||||
adc_pt1000_clear_error();
|
|
||||||
|
res = calibration_poll_data_acquisition(data_buffer, 512UL, &flag, &mu, &dev);
|
||||||
shellmatta_printf(shell, "Starting calibration: Insert 1000 Ohm calibration resistor and press ENTER\r\n");
|
/* Stay in this state until the measurements are finished */
|
||||||
wait_for_uart_enter();
|
if (res == 1) {
|
||||||
shellmatta_printf(shell, "Measurement...\r\n");
|
ret_val = SHELLMATTA_BUSY;
|
||||||
|
cal_state = CAL_MEAS_RES1;
|
||||||
/* Clear errors of PT1000 reading */
|
} else if (res == 0) {
|
||||||
adc_pt1000_clear_error();
|
shellmatta_printf(shell, "R=%.2f, Noise peak-peak: %.2f\r\n", mu, dev);
|
||||||
calibration_acquire_data(&mu, &dev, 512UL);
|
if (adc_pt1000_check_error() != ADC_PT1000_NO_ERR) {
|
||||||
shellmatta_printf(shell, "R=%.2f, Noise peak-peak: %.2f\r\n", mu, dev);
|
shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error());
|
||||||
if (adc_pt1000_check_error() != ADC_PT1000_NO_ERR) {
|
ret_val = SHELLMATTA_OK;
|
||||||
shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error());
|
cal_state = CAL_START;
|
||||||
return -1;
|
} else {
|
||||||
}
|
ret_val = SHELLMATTA_CONTINUE;
|
||||||
|
shellmatta_printf(shell, "Insert 2000 Ohm calibration resistor and press ENTER\r\n");
|
||||||
/* Measure 2nd calibration point */
|
cal_state = CAL_WAIT_RES2;
|
||||||
shellmatta_printf(shell, "Insert 2000 Ohm calibration resistor and press ENTER\r\n");
|
}
|
||||||
wait_for_uart_enter();
|
} else {
|
||||||
shellmatta_printf(shell, "Measurement...\r\n");
|
shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error());
|
||||||
|
ret_val = SHELLMATTA_OK;
|
||||||
/* Clear errors of PT1000 reading */
|
cal_state = CAL_START;
|
||||||
adc_pt1000_clear_error();
|
}
|
||||||
calibration_acquire_data(&mu2, &dev2, 512UL);
|
break;
|
||||||
shellmatta_printf(shell, "R=%.2f, Noise peak-peak: %.2f\r\n", mu2, dev2);
|
case CAL_WAIT_RES2:
|
||||||
if (adc_pt1000_check_error() != ADC_PT1000_NO_ERR) {
|
cal_state = CAL_WAIT_RES2;
|
||||||
shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error());
|
ret_val = SHELLMATTA_CONTINUE;
|
||||||
return -2;
|
shellmatta_read(shell, &stdin_data, &stdin_len);
|
||||||
}
|
if (stdin_len > 0) {
|
||||||
|
for (i = 0; i < stdin_len; i++) {
|
||||||
/* Check noise values */
|
if (stdin_data[i] == '\r') {
|
||||||
if (dev > CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM || dev2 > CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM) {
|
cal_state = CAL_MEAS_RES2;
|
||||||
shellmatta_printf(shell, "Calibration failed! Too much noise. Check your hardware.\r\n");
|
ret_val = SHELLMATTA_BUSY;
|
||||||
return -3;
|
shellmatta_printf(shell, "Measurement...\r\n");
|
||||||
}
|
adc_pt1000_clear_error();
|
||||||
|
data_buffer = calibration_acquire_data_start(512UL, &flag);
|
||||||
/* Calculate calibration */
|
break;
|
||||||
calibration_calculate(mu, 1000.0f, mu2, 2000.0f, &sens_dev, &offset);
|
} else if (stdin_data[i] == '\x03') {
|
||||||
|
cal_state = CAL_START;
|
||||||
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;
|
|
||||||
|
break;
|
||||||
|
case CAL_MEAS_RES2:
|
||||||
|
if (!data_buffer) {
|
||||||
|
shellmatta_printf(shell, "Data acquisition failed!\r\n");
|
||||||
|
ret_val = SHELLMATTA_OK;
|
||||||
|
cal_state = CAL_START;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = calibration_poll_data_acquisition(data_buffer, 512UL, &flag, &mu2, &dev2);
|
||||||
|
/* Stay in this state until the measurements are finished */
|
||||||
|
if (res == 1) {
|
||||||
|
ret_val = SHELLMATTA_BUSY;
|
||||||
|
cal_state = CAL_MEAS_RES2;
|
||||||
|
} else if (res == 0) {
|
||||||
|
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());
|
||||||
|
ret_val = SHELLMATTA_OK;
|
||||||
|
cal_state = CAL_START;
|
||||||
|
} else {
|
||||||
|
ret_val = SHELLMATTA_OK;
|
||||||
|
cal_state = CAL_START;
|
||||||
|
|
||||||
|
if (dev > CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM ||
|
||||||
|
dev2 > CALIBRATION_MAX_PEAK_PEAK_NOISE_OHM) {
|
||||||
|
shellmatta_printf(shell, "Calibration failed! Too much noise. Check your hardware.\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shellmatta_printf(shell, "Calibartion finished successfully!\r\n");
|
||||||
|
/* Calculate calibration */
|
||||||
|
calibration_calculate(mu, 1000.0f, mu2, 2000.0f, &sens_dev, &offset);
|
||||||
|
|
||||||
|
shellmatta_printf(shell, "\r\n\tSENS_DEVIATION: %.4f\r\n\tOFFSET_CORR: %.2f\r\n", sens_dev, offset);
|
||||||
|
adc_pt1000_set_resistance_calibration(offset, sens_dev, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shellmatta_printf(shell, "Error in resistance measurement: %d", adc_pt1000_check_error());
|
||||||
|
ret_val = SHELLMATTA_OK;
|
||||||
|
cal_state = CAL_START;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shellmatta_printf(shell, "Undefined state reached in calibration. Aborting\r\n");
|
||||||
|
cal_state = CAL_START;
|
||||||
|
ret_val = SHELLMATTA_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
void calibration_calculate(float low_measured, float low_setpoint, float high_measured, float high_setpoint,
|
void calibration_calculate(float low_measured, float low_setpoint, float high_measured, float high_setpoint,
|
||||||
float *sens_deviation, float *sens_corrected_offset);
|
float *sens_deviation, float *sens_corrected_offset);
|
||||||
|
|
||||||
int calibration_acquire_data(float *mu, float *max_dev, uint32_t count);
|
float *calibration_acquire_data_start(uint32_t count, volatile int *flag);
|
||||||
|
|
||||||
int calibration_sequence_shell_cmd(shellmatta_handle_t shell);
|
shellmatta_retCode_t calibration_sequence_shell_cmd(shellmatta_handle_t shell, const char *arg, uint32_t len);
|
||||||
|
|
||||||
#endif /* __CALIBRATION_H__ */
|
#endif /* __CALIBRATION_H__ */
|
||||||
|
@ -200,8 +200,7 @@ static shellmatta_retCode_t shell_cmd_cal(const shellmatta_handle_t handle,
|
|||||||
(void)arguments;
|
(void)arguments;
|
||||||
(void)length;
|
(void)length;
|
||||||
|
|
||||||
calibration_sequence_shell_cmd(handle);
|
return calibration_sequence_shell_cmd(handle, arguments, length);
|
||||||
return SHELLMATTA_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static shellmatta_retCode_t shell_meminfo(const shellmatta_handle_t handle,
|
static shellmatta_retCode_t shell_meminfo(const shellmatta_handle_t handle,
|
||||||
|
Loading…
Reference in New Issue
Block a user