Стояла как-то задача оснастить одну систему кучей термодатчиков. Причём оснастить максимально недорого.


Результаты изысканий (которые, по-моему, получились довольно изящными) предлагаю к рассмотрению в этой статье.



В данной статье разбираются контактные способы измерения температур в системах с микроконтроллером.


Давайте сперва перечислим некоторые особенности/требования измерений температуры:


Инерционность


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


Каким бы устройством мы ни управляли, будь то система управления холодильником или система, детектирующая перегрев какого-то элемента, скорость измерения температуры вряд ли будет критична. Измеряем температуру за 0.0001 секунды, или за 0.1 секунду, или даже (для многих случаев подойдёт) за 10 секунд — не так уж и важно.


Потребителя скорее будет интересовать точность измерения температуры, нежели скорость.


Помехоустойчивость


Зачастую проводники до термодатчика имеют довольно большую длину. Работающие рядом устройства создают набор помех/наводок. Требуется максимально нивелировать влияние помех
на точность измерений.


Если учитывать предыдущую особенность (инерционность), то тут проблем обычно больших нет: в цепи измерения включают сильное интеграционное звено (например, конденсатор), которое нивелирует влияние помех.


Итого


Задачу нам надо решить:


  • с минимальной стоимостью (требование)
  • с мягкими требованиями к скорости измерений
  • с максимальной помехоустойчивостью

Последние два пункта частично снимают (а не накладывают) ограничения на выбранные способы решения.


Например, не требуется скоростной АЦП.


Традиционные способы измерения


В рамках данной статьи рассмотрим способы измерения, где в качестве датчика используется термосопротивление.


Датчик нагревается, его сопротивление увеличивается (или уменьшается).


Как можно измерить сопротивление термодатчика с помощью микроконтроллера?


Подключить его к прецизионному источнику тока и измерить полученное напряжение при помощи АЦП:



Вычислить сопротивление терморезистора можно по формуле:



Либо подключить его к прецизионному источнику напряжения с использованием дополнительного эталонного резистора и так же измерить полученное напряжение при помощи АЦП:



Вычислить сопротивление терморезистора можно по формуле:



Второй способ — наверное, самое дешёвое решение при наличии АЦП.
Да, формула получилась нелинейной. Учитывая то, что скорость измерений нас не сильно
волнует, скорость вычисления формул — тоже.


Какие тут недостатки?


  1. Из-за нелинейности во втором случае и начального сопротивления в обоих, диапазон измерения АЦП будет неполным. Измеряемый диапазон напряжений будет меньше диапазона АЦП. Вероятнее всего, в разы. То есть, 10 разрядный АЦП даст точность в 9 или 8 разрядов, а вычисления ещё больше её уменьшат.
  2. Требуется "дорогой" АЦП, который в случае множества термодатчиков надо переключать
    между ними. То есть, ещё и дорогой аналоговый мультиплексор.
  3. Требуется прецизионный источник тока или напряжения.

Вопросы нелинейности и неполноты диапазона можно порешать, добавив в игру операционный усилитель и резисторный мост. Рассмотрение такой системы выходит за рамки данной статьи.


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


Рефлексируем


Предположим, что у нас нет в наличии прецизионного источника тока/напряжения. Можем ли мы как-то измерить сопротивление термодатчика с приемлемой точностью?


Можем. Например, сравнивая сопротивление датчика с сопротивлением, заранее известным.
Берём один источник тока и переключаем между двумя сопротивлениями, эталонным и измеряемым:



Переключатель на схеме нарисован механическим для упрощения. Схема приведена для иллюстрации принципа действия.


Итоговое сопротивление можно вычислить примерно так:



От одной прецизионности избавились, несколько нагрузив CPU математическими вычислениями.


Тут пока мы имеем удорожание (вместо одного АЦП требуется пара), но зато у нас получился новый метод измерения, основанный на сравнении с эталоном.


Сравнение с эталоном позволяет нам отказаться от прецизионности источника тока (напряжения), заменив её прецизионностью эталонного сопротивления.


Откажемся от АЦП


Если у нас нет АЦП, какие варианты измерения сопротивления можно придумать?


Мы можем, например:


  1. Собрать RC-генератор с использованием нашего термосопротивления и измерить частоту выдаваемых им колебаний.
  2. Зарядить эталонный конденсатор C через наше термосопротивление и измерить время заряда.

Пока оставим за кадром реализацию обоих способов, сразу попытаемся указать на недостатки:


Недостаток: Для точного измерения требуется точное знание ёмкости конденсатора,
который будет использован в этой системе.



Как можно избавиться от точного знания ёмкости конденсатора? Так же, как в предыдущем случае мы избавлялись от необходимости иметь прецизионный источник опорного тока (напряжения): вместо одного измерения будем делать два и сравнивать с эталонным резистором.



Осталось выбрать, каким путём идти: первым или вторым?


Очевидно, что вторая дорога в микроконтроллерном применении более проста в реализации:


  1. В среднем современном микроконтроллере есть входы с уровнями (триггером) Шмитта (но даже если и нет, то система будет работать и без них).
  2. В среднем современном микроконтроллере есть система, с помощью которой можно измерить интервал времени между событиями (таймер).

Итого, у меня получилась примерно такая схема измерительной части (Вход Шмитта и выходы логических элементов с 3 состояниями — это входы/выходы микроконтроллера):



Алгоритм измерения


  1. Начальное состояние: конденсатор разряжен, все выходы (PORT1-PORTx, PORTe) с Z состоянием выдают логический ноль.
  2. Переводим все выходы в состояние Z.
  3. Переводим выход PORTe в состояние логической единицы, начав одновременно с этим отсчёт времени (заряжаем конденсатор через эталонный резистор).
  4. Когда конденсатор зарядится до порогового уровня, сработает прерывание.
    В обработчике прерывания запомним, сколько тактов таймера занял заряд конденсатора через эталонный резистор — число Ne.
  5. Разрядим конденсатор снова, включив все выходы в состояние логического нуля.
  6. Далее зарядим конденсатор через первый термодатчик — получим измерение Nt1.
  7. Вычислим сопротивление терморезистора исходя из формулы:


Повторим предыдущие (5, 6 и 7) пункты для всех остальных термодатчиков.


Итого


Для измерений N температур нам требуется:


  1. N + 1 выходов с тремя состояниями (полно в любом микроконтроллере).
  2. Один вход прерывания с уровнями Шмитта (требование уровней Шмитта нестрогое, но они есть сейчас в среднем CPU, почему бы не использовать).
  3. Один эталонный резистор.
  4. Конденсатор.

Критерий выбора ёмкости конденсатора.


В общем и целом — чем больше, тем лучше (тем большую точность измерений можно получить).


Конденсатор тут является и средством сглаживания помех (интегрирующее звено), и участником измерений.


Я использовал танталовый конденсатор 100мкф. Но в целом можно строить измерения на любых конденсаторах в диапазоне 0.1 мкФ — 1000 мкФ. С маленьким конденсатором при том же сопротивлении скорость измерения будет выше, но и тактовая частота таймера нужна выше (чтобы получить достаточную точность измерений).


При конденсаторе 100мкФ, при измеряемых сопротивлениях 3-30кОм у меня получились 12-24 разрядные числа отсчётов измерений (использовался 8-битный аппаратный таймер контроллера AVR и ещё 16-битный счётчик переполнений).


Суммарно при таких параметрах получается выполнять 2-5 измерений в секунду. На опрос 16 термодатчиков требуется несколько секунд.


Примечания


  1. Можно проводить измерения и на заряде, и на разряде конденсатора. Это увеличит скорость измерений вдвое. Но надо и эталон обмерять в обоих направлениях.
  2. Если системе требуется много термодатчиков, то разряжать конденсатор можно через все датчики сразу. Это ускорит подготовку нового измерения (я использовал этот вариант).
  3. Если в систему внести этап "подстройки", то эталонный резистор может быть не прецизионным: берём любой резистор (главное, чтобы у него не было температурной зависимости), затем вводим программную коррекцию погрешности.
  4. Вычисления лучше всего проводить не в обработчике прерываний, а в фоне. То есть в результате работы системы измерений получаем пары чисел Ne-Nt. Фоновая программа, уже делая умножение/деление, приводит их к омам сопротивления или прямо к градусам.
  5. В предложенную схему довольно просто добавить гальваническую развязку и значительно повысить помехоустойчивость и безопасность.

Итог


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