From 55bee1a5d83f2275abc5eb09d1989cc8509e6c50 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Fri, 17 Apr 2026 22:21:18 +0200 Subject: [PATCH] push script to generate NTC lut --- fw/main.c | 13 +++++----- fw/script/ntc_lut.py | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-) create mode 100755 fw/script/ntc_lut.py diff --git a/fw/main.c b/fw/main.c index 40f75de..c15d1d2 100644 --- a/fw/main.c +++ b/fw/main.c @@ -28,11 +28,12 @@ // constants // LUT for converting NTC readings to degrees kelvin // Nominal: 1kOhm, Beta: 3380, Step: 64 -// TODO: Since the board temperature is almost always in the 300-200K range add -// more steps in order to better represent that interval const uint8_t ntc_step_size = 64; -const int16_t ntc_table[64] = { - 1180, 197, 155, 133, 119, 108, 100, 93, 87, 82, 77, 73, 69, 66, 63, 60, 57, 54, 52, 50, 47, 45, 43, 41, 39, 37, 35, 34, 32, 30, 28, 27, 25, 23, 22, 20, 19, 17, 15, 14, 12, 11, 9, 7, 6, 4, 2, 0, -1, -3, -5, -7, -9, -11, -14, -16, -19, -22, -25, -28, -33, -38, -44, -55 +const int16_t ntc_lut[] = { + 1316, 197, 155, 133, 119, 108, 100, 93, 87, 82, 77, 73, 69, 66, 63, 60, + 57, 54, 52, 50, 47, 45, 43, 41, 39, 37, 35, 34, 32, 30, 28, 27, + 25, 23, 22, 20, 19, 17, 15, 14, 12, 11, 9, 7, 6, 4, 2, 0, + -1, -3, -5, -7, -9, -11, -14, -16, -19, -22, -25, -28, -32, -38, -44, -55 }; @@ -50,8 +51,8 @@ static inline int16_t get_temp_k(uint16_t adc_reading) if (adc_reading > 4095) return 0; uint8_t index = adc_reading / ntc_step_size; uint8_t remainder = adc_reading % ntc_step_size; - int16_t temp_base = index < 64 ? ntc_table[index] : 0; - int16_t temp_next = index < 63 ? ntc_table[index + 1] : temp_base; + int16_t temp_base = index < 64 ? ntc_lut[index] : 0; + int16_t temp_next = index < 63 ? ntc_lut[index + 1] : temp_base; return temp_base + ((temp_next - temp_base) * remainder)/ntc_step_size; } diff --git a/fw/script/ntc_lut.py b/fw/script/ntc_lut.py new file mode 100755 index 0000000..476e038 --- /dev/null +++ b/fw/script/ntc_lut.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +import math + +# Script to generate NTC lookup table +# ^ Vcc +# | +# [RES] +# | +# +-- Vadc +# | +# [NTC] +# | +# _|_ GND +# /// + +adc_res = 12 +ntc_value = 10_000 # at 25°C +resistor_value = 10_000 +ntc_beta = 3380 # at 25°C +steps = 64 + +# NTC resistance to temperature (°C) conversion +def resistance_to_t(ntc_r): + # Standard B-parameter equation + # T = 1 / (1/T0 + 1/B * ln(R/R0)) + inv_t = 1/(25 + 273.15) + math.log(ntc_r/ntc_value)/ntc_beta + return 1/inv_t - 273.15 + +# Resistor divider percentage to NTC resistance conversion +# x = NTC / (NTC + RES) => NTC = RES * x / (1 - x) +def x_to_r(x): + x = max(0.0001, min(0.9999, x)) + return resistor_value * x / (1 - x) + +# Use 4096 for cleaner divisions +adc_max = 2**adc_res +step_size = adc_max // steps + +values = [] +for i in range(steps): + adc_val = i * step_size + x = adc_val / adc_max + r = x_to_r(adc_val / adc_max) + t = resistance_to_t(r) + values.append(int(round(t))) + +def to_c_array(values, ctype="float", name="table", formatter=str, colcount=8): + # apply formatting to each element + values = [formatter(v) for v in values] + # split into rows with up to `colcount` elements per row + rows = [values[i:i+colcount] for i in range(0, len(values), colcount)] + # separate elements with commas, separate rows with newlines + body = ',\n '.join([', '.join(r) for r in rows]) + # assemble components into the complete string + return '{} {}[] = {{\n {}}};'.format(ctype, name, body) + +print("uint8_t ntc_step_size = {};".format(int(step_size))) +print(to_c_array(values, ctype="int16_t", name="ntc_lut", formatter=str, colcount=16))