Add calibration routine from shell
This commit is contained in:
		@@ -19,9 +19,11 @@
 | 
			
		||||
 | 
			
		||||
#include <reflow-controller/calibration.h>
 | 
			
		||||
#include <reflow-controller/adc-meas.h>
 | 
			
		||||
#include <stm-periph/uart.h>
 | 
			
		||||
#include <helper-macros/helper-macros.h>
 | 
			
		||||
#include <arm_math.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <float.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <stdint.h>
 | 
			
		||||
#include <shellmatta.h>
 | 
			
		||||
 | 
			
		||||
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__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user