Измерение температуры с помощью NTC термистора

В начале августа я запустил собранный из подручного материала солнечный водонагреватель и потребовалось к нему собрать простенькое термореле, чтобы циркуляционный насос включался только тогда, когда температура солнечной панели (а это, к слову сказать, старый плоский радиатор отопления, утепленный снизу и покрашенный в черный и накрытый стеклом сверху) достигнет, скажем 40 градусов.

Поскольку у меня валялось несколько этих самых термисторов от отслуживших свое китайских термометров, то сразу подумал, почему бы их не использовать…
Поиски по интернету слегка охладили мой пыл, потому что теории, конечно, было много, а вот конкретной реализации гораздо меньше…


Картинка из вики насчет терморезистора и его характеристики.

После упорных поисков результат был достигнут в виде исходника. Мне из него потребовалась только формула расчета сопротивления термистора и вычисления температуры. Здесь же были приведены коэффициенты на конкретную модель термистора. В принципе, к моей задаче эти коэффициенты подошли с приемлемой точностью.
Если вам известна модель термистора, то коэффициенты нужно подставить из даташита или рассчитать по аппноуту из вложения.

Код:
/*************************************************************************
* getTempF - return the temp in Farenheight from 
*            Vishay thermistor NTCLE100E3103JB0
* v10bit - 10 bit value read from the A/D
* pdRes - value (in ohms) of the resistor that is in series with thermistor
*************************************************************************/
double getTempF(double v10bit, double pdRes)
{
	if (v10bit == 1024)
		return -1;

	double thermResistance = pdRes*(1024/v10bit-1);
	//return thermResistance;

	double thermRefResistance = 50000.0; // это сопротивление термистора при 25 градусов

	// Steinhart and Hart constants for Vishay thermistor NTCLE100E3103JB0
	double a = 3.354016 * pow(10, -3);
	double b = 2.56985 * pow(10, -4);
	double c = 2.620131 * pow(10, -6);
	double d = 6.383091 * pow(10, -8);

	//return v10bit;

	double celcius = 1.0/(a + b * log(thermResistance/thermRefResistance)
				+ c * pow(log(thermResistance/thermRefResistance), 2) 
				+ d * pow(log(thermResistance/thermRefResistance), 3)) - 273.15;
	//double farenheit = 9.0/5.0 * celcius + 32.0;

	return celcius;
}


Подключается термистор по такой схеме:

Преимущество этой схемы в том, что для точного измерения сопротивления достаточно знать сопротивление резистора, а напряжение питания стабилизировать не нужно.
Недостаток — саморазогрев. Но в моем случае это не критично.

Проверял я все это дело по такому принципу: подключил к одному микроконтроллеру датчик DS18B20 и термистор, а потом соединил их через термопасту. Расхождение при комнатной температуре получилось около пол-градуса, при 60-70 — около двух градусов. Но это не термостатировано, то есть, может быть, разница в корпусах увеличила расхождение.

Для особо желающих, во вложение добавил аппноут по расчету коэффициентов Стеинхарда-Хайта для произвольного термистора.
  • +2
  • 11 августа 2013, 21:57
  • antonluba
  • 1
Файлы в топике: NTC.zip

Комментарии (47)

RSS свернуть / развернуть
Преимущество этой схемы в том, что для точного измерения сопротивления достаточно знать сопротивление резистора, а напряжение питания стабилизировать не нужно.
странное предложение
если у тебя будет нестабильное напряжение, то и на ацп у тебя будет колебаться независимо от температуры, а саморазогрев тут никаким боком

сколько у тебя заняла готовая прошивка с этими запятыми и почему нужно было ставить терморезистор вместо цифрового?
насколько хорош этот солнечный коллектор?
0
странное предложение
В качестве опорного — напряжение питания, на входе — напряжение, образованное делителем, допустим, будет один к одному = 1/2 от напряжения питания. Код получаем при 10-битном АЦП ==512. Увеличится напряжение, код увеличится или уменьшится? делитель то тот же.
сколько у тебя заняла готовая прошивка
Там еще DS18B20, USART и LCD HD44780. Не помню, но в Мегу16 влезла.
почему нужно было ставить терморезистор вместо цифрового?
Просто так, поиграться
насколько хорош этот солнечный коллектор?
Не очень. Бачок литров 50 если не расходовать к вечеру примерно до 60 нагреет в жаркий день. Мы расходуем, максимум видел 48 градусов, обычно в течение дня около 40 держится.
0
соглашусь что стабилизировать не нужно. однако нужно поставить хотя бы LC фильтр, потому что времена, когда производится замер и и когда производится оцифровка — различаются, и если имеем высокочастотный шум по питанию АЦП — получим соответствующий результат
+1
сколько у тебя заняла готовая прошивка
Посмотрел:
Program: 8650 bytes (52.8% Full)
(.text + .data + .bootloader)

Data: 159 bytes (15.5% Full)
(.data + .bss + .noinit)
0
3.354016 * pow(10, -3)
оригинально

не проще было сразу взять какой-нибудь линейный датчик?
у термисторов еще и разброс огромный, придется калибровать каждый.
+1
не проще было сразу взять какой-нибудь линейный датчик?
Я пользовался LM335 до этого. Кажется, самый простой вариант.
у термисторов еще и разброс огромный, придется калибровать каждый.
Я пробовал калибровать, но нужно термостатировать и диапазон брать широкий, у меня нормально не получилось, точность все равно хуже.
0
оригинально
Ещё оригинальнее было бы
atof(«0.003354016»);
+1
Вы сказали, что точность Вас не напрягает, и что 1-2 градуса роли не играют. Поэтому возникает вопрос — а зачем так сложно?

Табличный вариант перевода ADC-значений в градусы Вы не рассматривали?

При таком подходе можно будет отказаться от ресурсоёмких библиотек с плавучкой. Тем более, что Вы используете еще и функции log и pow. Следовательно уменьшаться требования к размеру стека (RAM) и размеру кода (flash). Кроме того, функция перевода попугаев в градусы будет выполняться быстрее.

Мне кажется, для Вашего случая длина таблицы должна быть всего несколько десятков строк, а это значит, что для нее потребуется менее килобайта флеша.
+2
Да, если тип термистора известен, то так лучше, конечно. В даташите вся таблица есть.
0
публиковал пример с таблицей все несколько проще и таблички R/t легче ищутся чем коэффиценты
0
Я так понимаю, что для нахождения коэффициентов достаточно трех точек, а вот чтобы таблицу построить, точек нужно побольше и во всем диапазоне.
Хотя как вариант, сделать три точки, получить формулу, а потом рассчитать полную таблицу.
В любом случае, нужна высокая точность измерения при калибровке.
+1
Дело в том что как правило все публикуют таблицы для NTC и ничего считать не надо
0
Да и еще кое что обычно подтяжку используют а NTC ставят на землю
0
Да и еще кое что обычно подтяжку используют а NTC ставят на землю
И как сопротивление измерять в этом случае?
0
фактически также — просто делитель работает в другую сторону
0
Какое сопротивление резистора подтяжки и можно ли его измерять?
0
переверните вашу схему и все
0
Перевернуть мою схему это одно, а использовать подтяжку — это другое.
0
Я говорил о подтяжке с точки зрения расположения элементов -думал будет понятнее, но угадал :)
0
не угадал в смысле
0
Ага, ну теперь понятно, а то я уж бросился даташит листать, думаю, не пропустил ли чего ;)
0
кстати, подтяжка бывает и вниз…
0
pullup and pulldown

ps pullover 8)
0
Есть ли принципиальная разница?
0
полагаю в помехозащищенности и удобстве разводки
0

ps это мое 667 сообщение, предыдущее было сами знаете :)
0
Из какого документа эта картинка?
0
Насколько я помню, это схема аналоговых входов какого-то ПЛК. Она тут уже всплывала когда-то.
0
я же ее и постил это из контроллера Trend
0
На что намекает нам эта картинка? Что она должна символизировать, о чём сказать?
0
сказать она должна о примерной структуре входа с NTC- если ничего не говортит я не виноват
1.По поводу разводки- что проще подвести к терминалам — одну землю или кучу опор?
2.По поводу помех, как правило на плате контроллера земля выполнена более толстыми проводниками или полигонами.

зы все это не имеет особого значения в любительских кострукциях с 1-2 входам
0
 Приведенная вами схема показывает, как устроен универсальный вход в неком контроллере. Универсальный, на четыре варианта, а не только для терморезистора.
 Зачем же подводить «кучу опор»? Сами выдвинули ложное утверждение и сами его опровергаете. Для подключения внешнего терморезистора минимально достаточно двух выводов, а в приведенной вами схеме на терминалы выведена одна опора (24 В) и «куча» земель, и только словесно пояснено, куда нужно подключать термистор и остальные три варианта.
 Приведенная картинка неудачно иллюстрирует простоту подключения термистора к земле, скорее, говорит об обратном.
0
Ну то что вам мои фломастеры не подошли — на вкус и цвет… считайте картинка была для расширения кругозора — не нравится делайте подругому.
Про кучу опор я говорил в плане того, что проще иметь землю и измерительную точку на клеммник (а уж если вход универсальный то других вариантов фактически нет), почему писал выше и оговорился специально, что для дома для семьи пофиг — читайте внимательно.
0
полагаю в помехозащищенности и удобстве разводки
 Помехозащищённость? Допускаю, но никто не мешает удалённый терморезистор, подключенный к плюсу питания, заэкранировать от того же плюса питания. Или там плохой источник питания? Или что вы имели в виду под «помехозащищённостью»?
 Удобство разводки? Слишком конкретный вопрос, чтобы обсуждать его посредством телепатического прозрения.
0
Помехозащищенность здесь никоим боком. Не надо списывать со счетов резистор подтяжки. Или через него помеха не идет? Второе: Хороший кондерчик исправит ситуацию, поскольку температура — процесс длительный… еще можно программное округление. У меня тоже табличный метод использован. Делал как то программку по постоению таблицы в зависимости от параметров самого терморезистора и резистора подтяжки. Таблицей куда более удобно.
0
Делайте как нравится.

зы наверное производители контроллеров не полные мудаки да?
0
а кто спорит? микруха нужна, например, для прямого подключения к компу, если там интерфейс уарт… или если у проца нет ADC, или просто лень с таблицами возиться. А там вроде как прецизионные микрухи, проверенные, есть большой смысл доверять их показаниям.
0
Очень хорошо.
Раньше я не знал об аппроксимации Штайнхарта — Харта, теперь я могу по таблице найти коэффициенты и наоборот, по коэффициентам построить таблицу, а использовать любой из двух подходов, какой окажется удобнее.
+1
  • avatar
  • EW1UA
  • 12 августа 2013, 11:59
Коллега, за отсылку на модель Стеинхарда-Хайта (Steinhart–Hart equation) Вам однозначно плюс (хоть я бы использовал менее ресурсоемкие методы линеаризации типа таблицы или аппроксимации). Но вот код, который Вы выложили в качестве примера — очень «не фонтан». Очень очень… Выше уже говорили о конструкциях типа
double a = 3.354016 * pow(10, -3);

Но это только одна из немногих проблем. Там много проблем, начиная с декларации функции: почему double v10bit если v10bit — это 10ти битное значение с АЦП. И если это уж действительно 10ти битное значение, то к чему проверка if (v10bit == 1024) и т. д.

Я так понимаю, Вы просто взяли за основу код из этого или подробного проекта. Но помимо очень неудачной реализации (которую Вы взяли за основу) есть еще несколько сомнительных (ИМХО) моментов (которые я замерил только в Вашей реализации).

Я не понял, как Вы получили формулу

double thermResistance = pdRes*(1024/v10bit-1);


но (даже если она работает) при v10bit == 0 мы получим «деление на 0». А получить это просто, при обрыве провода к терморезистору, R1 подтянет уровень именно к 0.

Не сочтите за критику(я понимаю, что автор кода не Вы) и извиняюсь за занудство :)
0
  • avatar
  • e_mc2
  • 13 августа 2013, 00:26
Это код почти целиком из интернета, просто я ссылку сходу не нашел. Код действительно вообще не оптимизирован, я просто хотел быстро получить результат и я его получил.
Единственное, что я изменил, это как раз
double thermResistance = pdRes*(1024/v10bit-1);

Там было что-то длинное и неудобочитаемое, к тому же работало неправильно, хотя по схеме и фотографиям на сайте автора все должно было работать. Опять же, я не задавался целью оптимизировать и исключить ошибки, нужно было просто проверить работоспособность, что и было достигнуто.
Спасибо.
0
Нашел ссылку, вот она.
0
Я не понял, как Вы получили формулу
Выразил R1 из формул, представленных, например, в вики.
0
Вы правы. Я ошибся, и вывел формулу для случая, когда Rt внизу делителя, и получил
thermResistance = (pdRes * v10bit / 1024.0)/(1.0 — (v10bit/1024.0));
0
Видимо, по ссылке как раз такая формула, а ошибка в схеме. В этом случае деления на 0 не будет, а термистор нужно вниз переставить.
0
На тему измерения температуры с помощью NTC термистора есть очень полезная страничка.
aterlux.ru/index.php?page=article&art=ntcresistor
0
Когда-то давно решал похожую задачу (кто-то в ФИДО «конкурс» устроил).
Правда сводилась она не столько к измерению, сколько к термостатированию.
Табличка была захардкожена во флеше, шаг в 5 градусов (epcos даёт такие таблицы к своим NTC).
Чтобы получить точность в 1 градус я брал измеренное сопротивление, искал две ближайшие точки (которые с шагом в 5 градусов). Если точно попал в точку, то ок, если нет, то определял дельту == (сопротивление — ближайшая точка...) и эту дельту умножал на тангенс (== дельта температуры / дельта сопротивления), результат прибавлял к ближайшей температура.
В свете того, что на attiny15 с математикой тяжко, делал хитрость — решал задачу «графически», брал алгоритм Брезенхема и по паре точек искал самую подходящую между ними (если Брезенхемом рисуют прямые на экране с помощью сложения и вычитания, то почему бы не использовать его и в микроконтроллере?).
Страничка здесь: Страх-ужас-хардкор
Собственно исходники: zip
Весть алгоритм преобразования — один экран ассемблера.
См. функцию ConvertT в файле Thermostat2.asm в zip-е.
0
aterlux.ru/article/ntcresistor
Нашёл тему поиском. опечалился.
На всякий случай если вдруг наткнусь снова ссылочка с теорией
http://aterlux.ru/article/ntcresistor
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.