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 \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)