Терморезистор (или термистор) — это такой резистор, который меняет свое электрическое сопротивление в зависимости от температуры.
Существует два вида термисторов: PTC — с положительным температурным коэффициентом, и NTC — с отрицательным. Положительный коэффициент означает, что с повышением температуры сопротивление термистора растёт. NTC-термистор ведет себя противоположным способом.
Также термисторы отличаются номинальным сопротивлением, которое соответствует комнатной температуре — 25 C°. Например, популярными являются термисторы с номиналом 100 кОм и 10 кОм. Такие термисторы часто используют в 3D-принтерах.
В этом уроке мы будет использовать термистор NTC 100K в стеклянном корпусе. Вот такой:
Список необходимых компонентов
Для выполнения всех экспериментов в данном уроке, кроме самого термистора, потребуются: Ардуино-совместимый контроллер, макетная плата, резисторы и немного проводов вилка-вилка. Необходимые компоненты можно добавить в корзину прямо здесь, и затем оформить заказ в нашем интернет-магазине.
Подключение термистора к Ардуино
Чтобы измерить сопротивление термистора, подключим его в качестве нижнего плеча делителя напряжения. Среднюю же точку делителя подключим к аналоговому входу Ардуино — A0. Подобный способ использовался в уроке про фоторезистор.
Подробно об аналоговых входах Ардуино мы говорили на уроке: Аналого-цифровые преобразования — АЦП
Принципиальная схема
Внешний вид макета
Какое сопротивление должен иметь резистор в верхнем плече делителя? Как правило, используют резистор с сопротивлением, совпадающим по порядку с номиналом термистора. В нашем уроке мы используем резистор на R1 = 102 кОм, его легко получить последовательным соединением двух резисторов на 51 кОм.
Программа для вычисления сопротивления термистора
Первая программа, которую мы напишем, будет вычислять сопротивление термистора в Омах.
#define SERIAL_R 102000 // сопротивление последовательного резистора, 102 кОм
const byte tempPin = A0;
void setup() {
Serial.begin( 9600 );
pinMode( tempPin, INPUT );
}
void loop() {
int t = analogRead( tempPin );
float tr = 1023.0 / t - 1;
tr = SERIAL_R / tr;
Serial.println(tr);
delay(100);
}
Результат работы программы:
Можно заметить, что измеренное сопротивление термистора меньше 100 кОм, значит температура окружающей среды ниже 25 C°. Следующий шаг — вычисление температуры в градусах Цельсия.
Программа для вычисления температуры на термисторе
Чтобы вычислить значение температуры используют формулу Стейнхарта — Харта:
Уравнение имеет параметры A,B и C, которые нужно брать из спецификации к датчику. Так как нам не требуется большой точности, можно воспользоваться модифицированным уравнением (B-уравнение):
В этом уравнении неизвестным остается только параметр B, который для NTC термистора равен 3950. Остальные параметры нам уже известны:
- T0 — комнатная температура в Кельвинах, для которой указывается номинал термистора; T0 = 25 + 273.15;
- T — искомая температура, в Кельвинах;
- R — измеренное сопротивление термистора в Омах;
- R0 — номинальное сопротивление термистора в Омах.
Модифицируем программу для Ардуино, добавив расчет температуры:
#define B 3950 // B-коэффициент
#define SERIAL_R 102000 // сопротивление последовательного резистора, 102 кОм
#define THERMISTOR_R 100000 // номинальное сопротивления термистора, 100 кОм
#define NOMINAL_T 25 // номинальная температура (при которой TR = 100 кОм)
const byte tempPin = A0;
void setup() {
Serial.begin( 9600 );
pinMode( tempPin, INPUT );
}
void loop() {
int t = analogRead( tempPin );
float tr = 1023.0 / t - 1;
tr = SERIAL_R / tr;
Serial.print("R=");
Serial.print(tr);
Serial.print(", t=");
float steinhart;
steinhart = tr / THERMISTOR_R; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= B; // 1/B * ln(R/Ro)
steinhart += 1.0 / (NOMINAL_T + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273.15;
Serial.println(steinhart);
delay(100);
}
Результат:
Уже лучше! Программа показывает нам температуру в градусах Цельсия. Как и ожидалось, она немного ниже 25 C°.
Задания
- Термометр с дисплеем. Подключим к схеме символьный ЖК дисплей, и напишем программу, которая каждые 100 миллисекунд будет выводить на него температуру.
- Сигнализация перегрева. Добавим в схему зуммер и напишем программу, которая будет непрерывно вычислять температуру. В программе также должно быть условие: если температура превышает 70 C°, то включаем зуммер.
Термистор + RAMPS 1.4 + Arduino Mega
Последовательный резистор на RAMPS 1.4 уже имеется.
Находится возле пинов подключения термистора Т0, обозначен R7 и не равен сопротивлению моего термистора, а равен всего 4,7 кОм. Соответственно делаем изменения в скетче:
#define SERIAL_R 4700 // сопротивление последовательного резистора
Может кому понадобится для нестандартного применения RAMPS.
В схеме RAMPS указано сопротивление этого последовательного резистора: http://reprap.org/mediawiki/images/f/f6/RAMPS1.4schematic.png
По-моему в приципиальной схеме ошибка. R1 и NTC надо местами поменять?
2+3 это совсем не 3+2 их надо поменять местами!
для рамса 1.4 действительно уже стоит резистор, в данном примере в ардуине уно его нет,.. еще бы я формулу определения сопротивления переделал
float tr = 1023 — t ;
tr = SERIAL_R / tr * t ;
…просто преобразовал формулу заменив одно деление на умножение, не судите строго, новичек, и не проверял, но возможно это повлияет на скорость вычисления))))
А как округлить температуру выходящию с термистора ???
round()
Что за чушь здесь? При сопротивлении термистора 100 ком и сопротивлении постоянного резистора 102 ком в делителе падение напряжения на вход АЦП составит около 2,5 вольт. При опорном 5 вольт это примерно 512 в результатах ацп. Как у вас получилось на выходе 107 килоом по этой формуле: float tr = 1023.0 / t — 1; tr = SERIAL_R / tr; ?????? Если float tr=1023/512=2 (округляю, не суть), то tr = 102000/2=51000!!!!!!!!!!!! а не около 100000, как у вас на скрине в результате
Внимательнее почитайте текст.
1023/512 — 1 = 1
tr = 102000/1 = 102000
Всего вам доброго!
При измерении температуры и включении/выключении тена возникают скачки в измерении температуры в 15-40 градусов.
Для поддержания температуры необходимо применить пропорциональное управление или лучше полный PID регулятор.
Пид регулятор чего? Пропорциональное управление это что? Можно ли как то расширить ответ т.к. есть проблема которая возникает при реализации инструкций из статьи, при этом в статье ничего не говорится о таких проблемах.
RC цепочку поставить на выход резисторного делителя перед подключенем в ногу Arduino было бы хорошим тоном. Дополнительно (если сами делаете плату) правильная разводка поможет защититься от подобных помех.
А как терморезистор в FLProg нарисовать?
#define B 3950 — целое число.
steinhart /= B; // 1/B * ln(R/Ro) — только что отбросили дробную часть.
измерения получились дискретные о чем свидетельствуют повторяющиеся значения даже после скачка.
(float) steinhart /= B; // 1/B * ln(R/Ro), или же
#define B 3950.0
когда разница между сопротивлениями не большая, то дискретность не значительная,
но чем меньше будет ln(R/Ro) — тем неточность вычислений будет больше.
Собрал данную схему по своим номиналам:
#define B 3988 // B-коэффициент
#define SERIAL_R 10000 // сопротивление последовательного резистора, 10 кОм
#define THERMISTOR_R 10000 // номинальное сопротивления термистора, 10 кОм
#define NOMINAL_T 25 // номинальная температура (при которой TR = 10 кОм)
В коде была ошибка, при нагревании температура уменьшалась )
заменил и заработало:
что заменил:
steinhart = tr / THERMISTOR_R; // (R/Ro)
на что:
steinhart = THERMISTOR_R/tr; // (Ro/R)
R=8944.44, t=22.53
R=8979.59, t=22.62