Измеряем температуру без АЦП

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

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

chwta9nms_39fzt78e6_l-wycdy.png

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

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


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

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

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

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


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

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

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


Итого

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


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

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

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


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

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

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

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

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

eccsoaetqbjtcvz6ojz3jlz1zms.jpeg

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

c7y3ns7we3o5pf045afiakvgghk.gif

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

_iziaali6hyixhtbs5uct9timg0.jpeg

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

s88pcl_q7bqqjwdrjphdueytpkg.gif

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

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


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

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

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


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

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

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

b1z96xazfyog6eysemkmw2p1eiy.jpeg

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

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

uao-hq24yejlta8ehhsgrwn9btu.gif

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

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

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


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

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

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


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

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

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

ikpfhqrpv8hcf8gpmqcc0fxrt3i.gif

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

ewzjki1p_tggqh2pe-8kawptye8.gif

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

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


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

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

rh-mzvg5_zxsto57i875fvzjfe0.jpeg


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


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

fv0f7we296jhllycrqerwtrusny.gif

Повторим предыдущие (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. В предложенную схему довольно просто добавить гальваническую развязку и значительно повысить помехоустойчивость и безопасность.


Итог

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

© Habrahabr.ru