Created
August 6, 2020 08:26
-
-
Save HiFiPhile/c8b44b0366674261440912fa8d8a2d60 to your computer and use it in GitHub Desktop.
Table based NTC Code Generator (by Gerd Bartelt, sebulli)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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 °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°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) + '°'); | |
document.writeln('<br /><br /> '); | |
document.writeln('Measure range:<br /> '); | |
document.writeln('From <input name="tmin" type="text" size="3" maxlength="10" value="' + tmin + '">°C to <input name="tmax" type="text" size="3" maxlength="10" value="' + tmax + '">°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 + '°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 + ' °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 + '°C to '+ tmax + '°C the error'); | |
document.writeln('* caused by the usage of a table is '+ smaxerror + '°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 + ' °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