From b9b94fcadc6a6deaffe16c613446b02d6da41095 Mon Sep 17 00:00:00 2001 From: rusefillc <48498823+rusefillc@users.noreply.github.com> Date: Sat, 7 May 2022 14:12:20 -0400 Subject: [PATCH] Temperature (#63) * integer id interpolation * Calculate sensor temperature based on Ri * Sensor Ri around 25C Co-authored-by: Andrey Gusakov --- firmware/Makefile | 1 + firmware/interpolation.cpp | 37 +++++++++++++++++++++++++++++++++++++ firmware/interpolation.h | 10 ++++++++++ firmware/sampling.cpp | 27 +++++++++++++++++++++++++++ firmware/sampling.h | 1 + 5 files changed, 76 insertions(+) create mode 100644 firmware/interpolation.cpp create mode 100644 firmware/interpolation.h diff --git a/firmware/Makefile b/firmware/Makefile index 92bfbc9..795f7bc 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -144,6 +144,7 @@ CPPSRC = $(ALLCPPSRC) \ pid.cpp \ pump_control.cpp \ uart.cpp \ + interpolation.cpp \ main.cpp # List ASM source files here. diff --git a/firmware/interpolation.cpp b/firmware/interpolation.cpp new file mode 100644 index 0000000..2f99e12 --- /dev/null +++ b/firmware/interpolation.cpp @@ -0,0 +1,37 @@ +#include "interpolation.h" + +int interpolateInt(int x1, int y1, int x2, int y2, int x) +{ + if (x1 == x2) + return y1; + + return (y1 + (y2 - y1) * (x - x1) / (x2 - x1)); +} + +int interpolateIntClamped(int x1, int y1, int x2, int y2, int x) +{ + if (x <= x1) + return y1; + if (x >= x2) + return y2; + + return interpolateInt(x1, y1, x2, y2, x); +} + +int interpolate_1d_int(const struct inter_point *p, int size, int x) +{ + int i; + + /* no exterpolation */ + if (x < p[0].x) + return p[0].y; + + for (i = 0; i < size - 1; i++) { + if ((x >= p[i].x) && (x < p[i + 1].x)) { + return interpolateInt(p[i].x, p[i].y, p[i + 1].x, p[i + 1].y, x); + } + } + + /* no exterpolation */ + return p[size - 1].y; +} diff --git a/firmware/interpolation.h b/firmware/interpolation.h new file mode 100644 index 0000000..aa79d25 --- /dev/null +++ b/firmware/interpolation.h @@ -0,0 +1,10 @@ +#pragma once + +struct inter_point { + int x; + int y; +}; + +int interpolateInt(int x1, int y1, int x2, int y2, int x); +int interpolateIntClamped(int x1, int y1, int x2, int y2, int x); +int interpolate_1d_int(const struct inter_point *p, int size, int x); diff --git a/firmware/sampling.cpp b/firmware/sampling.cpp index 4810e8a..8ea72e7 100644 --- a/firmware/sampling.cpp +++ b/firmware/sampling.cpp @@ -1,4 +1,5 @@ #include "sampling.h" +#include "interpolation.h" #include "ch.h" #include "hal.h" @@ -14,6 +15,27 @@ static float nernstDc = 0; static float pumpCurrentSenseVoltage = 0; static float internalBatteryVoltage = 0; +static const struct inter_point lsu49_r_to_temp[] = +{ + { 80, 1030}, + { 150, 890}, + { 200, 840}, + { 250, 805}, + { 300, 780}, + { 350, 760}, + { 400, 745}, + { 450, 730}, + { 550, 705}, + { 650, 685}, + { 800, 665}, + { 1000, 640}, + { 1200, 630}, + { 2500, 565}, + { 6000, 25} /* measured while cold */ +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + constexpr float f_abs(float x) { return x > 0 ? x : -x; @@ -86,6 +108,11 @@ float GetSensorInternalResistance() return totalEsr - VM_RESISTOR_VALUE; } +float GetSensorTemperature() +{ + return interpolate_1d_int(lsu49_r_to_temp, ARRAY_SIZE(lsu49_r_to_temp), GetSensorInternalResistance()); +} + float GetNernstDc() { return nernstDc; diff --git a/firmware/sampling.h b/firmware/sampling.h index 34c796d..e376e05 100644 --- a/firmware/sampling.h +++ b/firmware/sampling.h @@ -4,6 +4,7 @@ void StartSampling(); float GetNernstAc(); float GetSensorInternalResistance(); +float GetSensorTemperature(); float GetNernstDc(); float GetPumpNominalCurrent();