Ker bom imel pri avtomatizaciji bajte vsaj 20 novih merilnih točk in ker bo pri nekaterih nevarnost odpovedi zaradi strele, sem nabavil [url=httpunichr("58")//wwwunichr("46")ebayunichr("46")counichr("46")uk/itm/50pcs-10k-OHM-Thermistor-Resistor-NTC-MF52-103-3435-10K-3435-1-/290767819319?ssPageName=ADMEunichr("58")Lunichr("58")PMRunichr("58")GBunichr("58")1123]50 termistorjev[/url]. Pri DS18B20 imaš ful sitnosti, ko ti zaradi strele pregorijo, saj moraš novemu prebrati ID in ga dodati v SW. Vprašanje kaj bo čez 5 ali 10 let, ali bom imel pri roki potrebno opremo.
Moje izkušne z NTC:
Tabela na strani prodajalca je polna napak, celo tabela proizvajalca - verjetno drugega, ima napako in je še drugačna, posebno na nizkih temperaturah, čeprav gre za isti B.
Formula za izračun temperature s pomočjo B je dobra za pozitivne temperature, bolj kot greš pod ničlo hujša je napaka.
Nekako sem sestavil tabelo od -40 do 130°C na 5°C. Deloma iz formula s pomočjo B-ja, deloma iz podatkov prodajalca (glej link), deloma po lastnih meritvah. Ko sem določil tabelo je program za linearno interpolacijo simpel. Na Arduinu Leonardo sem naredil še povprečenje 6 AD vhodov (teče v ozadju pod interaptom) v trajanju 780ms (prvi možni n * 20ms) in dobil izredno stabilne rezultate, tako da mi na koncu ni žal, je šlo pa odločno preveč časa.
6 vhodov lahko multipleksiram, recimo X 4 in imam 24 vhodov z rezultati vsake dobre 3s. Pri takem načinu merjenja je celo koristno, da je v signalu nekaj motenj, saj se s tem da dobiti precej večjo ločljivost od ločljivosti AD-ja, to pa je pri opazovanju temperature pogosto fajn, saj veliko lažje oceniš trend.
Koda:
//Na Leonardu bere A0 do A5, jih povpreči v časovnem oknu 780ms, kar je 39 period 50Hz
//oziroma 1250 skenov AD-ja na enem kanaluunichr("46") Konec konverzije proži prekinitev, v kateri se zamenja kanal in še kaj drugega postoriunichr("46")
//dolžina prekinitev vsakih 104us (kolikor traja ena konverzija) je od 7 do 15,4us, vsakih 780ms pa še nekaj več
//v povprečju manj kot 10% CPUja
//na prvih dveh portih sta NTC-ja, program iz tabele izračuna temperaturo in jo izpiše na Serial
//bere do 7 DS1820 na portu 7
#include <OneWireunichr("46")h>
#include <DallasTemperatureunichr("46")h>
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 7
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
byte NSenzorjev;
// Pass our oneWire reference to Dallas Temperatureunichr("46")
DallasTemperature sensors(&oneWire);
const byte adcPin = 0;
const byte AnRef= 64; //64 5V ref 192 interna 2,5V ref
long adcReadTempunichr("91")unichr("93")={0,0,0,0,0,0};
long adcReadingunichr("91")unichr("93")={0,0,0,0,0,0};
//AD readings * 10 for -40unichr("46")unichr("46")unichr("46")130°C
//+5V_8K25_ADIn_NTC_GND
//0 na koncu da se izkoplje iz while zanke v primeru kratkega stika
word NTC_Tableunichr("91")unichr("93")={9805,9702,9566,9381,9161,8903,8606,8270,7896,7487,7048,6584,6101,5605,5108,
4626,4168,3738,3341,2978,2649,2353,2089,1854,1646,1462,1300,1158,1032,922,825,739,663,597,538};
const byte TabLen = sizeof(NTC_Table)/2-1;//-1 da ni treba v while odštevat
//korekcija za 2 priključena NTC-ja
float TempCorunichr("91")unichr("93") = {0, -0unichr("46")3};
volatile boolean adcDone = false;
boolean adcStarted;
long sensorValue = 0;
//Mux tabela za Leonarda
byte AD_Kanaliunichr("91")unichr("93") = {5, 4, 1, 0, 7, 6};//V ADC IRQ rutini najprej postavi Mux na drugo vrednost
byte MuxIndex=0;
word itIndex=0;
int i;
void setup ()
{
// start serial port
Serialunichr("46")begin(19200);
ADMUX = AnRef+AD_Kanaliunichr("91")0unichr("93");
// start the conversion
ADCSRA |= _BV (ADSC) | _BV (ADIE) | 32;
// Start up the library
sensorsunichr("46")begin();
NSenzorjev = sensorsunichr("46")getDeviceCount();
} // end of setup
// ADC complete ISR
ISR (ADC_vect)
{
byte low, high;
low = ADCL;
high = ADCH;
ADMUX = AnRef+AD_Kanaliunichr("91")MuxIndexunichr("93");
adcReadTempunichr("91")MuxIndexunichr("93") = adcReadTempunichr("91")MuxIndexunichr("93")+((high << 8) | low);
MuxIndex++;
if (MuxIndex >5)
{
MuxIndex=0;
itIndex++;
if (itIndex > 1249)
{
adcDone = true;
itIndex = 0;
memcpy(adcReading,adcReadTemp,24);
for (int i=0; i <= 5; i++)
adcReadTempunichr("91")iunichr("93") = 0;
}
}
} // end of ADC_vect
void loop ()
{
// call sensorsunichr("46")requestTemperatures() to issue a global temperature
// request to all devices on the bus
sensorsunichr("46")requestTemperatures(); // Send the command to get temperatures
for (int i=0; i < NSenzorjev; i++){
Serialunichr("46")print("DS18B20_");
Serialunichr("46")print(i+1);
Serialunichr("46")print(" temeperature = ");
Serialunichr("46")print(sensorsunichr("46")getTempCByIndex(i));
Serialunichr("46")print("C ");
}
for (int n=0; n<2; n++){
//ADCx10 je povprečje odčitkov AD-ja pomnoženo z 10 zaradi večje točnosti
word ADCx10 = (adcReadingunichr("91")nunichr("93")+62) / 125;
i = 1;
while((ADCx10 <= NTC_Tableunichr("91")iunichr("93"))&(i<TabLen)){
i++;
}
if (ADCx10 >= NTC_Tableunichr("91")iunichr("93")){
int T = -40+i*5;
Serialunichr("46")print(T-5unichr("46")0*(ADCx10 - NTC_Tableunichr("91")iunichr("93"))/(NTC_Tableunichr("91")i-1unichr("93")-NTC_Tableunichr("91")iunichr("93"))+TempCorunichr("91")nunichr("93"));
Serialunichr("46")print("C ");
}
else{
Serialunichr("46")print("Napaka, odcitek AD-ja ");
Serialunichr("46")print(ADCx10/10);
Serialunichr("46")print(", morda je temperatura >130C ");
}
}
Serialunichr("46")println("");
adcDone = false;
} // end of loop