feat: add code for lookup table generation
This commit is contained in:
parent
d9bfca095a
commit
cc8894f703
89
AMS_Master_Code/temp_gen_adbms.py
Normal file
89
AMS_Master_Code/temp_gen_adbms.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt # Import matplotlib for plotting
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
NTC_A1 = 0.003354016
|
||||||
|
NTC_B1 = 0.000300131
|
||||||
|
NTC_C1 = 5.08516E-06
|
||||||
|
NTC_D1 = 2.18765E-07
|
||||||
|
|
||||||
|
LOW_TEMP = 0
|
||||||
|
HIGH_TEMP = 70
|
||||||
|
N = 16 # Number of bits
|
||||||
|
VREF = 3.0
|
||||||
|
RESOLUTION = 0.01 # temp is in 0.01°C
|
||||||
|
TEMP_CONV = 1/RESOLUTION
|
||||||
|
CELSIUS_TO_KELVIN = 273.15
|
||||||
|
|
||||||
|
|
||||||
|
def calc_temp_c(adc_voltage):
|
||||||
|
log_ohms = np.log(1 / ((VREF / adc_voltage) - 1))
|
||||||
|
temperature = 1 / (
|
||||||
|
NTC_A1 +
|
||||||
|
NTC_B1 * log_ohms +
|
||||||
|
NTC_C1 * log_ohms**2 +
|
||||||
|
NTC_D1 * log_ohms**3
|
||||||
|
) - CELSIUS_TO_KELVIN
|
||||||
|
return temperature
|
||||||
|
|
||||||
|
def calc_voltage(adc_code):
|
||||||
|
return adc_code * 150e-6 + 1.5 # Convert ADC ADBMS code to voltage
|
||||||
|
|
||||||
|
def temp_table(adc_codes):
|
||||||
|
temp = []
|
||||||
|
for adc_code in adc_codes: # Signed 16-bit ADC range
|
||||||
|
adc_voltage = calc_voltage(adc_code)
|
||||||
|
try:
|
||||||
|
temperature = calc_temp_c(adc_voltage)
|
||||||
|
except (ValueError, ZeroDivisionError):
|
||||||
|
temperature = None # Handle invalid calculations gracefully
|
||||||
|
temp.append(temperature)
|
||||||
|
return np.array(temp)
|
||||||
|
|
||||||
|
def make_c_code(temp_values, low_t_adc, high_t_adc):
|
||||||
|
# generate C code of an array and put into code.c file
|
||||||
|
with open("tempTable.h", "w") as f:
|
||||||
|
f.write("#include <stdint.h>\nconst uint16_t ADC2TEMP[] = {\n")
|
||||||
|
for temp in temp_values:
|
||||||
|
f.write(f" {(int)(temp*TEMP_CONV)}")
|
||||||
|
if temp != temp_values[-1]:
|
||||||
|
f.write(",")
|
||||||
|
f.write("};")
|
||||||
|
|
||||||
|
with open("tempCalc.c", "w") as f:
|
||||||
|
f.write("""#include "tempTable.h"
|
||||||
|
|
||||||
|
static inline uint16_t ntc_mv_to_celsius(int16_t adc) {
|
||||||
|
// Out of bounds checking --> done by OV/UV setting of the BMS?
|
||||||
|
if (adc < """ + str(int(low_t_adc)) + """ || adc > """ + str(int(high_t_adc)) + """) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ADC2TEMP[adc + """ + str(-int(low_t_adc)) + """];
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
adc_codes = np.linspace(-2**(N - 1), 2**(N - 1) - 1, 2**N)
|
||||||
|
temp_values = temp_table(adc_codes)
|
||||||
|
|
||||||
|
bool_vec = (temp_values >= LOW_TEMP) & (temp_values <= HIGH_TEMP)
|
||||||
|
|
||||||
|
low_t_adc = adc_codes[bool_vec][0]
|
||||||
|
high_t_adc = adc_codes[bool_vec][-1]
|
||||||
|
print(f"ADC code for {LOW_TEMP}°C: {low_t_adc}")
|
||||||
|
print(f"ADC code for {HIGH_TEMP}°C: {high_t_adc}")
|
||||||
|
|
||||||
|
plt.figure(figsize=(10, 6))
|
||||||
|
plt.plot(adc_codes[bool_vec], temp_values[bool_vec], "b", label="0°C to 70°C")
|
||||||
|
# plt.plot(adc_codes, temp_values, "r")
|
||||||
|
# plt.xlim([-10000, 10000])
|
||||||
|
plt.title("ADC Code to Temperature Conversion")
|
||||||
|
plt.xlabel("ADC Code")
|
||||||
|
plt.ylabel("Temperature (°C)")
|
||||||
|
plt.grid(True)
|
||||||
|
plt.legend()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
make_c_code(temp_values[bool_vec], low_t_adc, high_t_adc)
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user