foxBMS  1.4.0
The foxBMS Battery Management System API Documentation
vishay_ntcalug01a103g.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file vishay_ntcalug01a103g.c
44  * @author foxBMS Team
45  * @date 2018-10-30 (date of creation)
46  * @updated 2022-07-28 (date of last update)
47  * @version v1.4.0
48  * @ingroup TEMPERATURE_SENSORS
49  * @prefix TS
50  *
51  * @brief Resistive divider used for measuring temperature
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "vishay_ntcalug01a103g.h"
57 
58 #include "foxmath.h"
60 
61 /*========== Macros and Definitions =========================================*/
62 
63 /*========== Static Constant and Variable Definitions =======================*/
64 
65 /* clang-format off */
66 /** LUT filled from higher resistance to lower resistance */
68  { -400, 334274.4f},
69  { -390, 312904.4f},
70  { -380, 293033.6f},
71  { -370, 274548.0f},
72  { -360, 257343.1f},
73  { -350, 241322.9f},
74  { -340, 226398.8f},
75  { -330, 212489.7f},
76  { -320, 199520.6f},
77  { -310, 187422.7f},
78  { -300, 176132.5f},
79  { -290, 165591.5f},
80  { -280, 155745.6f},
81  { -270, 146545.1f},
82  { -260, 137944.1f},
83  { -250, 129900.0f},
84  { -240, 122373.7f},
85  { -230, 115329.0f},
86  { -220, 108732.2f},
87  { -210, 102552.5f},
88  { -200, 96761.1f },
89  { -190, 91331.5f },
90  { -180, 86239.0f },
91  { -170, 81460.9f },
92  { -160, 76976.0f },
93  { -150, 72764.6f },
94  { -140, 68808.6f },
95  { -130, 65091.1f },
96  { -120, 61596.4f },
97  { -110, 58309.9f },
98  { -100, 55218.1f },
99  { -90, 52308.4f },
100  { -80, 49569.0f },
101  { -70, 46989.1f },
102  { -60, 44558.56f},
103  { -50, 42267.85f},
104  { -40, 40108.20f},
105  { -30, 38071.41f},
106  { -20, 36149.83f},
107  { -10, 34336.32f},
108  { 0, 32624.23f},
109  { 10, 31007.34f},
110  { 20, 29479.85f},
111  { 30, 28036.35f},
112  { 40, 26671.76f},
113  { 50, 25381.36f},
114  { 60, 24160.73f},
115  { 70, 23005.71f},
116  { 80, 21912.45f},
117  { 90, 20877.31f},
118  { 100, 19896.90f},
119  { 110, 18968.04f},
120  { 120, 18087.75f},
121  { 130, 17253.25f},
122  { 140, 16461.90f},
123  { 150, 15711.26f},
124  { 160, 14999.01f},
125  { 170, 14323.01f},
126  { 180, 13681.22f},
127  { 190, 13071.73f},
128  { 200, 12492.75f},
129  { 210, 11942.59f},
130  { 220, 11419.69f},
131  { 230, 10922.54f},
132  { 240, 10449.75f},
133  { 250, 10000.00f},
134  { 260, 9572.05f },
135  { 270, 9164.74f },
136  { 280, 8776.97f },
137  { 290, 8407.70f },
138  { 300, 8055.96f },
139  { 310, 7720.82f },
140  { 320, 7401.43f },
141  { 330, 7096.96f },
142  { 340, 6806.64f },
143  { 350, 6529.74f },
144  { 360, 6265.58f },
145  { 370, 6013.51f },
146  { 380, 5772.92f },
147  { 390, 5543.22f },
148  { 400, 5323.88f },
149  { 410, 5114.37f },
150  { 420, 4914.20f },
151  { 430, 4722.92f },
152  { 440, 4540.08f },
153  { 450, 4365.27f },
154  { 460, 4198.11f },
155  { 470, 4038.21f },
156  { 480, 3885.23f },
157  { 490, 3738.84f },
158  { 500, 3598.72f },
159  { 510, 3464.58f },
160  { 520, 3336.12f },
161  { 530, 3213.08f },
162  { 540, 3095.22f },
163  { 550, 2982.27f },
164  { 560, 2874.02f },
165  { 570, 2770.26f },
166  { 580, 2670.76f },
167  { 590, 2575.34f },
168  { 600, 2483.82f },
169  { 610, 2396.00f },
170  { 620, 2311.74f },
171  { 630, 2230.85f },
172  { 640, 2153.21f },
173  { 650, 2078.65f },
174  { 660, 2007.05f },
175  { 670, 1938.27f },
176  { 680, 1872.19f },
177  { 690, 1808.69f },
178  { 700, 1747.65f },
179  { 710, 1688.98f },
180  { 720, 1632.56f },
181  { 730, 1578.31f },
182  { 740, 1526.13f },
183  { 750, 1475.92f },
184  { 760, 1427.62f },
185  { 770, 1381.12f },
186  { 780, 1336.37f },
187  { 790, 1293.29f },
188  { 800, 1251.80f },
189  { 810, 1211.85f },
190  { 820, 1173.36f },
191  { 830, 1136.28f },
192  { 840, 1100.55f },
193  { 850, 1066.11f },
194  { 860, 1032.91f },
195  { 870, 1000.91f },
196  { 880, 970.05f },
197  { 890, 940.29f },
198  { 900, 911.59f },
199  { 910, 883.89f },
200  { 920, 857.17f },
201  { 930, 831.38f },
202  { 940, 806.49f },
203  { 950, 782.46f },
204  { 960, 759.26f },
205  { 970, 736.85f },
206  { 980, 715.21f },
207  { 990, 694.31f },
208  { 1000, 674.11f },
209  { 1010, 654.60f },
210  { 1020, 635.74f },
211  { 1030, 617.51f },
212  { 1040, 599.88f },
213  { 1050, 582.84f }
214 };
215 /* clang-format on */
216 
217 /** size of the #ts_ntcalug01a103gLut LUT */
219 
220 /*========== Extern Constant and Variable Definitions =======================*/
221 /**
222  * Defines for calculating the ADC voltage on the ends of the operating range.
223  * The ADC voltage is calculated with the following formula:
224  *
225  * V_adc = ( ( V_supply * R_ntc ) / ( R + R_ntc ) )
226  *
227  * Depending on the position of the NTC in the voltage resistor (R_1/R_2),
228  * different R_ntc values are used for the calculation.
229  * @{
230  */
231 #if TS_VISHAY_NTCALUG01A103G_POSITION_IN_RESISTOR_DIVIDER_IS_R_1 == true
232 #define TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MAX_V \
233  (float)((TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_SUPPLY_VOLTAGE_V * ts_ntcalug01a103gLut[ts_ntcalug01a103gLutSize-1].resistance_Ohm) / (ts_ntcalug01a103gLut[ts_ntcalug01a103gLutSize-1].resistance_Ohm+TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_RESISTANCE_R_1_R_2_Ohm))
234 #define TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MIN_V \
235  (float)((TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_SUPPLY_VOLTAGE_V * ts_ntcalug01a103gLut[0].resistance_Ohm) / (ts_ntcalug01a103gLut[0].resistance_Ohm+TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_RESISTANCE_R_1_R_2_Ohm))
236 #else /* TS_VISHAY_NTCALUG01A103G_POSITION_IN_RESISTOR_DIVIDER_IS_R_1 == false */
237 #define TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MIN_V \
238  ((float)((TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_SUPPLY_VOLTAGE_V * ts_ntcalug01a103gLut[ts_ntcalug01a103gLutSize-1].resistance_Ohm) / (ts_ntcalug01a103gLut[ts_ntcalug01a103gLutSize-1].resistance_Ohm+TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_RESISTANCE_R_1_R_2_Ohm)))
239 #define TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MAX_V \
240  ((float)((TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_SUPPLY_VOLTAGE_V * ts_ntcalug01a103gLut[0].resistance_Ohm) / (ts_ntcalug01a103gLut[0].resistance_Ohm+TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_RESISTANCE_R_1_R_2_Ohm)))
241 #endif
242 /**@}*/
243 
244 /*========== Static Function Prototypes =====================================*/
245 
246 /*========== Static Function Implementations ================================*/
247 
248 /*========== Extern Function Implementations ================================*/
249 
250 extern int16_t TS_Vis00GetTemperatureFromLut(uint16_t adcVoltage_mV) {
251  int16_t temperature_ddegC = 0;
252  float resistance_Ohm = 0.0f;
253  float adcVoltage_V = adcVoltage_mV / 1000.0f; /* Convert mV to V */
254 
255  /* Check for valid ADC measurements to prevent undefined behavior */
257  /* Invalid measured ADC voltage -> sensor out of operating range or disconnected/shorted */
258  temperature_ddegC = INT16_MIN;
259  } else if (adcVoltage_V < TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MIN_V) {
260  /* Invalid measured ADC voltage -> sensor out of operating range or shorted/disconnected */
261  temperature_ddegC = INT16_MAX;
262  } else {
263  /* Calculate NTC resistance based on measured ADC voltage */
264 #if TS_VISHAY_NTCALUG01A103G_POSITION_IN_RESISTOR_DIVIDER_IS_R_1 == true
265  /* R_1 = R_2 * ( ( V_supply / V_adc ) - 1 ) */
268 #else /* TS_VISHAY_NTCALUG01A103G_POSITION_IN_RESISTOR_DIVIDER_IS_R_1 == false */
269  /* R_2 = R_1 * ( V_2 / ( V_supply - V_adc ) ) */
271  (adcVoltage_V / (TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_SUPPLY_VOLTAGE_V - adcVoltage_V));
272 #endif /* TS_VISHAY_NTCALUG01A103G_POSITION_IN_RESISTOR_DIVIDER_IS_R_1 */
273 
274  /* Variables for interpolating LUT value */
275  uint16_t between_high = 0;
276  uint16_t between_low = 0;
277  for (uint16_t i = 1u; i < ts_ntcalug01a103gLutSize; i++) {
278  if (resistance_Ohm < ts_ntcalug01a103gLut[i].resistance_Ohm) {
279  between_low = i + 1u;
280  between_high = i;
281  }
282  }
283 
284  /* Interpolate between LUT values, but do not extrapolate LUT! */
285  if (!(((between_high == 0u) && (between_low == 0u)) || /* measured resistance > maximum LUT resistance */
286  (between_low >= ts_ntcalug01a103gLutSize))) { /* measured resistance < minimum LUT resistance */
287  temperature_ddegC = (int16_t)MATH_LinearInterpolation(
288  ts_ntcalug01a103gLut[between_low].resistance_Ohm,
289  ts_ntcalug01a103gLut[between_low].temperature_ddegC,
290  ts_ntcalug01a103gLut[between_high].resistance_Ohm,
291  ts_ntcalug01a103gLut[between_high].temperature_ddegC,
292  resistance_Ohm);
293  }
294  }
295 
296  /* Return temperature based on measured NTC resistance */
297  return temperature_ddegC;
298 }
299 
300 extern int16_t TS_Vis00GetTemperatureFromPolynomial(uint16_t adcVoltage_mV) {
301  (void)adcVoltage_mV;
303  int16_t temperature_ddegC = 0;
304  /* TODO this is not implemented */
305  return temperature_ddegC;
306 }
307 
308 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:126
float MATH_LinearInterpolation(const float x1, const float y1, const float x2, const float y2, const float x_interpolate)
Linear inter-/extrapolates a third point according to two given points.
Definition: foxmath.c:86
math library for often used math functions
#define TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MIN_V
int16_t TS_Vis00GetTemperatureFromPolynomial(uint16_t adcVoltage_mV)
returns temperature based on measured ADC voltage
#define TS_VISHAY_NTCALUG01A103G_ADC_VOLTAGE_V_MAX_V
static const uint16_t ts_ntcalug01a103gLutSize
int16_t TS_Vis00GetTemperatureFromLut(uint16_t adcVoltage_mV)
returns temperature based on measured ADC voltage.
static const TS_TEMPERATURE_SENSOR_LUT_s ts_ntcalug01a103gLut[]
Resistive divider used for measuring temperature.
#define TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_SUPPLY_VOLTAGE_V
#define TS_VISHAY_NTCALUG01A103G_RESISTOR_DIVIDER_RESISTANCE_R_1_R_2_Ohm