Skip to content
This repository has been archived by the owner on Aug 27, 2023. It is now read-only.

Thermistor config #208

Open
wants to merge 4 commits into
base: experimental
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions configtool/thermistortablefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def generateTempTables(sensors, settings):

ofp.output("#define NUMTABLES %d" % len(tl))
ofp.output("#define NUMTEMPS %d" % N)
ofp.output("#define TEMPTABLE_FORMAT 1")
ofp.output("");

for i in range(len(tl)):
Expand All @@ -65,7 +66,7 @@ def generateTempTables(sensors, settings):
ofp.close();
return True

ofp.output("const uint16_t PROGMEM temptable[NUMTABLES][NUMTEMPS][2] = {")
ofp.output("const uint16_t PROGMEM temptable[NUMTABLES][NUMTEMPS][3] = {")

tcount = 0
for tn in tl:
Expand Down Expand Up @@ -102,8 +103,9 @@ def BetaTable(ofp, params, names, settings, finalTable):

samples = optimizeTempTable(thrm, N, hiadc)

prev = samples[0]
for i in samples:
t = int(thrm.temp(i))
t = thrm.temp(i)
if t is None:
ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i)
continue
Expand All @@ -117,10 +119,12 @@ def BetaTable(ofp, params, names, settings, finalTable):
c = " "
else:
c = ","
ostr = (" {%4s, %5s}%s // %4d C, %6.0f ohms, %0.3f V,"
" %0.2f mW") % (i, t * 4, c, t, int(round(r)),
vTherm, ptherm * 1000)
delta = (t-thrm.temp(prev))/(prev-i) if i!=prev else 0
ostr = (" {%4s, %5s, %5s}%s // %4d C, %6.0f ohms, %0.3f V,"
" %0.2f mW, m=%0.4f") % (i, int(t * 4), int(delta*4*256), c,
int(t), int(round(r)), vTherm, ptherm * 1000, delta)
ofp.output(ostr)
prev = i

if finalTable:
ofp.output(" }")
Expand All @@ -145,8 +149,9 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):

samples = optimizeTempTable(thrm, N, hiadc)

prev = samples[0]
for i in samples:
t = int(thrm.temp(i))
t = thrm.temp(i)
if t is None:
ofp.output("// ERROR CALCULATING THERMISTOR VALUES AT ADC %d" % i)
continue
Expand All @@ -157,8 +162,10 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
c = " "
else:
c = ","
ofp.output(" {%4d, %5d}%s // %4d C, %6d ohms" %
(i, t * 4, c, t, int(round(r))))
delta = (t-thrm.temp(prev))/(prev-i) if i!=prev else 0
ofp.output(" {%4d, %5d, %5d}%s // %4d C, %6d ohms, m=%0.4f" %
(i, int(t * 4), int(delta*4*256), c, int(t), int(round(r))), delta)
prev = i

if finalTable:
ofp.output(" }")
Expand Down
1 change: 1 addition & 0 deletions simulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ void sim_error(const char msg[]);
void sim_assert(bool cond, const char msg[]);
void sim_gcode_ch(char ch);
void sim_gcode(const char msg[]);
void sim_report_temptables(int sensor) ;

/**
* Initialize simulator timer and set time scale.
Expand Down
30 changes: 28 additions & 2 deletions simulator/analog_sim.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
#include "temp.h"
#include "analog.h"
#include "simulator.h"
#include <stdio.h>

static bool analog_initialised = false;

void analog_init(void) {
sim_info("analog_init: not implemented in simulator");
analog_initialised = true;
}

static uint16_t analog_read_value = 0;
uint16_t analog_read(uint8_t channel) {
sim_assert(analog_initialised, "analog_init() was not called before analog_read()");
sim_assert(sim_interrupts, "interrupts disabled");
return 0;
return analog_read_value;
}

void sim_report_temptables(int sensor) {
int i ;
temp_sensor_t s, first = sensor, last = sensor+1 ;

// sensor is a specific sensor or -1 for "all sensors"
if (sensor == -1) {
first = 0;
last = NUM_TEMP_SENSORS;
}

sei();
analog_init();
printf("; Temperature sensor test %d\n", sensor);
for (s = first; s < last; s++ ) {
printf("; Sensor %d\n", s);
for (i = 0 ; i < 1024 ; i++ ) {
analog_read_value = i ;
temp_sensor_tick() ;
uint16_t temp = temp_get(s);
printf("%d %.2f\n", i, ((float)temp)/4 ) ;
}
}
}
7 changes: 6 additions & 1 deletion simulator/simulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ int verbose = 1; ///< 0=quiet, 1=normal, 2=noisy, 3=debug, etc.
int trace_gcode = 0; ///< show gcode on the console
int trace_pos = 0; ///< show print head position on the console

const char * shortopts = "qgpvt:o::";
const char * shortopts = "qgpvt:o::T::";
struct option opts[] = {
{ "quiet", no_argument, &verbose , 0 },
{ "verbose", no_argument, NULL, 'v' },
{ "gcode", no_argument, NULL, 'g' },
{ "pos", no_argument, NULL, 'p' },
{ "time-scale", required_argument, NULL, 't' },
{ "tracefile", optional_argument, NULL, 'o' },
{ "report-temptable", optional_argument, NULL, 'T' },
{ 0, 0, 0, 0 }
};

Expand All @@ -65,6 +66,7 @@ static void usage(const char *name) {
printf(" -p || --pos show head position on console\n");
printf(" -t || --time-scale=n set time-scale; 0=warp-speed, 1=real-time, 2=half-time, etc.\n");
printf(" -o || --tracefile[=filename] write simulator pin trace to 'outfile' (default filename=datalog.out)\n");
printf(" -T || --report-temptable=n Report calculated temperatures for all ADC values and exit\n");
printf("\n");
exit(1);
}
Expand Down Expand Up @@ -96,6 +98,9 @@ void sim_start(int argc, char** argv) {
case 'o':
recorder_init(optarg ? optarg : "datalog.out");
break;
case 'T':
sim_report_temptables(optarg ? atoi(optarg) : -1);
exit(0);
default:
exit(1);
}
Expand Down
93 changes: 52 additions & 41 deletions temp.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,53 +186,64 @@ static uint16_t mcp3008_read(uint8_t channel) {
*/
#if defined TEMP_THERMISTOR || defined TEMP_MCP3008
static uint16_t temp_table_lookup(uint16_t temp, uint8_t sensor) {
uint8_t j;
uint8_t lo, hi;
uint8_t table_num = temp_sensors[sensor].additional;

for (j = 1; j < NUMTEMPS; j++) {
if (pgm_read_word(&(temptable[table_num][j][0])) > temp) {

if (DEBUG_PID && (debug_flags & DEBUG_PID))
sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),
temp_sensors[sensor].temp_pin, temp, j);

// Wikipedia's example linear interpolation formula.
// y = ((x - x₀)y₁ + (x₁-x)y₀) / (x₁ - x₀)
// y = temp
// x = ADC reading
// x₀= temptable[j-1][0]
// x₁= temptable[j][0]
// y₀= temptable[j-1][1]
// y₁= temptable[j][1]
temp = (
// ((x - x₀)y₁
((uint32_t)temp - pgm_read_word(&(temptable[table_num][j-1][0]))) *
pgm_read_word(&(temptable[table_num][j][1]))
// +
+
// (x₁-x)y₀)
(pgm_read_word(&(temptable[table_num][j][0])) - (uint32_t)temp) *
pgm_read_word(&(temptable[table_num][j - 1][1])))
// /
/
// (x₁ - x₀)
(pgm_read_word(&(temptable[table_num][j][0])) -
pgm_read_word(&(temptable[table_num][j - 1][0])));

if (DEBUG_PID && (debug_flags & DEBUG_PID))
sersendf_P(PSTR(" temp:%d.%d"), temp / 4, (temp % 4) * 25);

// Value found, no need to read the table further.
break;
}
// Binary search for table value bigger than our target
for (lo = 0, hi=NUMTEMPS-1 ; hi-lo > 1 ; ) {
uint8_t j = lo + (hi - lo) / 2 ;
if (pgm_read_word(&(temptable[table_num][j][0])) >= temp)
hi = j ;
else
lo = j ;
}
// lo = index of highest entry less than target
// hi = index of lowest entry greater than or equal to target

if (DEBUG_PID && (debug_flags & DEBUG_PID))
sersendf_P(PSTR(" Sensor:%d\n"), sensor);
sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),
temp_sensors[sensor].temp_pin, temp, hi);

#if (TEMPTABLE_FORMAT == 0)
// Wikipedia's example linear interpolation formula.
// y = ((x - x₀)y₁ + (x₁-x)y₀) / (x₁ - x₀)
// y = temp
// x = ADC reading
// x₀= temptable[lo][0]
// x₁= temptable[hi][0]
// y₀= temptable[lo][1]
// y₁= temptable[hi][1]
temp = (
// ((x - x₀)y₁
((uint32_t)temp - pgm_read_word(&(temptable[table_num][lo][0]))) *
pgm_read_word(&(temptable[table_num][hi][1]))
// +
+
// (x₁-x)y₀)
(pgm_read_word(&(temptable[table_num][hi][0])) - (uint32_t)temp) *
pgm_read_word(&(temptable[table_num][lo][1])))
// /
/
// (x₁ - x₀)
(pgm_read_word(&(temptable[table_num][hi][0])) -
pgm_read_word(&(temptable[table_num][lo][0])));
#elif (TEMPTABLE_FORMAT == 1)
// Linear interpolation using pre-computed slope
// y = y₁ - (x-x₁)*d₁
#define X1 pgm_read_word(&(temptable[table_num][hi][0]))
#define Y1 pgm_read_word(&(temptable[table_num][hi][1]))
#define D1 pgm_read_word(&(temptable[table_num][hi][2]))

temp = Y1 - ((((int32_t)temp - X1) * D1 + (1<<7)) >> 8);
#else
#error "temptable format unrecognized"
#endif

if (DEBUG_PID && (debug_flags & DEBUG_PID))
sersendf_P(PSTR(" temp:%d.%d"), temp / 4, (temp % 4) * 25);

// Clamp for overflows.
if (j == NUMTEMPS)
temp = temptable[table_num][NUMTEMPS - 1][1];
if (DEBUG_PID && (debug_flags & DEBUG_PID))
sersendf_P(PSTR(" Sensor:%d\n"), sensor);

return temp;
}
Expand Down