Измерение температуры при помощи NTC термистора и микроконтроллера AVR
Характеристика NTC термистора
Вычисление температуры Схемы подключения Подключение термистора Подключение к АЦП микроконтроллера ATmega Расчёт таблицы значений Пример использования Автор: Погребняк Дмитрий Самара, 2013. Click here to read this article in English. Одним из вариантов для измерения температуры является использование термисторов. Среди преимуществ термистора можно выделить большое значение температурного коэффициента, то есть значительное изменение сопротивления в зависимости от температуры (порядка 2-10% на Кельвин). Термисторы бывают двух типов: с положительным температурным коэффициентом (PTC, Positive Temperature Coefficient), то есть увеличивающие своё сопротивление с увеличением температуры, и с отрицательным (NTC, Negative Temperature Coefficient) – уменьшающие сопротивление с возрастанием температуры. Речь в данной статье пойдёт про вторые, и про их использования для измерения температуры в сочетании с микроконтроллерами AVR Характеристика NTC термистораТермисторы характеризуются рядом параметров, такими, как максимальный допустимый ток, точность, сопротивление при определённой температуре (как правило, при 25°С). Одним из параметров, характеризующим степень изменения сопротивления в зависимости от температуры является коэффициент температурной чувствительности, обозначаемый B. Этот коэффициент рассчитывается на основе значений сопротивления при двух конкретных значениях температур. Во многих случаях этими температурами выбираются 25°С и 100°С. Обычно температуры, использованные при вычислении коэффициента указываются после буквы, например B25/100. Коэффициент B измеряется в Кельвинах и вычисляется по следующей формуле: где R1 и R2 - значения сопротивлений при температурах соответственно T1 и T2, выраженных в Кельвинах. Из этой формулы следуют и обратные: Вычисление температурыТермисторы обладают высокой степенью нелинейности параметров, и термисторы различных моделей, даже при одинаковых значениях параметра B25/100 могут по разному изменять сопротивление в зависимости от температуры. Поэтому формула [3] может лишь приблизительно оценить температуру. Кроме того, такая формула подразумевает сложные вычисления, которые требуют много процессорного времени, что часто является неприемлемым. Более простым и эффективным подходом является хранение таблицы, в которую заносятся предварительно рассчитанные значения, возвращаемые АЦП при тех, или иных температурах. Для экономии памяти можно хранить значения только для некоторых точек, искать их в таблице двоичным поиском, а промежуточные значения получать линейной интерполяцией. Для измерений температуры окружающего воздуха с точностью до 0.3°C, достаточно хранить значения с шагом 5°C. Если значения лежат в пределах 16 бит (и занимают 2 байта), то для хранения такой таблицы для диапазона измеряемых температур от -30 до 70 градусов потребуется всего 40 байт. Точность измерений можно повысить, уменьшив шаг таблицы. Так при шаге 2°C можно добиться точности до 0.1°C на широком диапазоне измерений. Производители термисторов, как правило, приводят таблицы показывающие изменение сопротивления в зависимости от температур. Значения в этих таблицах также привязаны к сетке температур с некоторым шагом (например, 5°C). Используя формулы [1] и [2] можно с достаточной точностью интерполировать табличные значения. Схемы подключенияПодключение термистора
Наиболее простым вариантом подключения является схема A. При выборе номинала резистора RA примерно равным сопротивлению термистора в районе измеряемых температур, значения U будут изменяться ближе к линейным, что обеспечит большую точность при интерполяции табличных значений. Выбирая номиналы RA и термистора, следует учесть, что протекающий через термистор ток вызывает его нагрев и, как следствие, искажение показаний. Желательно чтобы мощность на термисторе не превышала 1 мВт. А значит, при напряжении U0 = 5В, RA должен быть как минимум, 10 килоОм. Сопротивление термистора в измеряемом диапазоне должно иметь примерно тот же порядок. Схема B призвана ограничить мощность, рассеиваемую на термисторе. Схемы C и D являются обратными к A и B. Их имеет смысл использовать, если требуется измерять низкие температуры, когда референтное значение АЦП (Uref) ниже U0. Подключение к АЦП микроконтроллера ATmega
У контроллеров ATmega для снижения шумов используется отдельная линия питания для модуля АЦП. Инструкция рекомендует подключать эти входы через фильтр: индуктивность L = 10мкГн, и конденсатор C2 = 0,1мкФ. Микроконтроллер может использовать либо внешнее референтное напряжение для АЦП, либо внутреннее (2,56В или 1,1В), либо, в качестве такового, использовать напряжение питания АЦП: AVCC. При использовании внешнего напряжения, оно должно быть подано на вход AREF. При использовании AVCC, или внутреннего напряжения 2,56В, между этим входом и землёй должен быть размещён конденсатор (на схеме C1). Инструкция не даёт чёткого указания для выбора ёмкости конденсатора, рекомендую использовать керамический конденсатор 0,1мкФ и более. Для снижения измеряемых шумов, рекомендую термистор также подключать к фильтрованному напряжению параллельно AVCC, и настроить на использование этого напряжения в качестве референтного. Дополнительно, для подавления шумов возникающих на линиях, можно установить конденсатор C3 в диапазоне 1-100нФ. Следует учесть, что помимо модуля АЦП, вход AVCC запитывает также некоторые из портов ввода/вывода (как правило, на тех же выводах, что используются для АЦП). Использование этих портов на вывод и подключение к ним нагрузки может создать дополнительные шумы в работе АЦП. Чтобы нивелировать шумы, возникающие на АЦП, рекомендую провести замеры несколько раз подряд и просуммировать полученные значения. В микроконтроллерах ATmega АЦП – 10-разрядный. Просуммировав результаты 64 подряд идущих измерений, результат остаётся в пределах 16-битного беззнакового целого, что не потребует дополнительной памяти для сохранения таблицы значений. При большем числе измерений также можно оставаться в пределах 16 бит, соответствующим образом сдвигая или деля результат. Расчёт таблицы значенийВашему вниманию предлагаю скрипт для онлайн расчёта таблицы значений АЦП. Расчёт значений ведётся либо по двум значениям температур и сопротивлений, либо вводится списком, либо используется одна из предзагруженных R/T характеристик. В настоящее время загружены R/T характеристики термисторов фирмы Siemens/EPCOS. Выберите подходящую из списка. Загруженные характеристики даны с шагом 5°С, при выборе меньшего шага сетки, значения получаются путём интерполяции по формулам [1] и [2] двух ближайших значений из таблицы. При построении таблицы автоматически соответствующим образом обновляется пример исходного кода под ней. Внимание! Так как параметры термисторов в значительной мере нелинейны, расчёт по двум значениям сопротивлений, либо по значению и коэффициенту будет очень приблизительным. Вычисленное значение температуры при измерении высоких, или низких температур в таком случае может значительно (на десятки градусов) отличаться от актуальной. Чтобы узнать подходящий тип R/T характеристики для вашего термистора, скачайте документацию, данную заводом изготовителем. Сводная таблица для некоторых моделей термисторов Siemens/Epcos приведена ниже. Нажмите на код R/T характеристики, чтобы подгрузить параметры в форму ниже:
Форма для он-лайн расчёта значений АЦП
Пояснения к таблице: жирным выделены значения R/R1 и R, полученные на основе табличных. Обычным шрифтом обозначены значения полученные интерполяцией или экстраполяцией по формулам. ADC – округлённое значение на выходе АЦП, с учётом множителя. Значения, выходящие за предел измерений АЦП, не отображаются. I,мкА - ток в цепи. P,мВт - мощность, рассеиваемая на термисторе. E – эвристическая оценка возможной погрешности вычисленной температуры, вызванной использованием линейной интерполяции табличных значений, и ограниченной точностью АЦП. Позволяет выбрать параметры и схему включения таким образом, чтобы в области измеряемых значений погрешность была минимальна. Эта оценка не учитывает возможный шум, возникающий на АЦП, а также погрешность, вызванную нагревом термистора из-за протекающих токов. Погрешность можно уменьшить выбрав меньший шаг таблицы, используя АЦП большей разрядности, или путём усреднения большего числа измерений, а также подбором номиналов сопротивлений в цепи. Код, соответствующий таблице #include <avr/io.h> #include <avr/pgmspace.h> // Значение температуры, возвращаемое если сумма результатов АЦП больше первого значения таблицы #define TEMPERATURE_UNDER 0 // Значение температуры, возвращаемое если сумма результатов АЦП меньше последнего значения таблицы #define TEMPERATURE_OVER 0 // Значение температуры соответствующее первому значению таблицы #define TEMPERATURE_TABLE_START 0 // Шаг таблицы #define TEMPERATURE_TABLE_STEP 50 // Тип каждого элемента в таблице, если сумма выходит в пределах 16 бит - uint16_t, иначе - uint32_t typedef uint16_t temperature_table_entry_type; // Тип индекса таблицы. Если в таблице больше 256 элементов, то uint16_t, иначе - uint8_t typedef uint8_t temperature_table_index_type; // Метод доступа к элементу таблицы, должна соответствовать temperature_table_entry_type #define TEMPERATURE_TABLE_READ(i) pgm_read_word(&termo_table[i]) /* Таблица суммарного значения АЦП в зависимости от температуры. От большего значения к меньшему Для построения таблицы использованы следующие парамертры: */ const temperature_table_entry_type termo_table[] PROGMEM = { 0 // Нажмите "Построить таблицу" на форме выше, чтобы заполнить этот массив }; // Функция вычисляет значение температуры в десятых долях градусов Цельсия // в зависимости от суммарного значения АЦП. int16_t calc_temperature(temperature_table_entry_type adcsum) { temperature_table_index_type l = 0; temperature_table_index_type r = (sizeof(termo_table) / sizeof(termo_table[0])) - 1; temperature_table_entry_type thigh = TEMPERATURE_TABLE_READ(r); // Проверка выхода за пределы и граничных значений if (adcsum <= thigh) { #ifdef TEMPERATURE_UNDER if (adcsum < thigh) return TEMPERATURE_UNDER; #endif return TEMPERATURE_TABLE_STEP * r + TEMPERATURE_TABLE_START; } temperature_table_entry_type tlow = TEMPERATURE_TABLE_READ(0); if (adcsum >= tlow) { #ifdef TEMPERATURE_OVER if (adcsum > tlow) return TEMPERATURE_OVER; #endif return TEMPERATURE_TABLE_START; } // Двоичный поиск по таблице while ((r - l) > 1) { temperature_table_index_type m = (l + r) >> 1; temperature_table_entry_type mid = TEMPERATURE_TABLE_READ(m); if (adcsum > mid) { r = m; } else { l = m; } } temperature_table_entry_type vl = TEMPERATURE_TABLE_READ(l); if (adcsum >= vl) { return l * TEMPERATURE_TABLE_STEP + TEMPERATURE_TABLE_START; } temperature_table_entry_type vr = TEMPERATURE_TABLE_READ(r); temperature_table_entry_type vd = vl - vr; int16_t res = TEMPERATURE_TABLE_START + r * TEMPERATURE_TABLE_STEP; if (vd) { // Линейная интерполяция res -= ((TEMPERATURE_TABLE_STEP * (int32_t)(adcsum - vr) + (vd >> 1)) / vd); } return res; } Пример использованияВ примере ниже используется вывод на семисигментный индикатор. Описание работы с индикатором смотрите в другой моей статье.
ADMUX = 0b01000111; // референтное напряжение - Vcc, вход ADC7, реузультат по правому краю ADCSRA = 0b10000111; // 1/128 делитель частоты, включение АЦП while(1) { temperature_table_entry_type summ = 0; for (uint8_t i = 0; i < 64; i++) { ADCSRA |= _BV(ADSC); loop_until_bit_is_clear(ADCSRA, ADSC); summ += ADC; } int16_t t = calc_temperature(summ); ledind_num(t, 1, 0b01010011); // Вывод значения на индикатор с префиксом в виде буквы t _delay_ms(250); } 8 ms; mod: Mon, 11 Jan 2021 09:39:36 GMT; gen: Tue, 26 Nov 2024 12:30:38 GMT |