Skip to content

Instantly share code, notes, and snippets.

@HiFiPhile
Created August 6, 2020 08:26
Show Gist options
  • Save HiFiPhile/c8b44b0366674261440912fa8d8a2d60 to your computer and use it in GitHub Desktop.
Save HiFiPhile/c8b44b0366674261440912fa8d8a2d60 to your computer and use it in GitHub Desktop.
Table based NTC Code Generator (by Gerd Bartelt, sebulli)
<!DOCTYPE html>
<!-- saved from url=(0036)http://www.sebulli.com/ntc/index.php -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="Gerd Bartelt, sebulli">
<meta name="description" content="Gerd Bartelt - Projects">
<meta name="page-topic" content="Table based NTC Code Generator">
<meta name="language" content="en">
<meta name="content-language" content="en">
<meta http-equiv="language" content="en">
<meta http-equiv="content-language" content="en">
<meta name="revisit-after" content="10 days">
<meta name="robots" content="index, follow">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<title>Table based NTC Code Generator</title>
<script>
HTTP_GET_VARS=new Array();
strGET=document.location.search.substr(1,document.location.search.length);
if(strGET!='') {
gArr=strGET.split('&');
for(i=0;i<gArr.length;++i){
v='';vArr=gArr[i].split('=');
if(vArr.length>1){v=vArr[1];}
HTTP_GET_VARS[unescape(vArr[0])]=unescape(v);
}
}
function GET(v) {
if(!HTTP_GET_VARS[v]){return 'undefined';}
return HTTP_GET_VARS[v];
}
function div2shift(v) {
if (v == 1) return 0;
if (v == 2) return 1;
if (v == 4) return 2;
if (v == 8) return 3;
if (v == 16) return 4;
if (v == 32) return 5;
if (v == 64) return 6;
if (v == 128) return 7;
if (v == 256) return 8;
if (v == 512) return 9;
if (v == 1024) return 10;
if (v == 2048) return 11;
if (v == 4096) return 12;
return 0;
}
function bit2mask(v, is_int) {
if (is_int) {
if (v == 1) return "0x000F";
if (v == 2) return "0x0001";
if (v == 4) return "0x0003";
if (v == 8) return "0x0007";
if (v == 16) return "0x000F";
if (v == 32) return "0x001F";
if (v == 64) return "0x003F";
if (v == 128) return "0x007F";
if (v == 256) return "0x00FF";
if (v == 512) return "0x01FF";
if (v == 1024) return "0x03FF";
if (v == 2048) return "0x07FF";
if (v == 4096) return "0x0FFF";
}
else
if (v == 1) return "0x0F";
if (v == 2) return "0x01";
if (v == 4) return "0x03";
if (v == 8) return "0x07";
if (v == 16) return "0x0F";
if (v == 32) return "0x1F";
if (v == 64) return "0x3F";
if (v == 128) return "0x7F";
if (v == 256) return "0xFF";
if (v == 512) return "0x01FF";
if (v == 1024) return "0x03FF";
if (v == 2048) return "0x07FF";
if (v == 4096) return "0x0FFF";
}
function bit2stepmask(v) {
if (v == 1) return 0x000F;
if (v == 2) return 0x0001;
if (v == 4) return 0x0003;
if (v == 8) return 0x0007;
if (v == 16) return 0x000F;
if (v == 32) return 0x001F;
if (v == 64) return 0x003F;
if (v == 128) return 0x007F;
if (v == 256) return 0x00FF;
if (v == 512) return 0x01FF;
if (v == 1024) return 0x03FF;
if (v == 2048) return 0x07FF;
if (v == 4096) return 0x0FFF;
}
var adc_step;
var adc_stepmask;
var nointerpol = 0;
var circuit = 1;
if (GET('circuit') == 'pulldown')
circuit = 0;
if (GET('circuit') == 'pullup')
circuit = 1;
var points;
points = Number(GET('points'));
if (points < 8)
points = 8;
if (points > 4096)
points = 4096;
var resolution = 8;
if (GET('resolution') == '8+Bit')
resolution = 8;
if (GET('resolution') == '10+Bit')
resolution = 10;
if (GET('resolution') == '12+Bit')
resolution = 12;
if ((resolution == 8) && (points >= 256)) {
nointerpol = 1;
points = 256;
}
if ((resolution == 10) && (points >= 1024)) {
nointerpol = 1;
points = 1024;
}
if ((resolution == 12) && (points >= 4096)) {
nointerpol = 1;
points = 4096;
}
var adctype = "unsigned char ";
if (resolution>8)
adctype = "unsigned int ";
var resistor;
resistor = Number(GET('resistor'));
if (resistor < 1)
resistor = 10000;
if (resistor > 10000000)
resistor = 10000000;
var r25;
r25 = Number(GET('r25'));
if (r25 < 1)
r25 = 10000;
if (r25 > 10000000)
r25 = 10000000;
var beta;
beta = Number(GET('beta'));
if (beta < 100)
beta = 3480;
if (beta > 10000)
beta = 10000;
var test_resistance;
test_resistance = Number(GET('test_resistance'));
var unit;
unit = Number(GET('unit'));
if (unit < 0.00001)
unit = 0.1;
if (unit > 10)
unit = 10;
var tmin;
tmin = Number(GET('tmin'));
if (tmin < -273.15)
tmin = -273.15;
if (tmin > 1000)
tmin = 1000;
var tmax;
tmax = Number(GET('tmax'));
if (tmax < -273.15)
tmax = -273.15;
if (tmax > 1000)
tmax = 1000;
if (tmax < tmin)
tmax = tmin;
if (!Number(GET('points'))) {
circuit = 0;
points = 32;
resolution = 8;
r25 = 10000;
resistor = 10000;
unit = 0.1;
beta = 3480;
tmin = -10;
tmax = 50;
test_resistance = r25;
}
</script>
</head>
<body>
</div>
<div id="inhalt">
<h1>Table based NTC Code Generator</h1>
<img src="./Table based NTC Code Generator_files/ntc.png" alt="NTC" class="img"><br>
<p>Generates a C Code to calculate temperature in °C from an ADC values of a NTC voltage divider. </p>
<form method="get">
<script>
var t0 = -273.15;
var tn = 25.0 -t0;
function resistance2temp(resistance) {
return beta*tn/(beta+Math.log(resistance/r25)*tn) + t0;
}
document.writeln('<input name="lang" type="hidden" value="en">');
document.writeln('Number of interpolating points:');
document.writeln('<select name="points" size="1">');
document.write('<option');if (points == 8) document.write(' selected');document.writeln('>8</option>');
document.write('<option');if (points == 16) document.write(' selected');document.writeln('>16</option>');
document.write('<option');if (points == 32) document.write(' selected');document.writeln('>32</option>');
document.write('<option');if (points == 64) document.write(' selected');document.writeln('>64</option>');
document.write('<option');if (points == 128) document.write(' selected');document.writeln('>128</option>');
document.write('<option');if (points == 256) document.write(' selected');document.writeln('>256</option>');
document.write('<option');if (points == 512) document.write(' selected');document.writeln('>512</option>');
document.write('<option');if (points == 1024) document.write(' selected');document.writeln('>1024</option>');
document.write('<option');if (points == 2048) document.write(' selected');document.writeln('>2048</option>');
document.write('<option');if (points == 4096) document.write(' selected');document.writeln('>4096</option>');
document.writeln('</select>');
document.writeln('<br /><br /> ');
document.writeln('Unit in &deg;C:<br /> ');
document.writeln('<input name="unit" type="text" size="10" maxlength="10" value="' + unit + '">');
document.writeln('<br /><br /> ');
document.writeln('ADC Resolution:');
document.writeln('<select name="resolution" size="1">');
document.write('<option');if (resolution == 8) document.write(' selected');document.writeln('>8 Bit</option>');
document.write('<option');if (resolution == 10) document.write(' selected');document.writeln('>10 Bit</option>');
document.write('<option');if (resolution == 12) document.write(' selected');document.writeln('>12 Bit</option>');
document.writeln('</select>');
document.writeln('<br /><br /> ');
document.writeln('NTC circuit: <br /> ');
document.write('<input type="radio" name="circuit" value="pulldown" ');if (circuit == 0) document.write(' checked="checked"');
document.writeln('>NTC with pull down resistor<br/>');
document.write('<input type="radio" name="circuit" value="pullup" ');if (circuit == 1) document.write(' checked="checked"');
document.writeln('>NTC with pull up resistor<br/>');
document.writeln('<br /><br /> ');
document.writeln('Pullup/down-resistance in Ohm:<br /> ');
document.writeln('<input name="resistor" type="text" size="10" maxlength="10" value="' + resistor + '">');
document.writeln('<br /><br /> ');
document.writeln('NTC resistance at 25&deg;C:<br /> ');
document.writeln('<input name="r25" type="text" size="10" maxlength="10" value="' + r25 + '">');
document.writeln('<br /><br /> ');
document.writeln('BETA value of the NTC:<br /> ');
document.writeln('<input name="beta" type="text" size="10" maxlength="10" value="' + beta + '">');
document.writeln('<br /><br /> ');
document.writeln('Test resistance:<br /> ');
document.writeln('<input name="test_resistance" type="text" size="10" maxlength="20" value="' + test_resistance + '">');
document.writeln(resistance2temp(test_resistance) + '&deg;');
document.writeln('<br /><br /> ');
document.writeln('Measure range:<br /> ');
document.writeln('From <input name="tmin" type="text" size="3" maxlength="10" value="' + tmin + '">&deg;C to <input name="tmax" type="text" size="3" maxlength="10" value="' + tmax + '">&deg;C');
document.writeln('<br /><br /> ');
</script>
<input type="submit" value="Generate C-Code now">
</form>
<!-- Finally, to actually run the highlighter, you need to include this JS on your page -->
<script>
// Calculate the maximum ADC value
var max_adc = 256;
if (resolution == 10)
max_adc = 1024;
if (resolution == 12)
max_adc = 4096;
// Calculate the step from one point to an other
adc_step = max_adc / points;
adc_stepmask = bit2stepmask(adc_step);
if (GET('points') && GET('resolution') && GET('circuit') && Number(GET('points'))) {
tablevals = new Array(points+1);
var column = 0;
var adc_val;
var resistance;
var temperature;
var t0 = -273.15;
var is_signed = 0;
var is_int = 0;
var ipadd = 1;
if (nointerpol)
ipadd = 0;
function adc2temp(adc_v) {
if (circuit == 0)
resistance = resistor / (max_adc/(max_adc - adc_v - 1) - 1.0);
else
resistance = resistor / (max_adc/adc_v - 1.0);
return resistance2temp(resistance);
}
function f2i(f){
if (f >= 0)
return Math.floor(f);
else
return Math.ceil(f);
}
function adc2temp_table(adc_v) {
var p1,p2;
p1 = tablevals[ f2i(adc_v / adc_step) ];
p2 = tablevals[ f2i(adc_v / adc_step)+1];
return p1 + f2i(( (p2-p1) * (adc_v & adc_stepmask) ) / adc_step);
}
for (var i =0; i<(points+ipadd); i++) {
temperature = adc2temp(i*adc_step);
temperature = Math.round(temperature / unit);
tablevals[i] = temperature;
}
// Correct the first and the last entry
tablevals[0] = tablevals[1] - (tablevals[2] -tablevals[1]);
tablevals[points-1+ipadd] = tablevals[points-2+ipadd] - (tablevals[points-3+ipadd] -tablevals[points-2+ipadd]);
var maxerror = 0.0;
var terror = 0.0;
for (var i=1 ; i < (max_adc-1); i++) {
temperature = adc2temp(i);
if (( temperature >= tmin) && (temperature < tmax)) {
terror = Math.abs(adc2temp_table(i)*unit-temperature);
if (terror > maxerror)
maxerror = terror;
}
}
var smaxerror;
smaxerror = maxerror.toFixed(3);
if ((tablevals[0] < 0) || (tablevals[points-1+ipadd] < 0))
is_signed = 1;
if (is_signed) {
if ((tablevals[0] < -128) || (tablevals[points-1+ipadd] < -128))
is_int = 1;
if ((tablevals[0] > 127) || (tablevals[points-1+ipadd] > 127))
is_int = 1;
}
else {
if ((tablevals[0] > 255) || (tablevals[points-1+ipadd] > 255))
is_int = 1;
}
if (!nointerpol) {
document.writeln('<br /><br />Error caused by the usage of a table:' + smaxerror + '&deg;C.<br />');
}
document.writeln('<br /><br />C-Code: <br />');
document.writeln('<div style="width: 1000px; padding: 1px 0px 1px 0px ;margin:auto; background-color: #fff;">');
document.writeln('<pre class="brush: cpp">');
document.writeln('/**');
document.writeln('* The NTC table has ' + (points+ipadd) + ' interpolation points.');
document.writeln('* Unit:'+ unit + ' &deg;C');
document.writeln('*');
document.writeln('*/');
var temptype = "";
if (!is_signed)
temptype = "unsigned ";
if (is_int)
temptype+= "int ";
else
temptype+= "char ";
document.writeln(temptype + 'NTC_table['+ (points+ipadd) +'] = {');
document.write(' ');
for (var i =0; i<(points+ipadd); i++) {
if (i != 0) {
document.write(', ');
column +=2;
}
// columns size: max 80
if (column > 40) {
column = 0;
document.writeln('');
document.write(' ');
}
column += String(tablevals[i]).length;
document.write(tablevals[i]);
}
document.writeln('');
document.writeln('};');
document.writeln('');
document.writeln('');
document.writeln('');
document.writeln('/**');
document.writeln('* \\brief Converts the ADC result into a temperature value.');
document.writeln('*');
if (!nointerpol) {
document.writeln('* P1 and p2 are the interpolating point just before and after the');
document.writeln('* ADC value. The function interpolates between these two points');
document.writeln('* The resulting code is very small and fast.');
document.writeln('* Only one integer multiplication is used.');
document.writeln('* The compiler can replace the division by a shift operation.');
document.writeln('*');
document.writeln('* In the temperature range from '+ tmin + '&deg;C to '+ tmax + '&deg;C the error');
document.writeln('* caused by the usage of a table is '+ smaxerror + '&deg;C');
} else {
document.writeln('* The temperature values are read from the table.');
}
document.writeln('*');
document.writeln('* \\param adc_value The converted ADC result');
document.writeln('* \\return The temperature in '+ unit + ' &deg;C');
document.writeln('*');
document.writeln('*/');
document.writeln(temptype + 'NTC_ADC2Temperature(' + adctype + 'adc_value){');
document.writeln('');
if (!nointerpol) {
document.writeln(' ' + temptype + 'p1,p2;');
document.writeln(' /* Estimate the interpolating point before and after the ADC value. */');
document.writeln(' p1 = NTC_table[ (adc_value >> ' + div2shift(adc_step) + ') ];');
document.writeln(' p2 = NTC_table[ (adc_value >> ' + div2shift(adc_step) + ')+1];');
document.writeln('');
document.writeln(' /* Interpolate between both points. */');
if (circuit == 1)
document.write(' return p1 - ( (p1-p2) * (adc_value & ' +bit2mask(adc_step, resolution > 8)+') ) ');
else
document.write(' return p1 + ( (p2-p1) * (adc_value & ' +bit2mask(adc_step, resolution > 8)+') ) ');
if (is_signed)
document.writeln('/ ' + adc_step + ';');
else
document.writeln('/ ' + div2shift(adc_step) + ';');
} else {
document.writeln(' /* Read values directly from the table. */');
document.writeln(' return NTC_table[ adc_value ];');
}
document.writeln('};');
document.writeln('</pre>');
document.writeln('</div>');
SyntaxHighlighter.all()
}
</script>
</div>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment