Made motor temperature lpf slower, and added median motor temperature lpf to HWs with adc mux

This commit is contained in:
Benjamin Vedder 2020-04-18 09:48:25 +02:00
parent d305e37c61
commit 9924f333af
10 changed files with 55 additions and 33 deletions

View File

@ -23,6 +23,7 @@
* Improved battery level and range estimation.
* Use fast speed estimator for encoder sensorless transition.
* Signigicantly improved hall sensor transitions and interpolation.
* More filtering on the motor temperature.
=== FW 4.02 ===
* Position PID fix (most notable on multiturn encoders).

View File

@ -432,7 +432,7 @@
#define ADC_IND_TEMP_MOTOR_2 ADC_IND_TEMP_MOTOR
#endif
#ifndef MOTOR_TEMP_LPF
#define MOTOR_TEMP_LPF 0.1
#define MOTOR_TEMP_LPF 0.01
#endif
#ifndef HW_ADC_CHANNELS_EXTRA
#define HW_ADC_CHANNELS_EXTRA 0

View File

@ -22,8 +22,7 @@
#include "comm_can.h"
#include "mc_interface.h"
#include "ledpwm.h"
#include <string.h>
#include <stdlib.h>
#include "utils.h"
typedef enum {
SWITCH_BOOTED = 0,
@ -36,7 +35,7 @@ typedef enum {
// Variables
static volatile bool i2c_running = false;
static THD_WORKING_AREA(smart_switch_thread_wa, 128);
static THD_WORKING_AREA(mux_thread_wa, 128);
static THD_WORKING_AREA(mux_thread_wa, 256);
static THD_WORKING_AREA(switch_color_thread_wa, 128);
static THD_FUNCTION(mux_thread, arg);
static THD_FUNCTION(switch_color_thread, arg);
@ -316,10 +315,9 @@ static THD_FUNCTION(mux_thread, arg) {
chRegSetThreadName("adc_mux");
(void)arg;
const unsigned int samp_num = 9;
uint16_t mot1_temp_samples[samp_num];
uint16_t mot2_temp_samples[samp_num];
uint16_t mot_temp_samp_sorted[samp_num];
#define TEMP_FILTER_LEN 9
uint16_t mot1_temp_samples[TEMP_FILTER_LEN] = {0};
uint16_t mot2_temp_samples[TEMP_FILTER_LEN] = {0};
unsigned int mot1_temp_samp_ptr = 0;
unsigned int mot2_temp_samp_ptr = 0;
@ -334,19 +332,13 @@ static THD_FUNCTION(mux_thread, arg) {
ENABLE_MOT_TEMP1();
chThdSleepMicroseconds(400);
mot1_temp_samples[mot1_temp_samp_ptr++] = ADC_Value[ADC_IND_ADC_MUX];
mot1_temp_samp_ptr %= samp_num;
memcpy(mot_temp_samp_sorted, mot1_temp_samples, sizeof(uint16_t) * samp_num);
qsort(mot_temp_samp_sorted, samp_num, sizeof(uint16_t), samp_cmp_func);
ADC_Value[ADC_IND_TEMP_MOTOR] = mot_temp_samp_sorted[samp_num / 2];
ADC_Value[ADC_IND_TEMP_MOTOR] = utils_median_filter_uint16_run(
mot1_temp_samples, &mot1_temp_samp_ptr, TEMP_FILTER_LEN, ADC_Value[ADC_IND_ADC_MUX]);
ENABLE_MOT_TEMP2();
chThdSleepMicroseconds(400);
mot2_temp_samples[mot2_temp_samp_ptr++] = ADC_Value[ADC_IND_ADC_MUX];
mot2_temp_samp_ptr %= samp_num;
memcpy(mot_temp_samp_sorted, mot2_temp_samples, sizeof(uint16_t) * samp_num);
qsort(mot_temp_samp_sorted, samp_num, sizeof(uint16_t), samp_cmp_func);
ADC_Value[ADC_IND_TEMP_MOTOR_2] = mot_temp_samp_sorted[samp_num / 2];
ADC_Value[ADC_IND_TEMP_MOTOR_2] = utils_median_filter_uint16_run(
mot2_temp_samples, &mot2_temp_samp_ptr, TEMP_FILTER_LEN, ADC_Value[ADC_IND_ADC_MUX]);
ENABLE_ADC_EXT_1();
chThdSleepMicroseconds(400);

View File

@ -248,7 +248,6 @@
#define NTC_RES_MOTOR(adc_val) (10000.0 / ((4095.0 / (float)adc_val) - 1.0)) // Motor temp sensor on low side
#define NTC_TEMP_MOTOR(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15)
#define NTC_TEMP_MOTOR_2(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR_2]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15)
#define MOTOR_TEMP_LPF 0.01
// Double samples in beginning and end for positive current measurement.
// Useful when the shunt sense traces have noise that causes offset.

View File

@ -22,7 +22,7 @@
#include "comm_can.h"
#include "mc_interface.h"
#include "ledpwm.h"
#include "utils.h"
typedef enum {
SWITCH_BOOTED = 0,
@ -35,7 +35,7 @@ typedef enum {
// Variables
static volatile bool i2c_running = false;
static THD_WORKING_AREA(smart_switch_thread_wa, 128);
static THD_WORKING_AREA(mux_thread_wa, 128);
static THD_WORKING_AREA(mux_thread_wa, 256);
static THD_WORKING_AREA(switch_color_thread_wa, 128);
static THD_FUNCTION(mux_thread, arg);
static THD_FUNCTION(switch_color_thread, arg);
@ -312,6 +312,12 @@ static THD_FUNCTION(mux_thread, arg) {
chRegSetThreadName("adc_mux");
(void)arg;
#define TEMP_FILTER_LEN 9
uint16_t mot1_temp_samples[TEMP_FILTER_LEN] = {0};
uint16_t mot2_temp_samples[TEMP_FILTER_LEN] = {0};
unsigned int mot1_temp_samp_ptr = 0;
unsigned int mot2_temp_samp_ptr = 0;
for (;;) {
ENABLE_MOS_TEMP1();
chThdSleepMicroseconds(400);
@ -323,11 +329,13 @@ static THD_FUNCTION(mux_thread, arg) {
ENABLE_MOT_TEMP1();
chThdSleepMicroseconds(400);
ADC_Value[ADC_IND_TEMP_MOTOR] = ADC_Value[ADC_IND_ADC_MUX];
ADC_Value[ADC_IND_TEMP_MOTOR] = utils_median_filter_uint16_run(
mot1_temp_samples, &mot1_temp_samp_ptr, TEMP_FILTER_LEN, ADC_Value[ADC_IND_ADC_MUX]);
ENABLE_MOT_TEMP2();
chThdSleepMicroseconds(400);
ADC_Value[ADC_IND_TEMP_MOTOR_2] = ADC_Value[ADC_IND_ADC_MUX];
ADC_Value[ADC_IND_TEMP_MOTOR_2] = utils_median_filter_uint16_run(
mot2_temp_samples, &mot2_temp_samp_ptr, TEMP_FILTER_LEN, ADC_Value[ADC_IND_ADC_MUX]);
ENABLE_ADC_EXT_1();
chThdSleepMicroseconds(400);

View File

@ -239,7 +239,6 @@
#define NTC_RES_MOTOR(adc_val) (10000.0 / ((4095.0 / (float)adc_val) - 1.0)) // Motor temp sensor on low side
#define NTC_TEMP_MOTOR(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15)
#define NTC_TEMP_MOTOR_2(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR_2]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15)
#define MOTOR_TEMP_LPF 0.01
// Double samples in beginning and end for positive current measurement.
// Useful when the shunt sense traces have noise that causes offset.

View File

@ -22,6 +22,7 @@
#include "comm_can.h"
#include "mc_interface.h"
#include "ledpwm.h"
#include "utils.h"
typedef enum {
SWITCH_BOOTED = 0,
@ -34,7 +35,7 @@ typedef enum {
// Variables
static volatile bool i2c_running = false;
static THD_WORKING_AREA(smart_switch_thread_wa, 128);
static THD_WORKING_AREA(mux_thread_wa, 128);
static THD_WORKING_AREA(mux_thread_wa, 256);
static THD_FUNCTION(mux_thread, arg);
static volatile switch_states switch_state = SWITCH_BOOTED;
@ -302,22 +303,30 @@ static THD_FUNCTION(mux_thread, arg) {
chRegSetThreadName("adc_mux");
(void)arg;
#define TEMP_FILTER_LEN 9
uint16_t mot1_temp_samples[TEMP_FILTER_LEN] = {0};
uint16_t mot2_temp_samples[TEMP_FILTER_LEN] = {0};
unsigned int mot1_temp_samp_ptr = 0;
unsigned int mot2_temp_samp_ptr = 0;
for (;;) {
ENABLE_MOS_TEMP1();
chThdSleepMilliseconds(1);
chThdSleepMicroseconds(400);
ADC_Value[ADC_IND_TEMP_MOS] = ADC_Value[ADC_IND_ADC_MUX];
ENABLE_MOS_TEMP2();
chThdSleepMilliseconds(1);
chThdSleepMicroseconds(400);
ADC_Value[ADC_IND_TEMP_MOS_M2] = ADC_Value[ADC_IND_ADC_MUX];
ENABLE_MOT_TEMP1();
chThdSleepMilliseconds(1);
ADC_Value[ADC_IND_TEMP_MOTOR] = ADC_Value[ADC_IND_ADC_MUX];
chThdSleepMicroseconds(400);
ADC_Value[ADC_IND_TEMP_MOTOR] = utils_median_filter_uint16_run(
mot1_temp_samples, &mot1_temp_samp_ptr, TEMP_FILTER_LEN, ADC_Value[ADC_IND_ADC_MUX]);
ENABLE_MOT_TEMP2();
chThdSleepMilliseconds(1);
ADC_Value[ADC_IND_TEMP_MOTOR_2] = ADC_Value[ADC_IND_ADC_MUX];
chThdSleepMicroseconds(400);
ADC_Value[ADC_IND_TEMP_MOTOR_2] = utils_median_filter_uint16_run(
mot2_temp_samples, &mot2_temp_samp_ptr, TEMP_FILTER_LEN, ADC_Value[ADC_IND_ADC_MUX]);
}
}

View File

@ -179,7 +179,6 @@
#define NTC_RES_MOTOR(adc_val) (10000.0 / ((4095.0 / (float)adc_val) - 1.0)) // Motor temp sensor on low side
#define NTC_TEMP_MOTOR(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15)
#define NTC_TEMP_MOTOR_2(beta) (1.0 / ((logf(NTC_RES_MOTOR(ADC_Value[ADC_IND_TEMP_MOTOR_2]) / 10000.0) / beta) + (1.0 / 298.15)) - 273.15)
#define MOTOR_TEMP_LPF 0.01
// UART Peripheral
#define HW_UART_DEV SD3

13
utils.c
View File

@ -24,6 +24,7 @@
#include "conf_general.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
// Private variables
static volatile int sys_lock_cnt = 0;
@ -807,7 +808,19 @@ float utils_batt_liion_norm_v_to_capacity(float norm_v) {
return capacity;
}
static int uint16_cmp_func (const void *a, const void *b) {
return (*(uint16_t*)a - *(uint16_t*)b);
}
uint16_t utils_median_filter_uint16_run(uint16_t *buffer,
unsigned int *buffer_index, unsigned int filter_len, uint16_t sample) {
buffer[*buffer_index++] = sample;
*buffer_index %= filter_len;
uint16_t buffer_sorted[filter_len]; // Assume we have enough stack space
memcpy(buffer_sorted, buffer, sizeof(uint16_t) * filter_len);
qsort(buffer_sorted, filter_len, sizeof(uint16_t), uint16_cmp_func);
return buffer_sorted[filter_len / 2];
}
const float utils_tab_sin_32_1[] = {
0.000000, 0.195090, 0.382683, 0.555570, 0.707107, 0.831470, 0.923880, 0.980785,

View File

@ -61,7 +61,9 @@ void utils_fft8_bin1(float *real_in, float *real, float *imag);
void utils_fft8_bin2(float *real_in, float *real, float *imag);
uint8_t utils_second_motor_id(void);
int utils_read_hall(bool is_second_motor);
float utils_batt_liion_norm_v_to_capacity(float norm_v) ;
float utils_batt_liion_norm_v_to_capacity(float norm_v);
uint16_t utils_median_filter_uint16_run(uint16_t *buffer,
unsigned int *buffer_index, unsigned int filter_len, uint16_t sample);
// Return the sign of the argument. -1 if negative, 1 if zero or positive.
#define SIGN(x) ((x < 0) ? -1 : 1)