Двухканальный термометр на PIC16F628

Предлагаемый цифровой термометр построен на базе микроконтроллера PIC16F628. В качестве датчиков температуры используются терморезисторы, индикаторы — светодиодные семисегментные трёхразрядные с общими катодами.

Принцип работы. Для измерения используются встроенные аналоговые компараторы. Пары резисторов R18 с R20 и R19 с R21 образуют делители напряжения, средняя точка которых подключена к отрицательным входам компараторов (AN0, AN1). Конденсаторы C2, C3 служат для подавления помех. Положительные входы компараторов (AN2) подключены к конденсатору C1. К этому же конденсатору через резистор R2 подключен цифровой выход RA3. В процессе измерения программно анализируется выход одного из компараторов (они выбираются поочерёдно), инвертируется и выводится на вывод RA3. Это приводит к тому, что напряжение на конденсаторе C1 стремится установиться равным напряжению на одном из делителей напряжения. При этом подсчитывается, сколько времени на вывод RA3 выдавался уровень логической «1» (T1) и сколько — уровень логического «0» (T0). Отношение T0/T1 равно отношению сопротивлений резисторов R18/R20 или R19/R21, и почти не зависит от других факторов (напряжение питания, тактовая частота, ёмкость конденсаторов C1-C3 и т. п.).

Затем температура терморезистора вычисляется по формуле:

ln(R'/R'') = B*(1/T' – 1/T'')

где R' и R'' – сопротивление терморезистора при (абсолютной) температуре соответственно T' и T'';
B – постоянная, зависящая от типа терморезистора.

В качестве R' можно взять сопротивление верхнего резистора в делителе напряжения, тогда измеренное отношение T0/T1 можно сразу подставить в формулу. Преобразовав формулу, получим выражение для T'':

T'' = B / (A – ln(T0/T1)) (1)

где: T'' – искомая (абсолютная) температура терморезистора;
A = B/T', T' – температура, при которой сопротивление терморезистора равно сопротивлению верхнего резистора делителя напряжения. Параметры A и B определяются при калибровке. Чтобы перевести температуру T'' в градусы Цельсия, нужно из неё вычесть константу 273,15.

Калибровка. При калибровке проводятся контрольные измерения известных температур (реперных точек), значения точек вводятся в устройство. Каждое измерение даёт значение d[i] = ln(T0/T1), и известное значение температуры T[i]. Для расчёта удобнее вместо T[i] взять обратное значение f[i] = 1/T[i]. По методу наименьших квадратов минимизируется сумма квадратов отклонений рассчитанного значение f от заданного f[i]:

((A – d[1]) / B – f[1])^2 + ((A – d[2]) / B – f[2])^2 + … + ((A – d[n]) / B – f[n])^2 = Σ((A – d[i]) / B – f[i])^2 → min

Выполнив замену переменных C = A/B, D =1/B, получим выражение:

Σ(C – d[i] * D – f[i])^2 → min

Это известная задача линейной оптимизации. Чтобы найти минимум функции относительно переменных C и D, нужно приравнять нулю частные производные:

∂(Σ(C – d[i] * D – f[i])^2)/∂C = 2 * Σ(C – d[i] * D – f[i]) = 0

∂(Σ(C – d[i] * D – f[i])^2)/∂D = – 2 * Σ((C – d[i] * D – f[i]) * d[i]) = 0

На 2 можно сократить. Преобразуем систему уравнений:

Σ(C – d[i] * D – f[i]) = C * Σ(1) – D * Σ(d[i]) – Σ(f[i]) = 0

Σ((C – d[i] * D – f[i]) * d[i]) = C * Σ(d[i]) – D * Σ(d[i]^2) – Σ(f[i]*d[i]) = 0

Для краткости, индексы [i] можно опустить. А сумма Σ(1) равна n – числу точек. Получим:

C * n – D * Σ(d) – Σ(f) = 0

C * Σ(d) – D * Σ(d^2) – Σ(f*d) = 0

Решая полученную систему уравнений относительно C и D, получим выражения для C и D:

C = (Σ(f*d) * Σ(d) – Σ(f) * Σ(d^2)) / (Σ(d)^2 – n * Σ(d^2))

D = (n * Σ(f*d) – Σ(f)* Σ(d)) / (Σ(d)^2 – n * Σ(d^2))

Таким образом, для вычисления параметров C и D (а затем A и B), необходимо накопить четыре суммы и знать число точек. Сами же значения точек хранить не нужно. Алгоритм калибровки выглядит следующим образом:

  1. Вводим реперную точку. Получаем результаты измерения T0, T1 и контрольное значение температуры t;
  2. Вычисляем: d = ln(T0/T1); T = t + 273,15; f = 1/T;
  3. Накапливаем суммы: Σ(d) += d; Σ(f) += f; Σ(f*d) += f*d; Σ(d^2) += d^2; n += 1;
  4. Если n >= 2, то вычисляем параметры C и D по вышеприведённым формулам. Затем вычисляем B = 1/D, A = C/D
  5. Повторяем шаги 1-4 для всех точек.

Если введена только одна точка, то вычислять параметры C и D по формулам нельзя, в знаменателе получится ноль. В программе после ввода первой точки выполняется расчёт по упрощённой формуле: параметр B остаётся неизменным, вычисляется только параметр A. Практической пользы от этого нет, но в процессе калибровки позволяет видеть, что первая реперная точка принята в расчёт.

Особенности схемотехники. Выводы микроконтроллера RB0-RB7 подключены к выводам сегментов индикаторов (анодам). Выводы были переставлены между собой с целью удобства разводки печатной платы, вместе соединялись только выводы десятичной точки, т.к, она часто требует меньшего тока. Резисторы R3-R10 ограничивают ток сегментов. Выводы разрядов (катоды) через транзисторные ключи VT1-VT6 подключены к выходам сдвигового регистра 4094, который используется для поочерёдного включения разрядов. Входы регистра подключены в выводам микроконтроллера RA6 и RA7. Ко входу RA5 подключена кнопка (обычная без фиксации), главное назначение которой — выполнение калибровки. Вывод RA4 – свободен, подтянут к источнику питания, с модифицированной прошивкой может быть использован для других целей.

Терморезисторы должны быть с отрицательным ТКС (в авторском варианте используются ММТ-4). Номинальное сопротивление может быть любым, оптимально — в пределах 4,7 — 22 кОм. При этом сопротивление постоянного резистора, который стоит в верхнем плече делителя напряжения, должно быть примерно равным номиналу терморезистора или чуть больше. Его сопротивление особого значения не имеет, оно учитывается в процессе калибровки, но должно быть стабильным — от этого зависит стабильность измерений. Конденсаторы C1-C3 должны быть слабо поляризующиеся. Транзисторы VT1-VT6 – КТ315Б, КТ315Г или аналогичные с h21э >= 100, и максимальным током коллектора не менее 100 мА. Светодиодные индикаторы — типа E30561 или любые другие семисегментные с общими катодами. Цвет свечения значения не имеет (у автора один красный, второй - зелёный), но если требуется работа при пониженном питании (до 3 В), то нужно брать красные. Напряжение питания может быть в пределах 4,5-5,5 В (нижний предел можно снизить до 3 В, если установить в 0 бит BODEN в конфигурационном слове прошивки), ток потребления может достигать 80-90 мА.

Особенности реализации. Для управления индикатором используется стандартный приём: таймер настраивается на выдачу прерываний, а в обработчике прерывания переключаются разряды и выдаются сигналы на сегменты. Частота прерываний выбрана довольно большой (1000 Гц), получается по 167 Гц на цифру. В обработчике прерываний также опрашивается состояние кнопки, распознаются одиночные, двойные и длинные нажатия с подавлением дребезга контактов. Также организуется несколько программных таймеров для различных целей.

Поскольку процесс измерения интервалов T0 и T1 довольно длительный (0,6 с), и требует точного соблюдения временных задержек, то прерывания неизбежно приведут к искажению результатов измерений. Но если их запретить, то погаснет индикация, что вызовет неудобства в работе. Чтобы этого избежать, использовано следующее решение: прерывания запрещаются, но в цикле измерения проверяется состояние флага прерывания. Как только флаг устанавливается, то вывод RA3 переводится в режим ввода, после чего прерывания разрешаются. А после того как обработчик прерывания завершит работу, прерывания снова запрещаются, и затем вывод RA3 снова переводится в режим вывода. Таким образом, прерывания хотя фактически и выполняются, но не оказывают существенного влияния на результаты измерений, т.к, всё это время вывод RA3 находится в режиме ввода и конденсатор C1 просто хранит накопленный заряд.

В конце цикла измерений получаем значения временных интервалов T0 и T1. Далее следует расчёт по формуле (1). Вычисления выполняются с плавающей точкой, вариант с целочисленными вычисления был признан неудовлетворительным по точности. Для выполнения вычислений организована стековая машина (примерно как на советских калькуляторах Б3-34, МК-52/61 или аналогичных, или на процессорах 80x87). Результат переводится в градусы Цельсия, преобразуется в десятичное число и выводится на индикатор. Если значение температуры получилось в пределах -9,9 … +99,9 °С, результат будет выведен с десятыми долями градуса. Результат в пределах -99 … +999 °С выводится как целое число. Если результат не помещается на индикаторе, выводится одиночный символ «-». Если в процессе вычислений произошла ошибка (например, деление на ноль; она может произойти при обрыве или коротком замыкании датчика), выводится три символа «-».

О вычислении логарифма. В формуле (1) присутствует натуральный логарифм. Обычно он вычисляется по таблице, или аппроксимируется полиномом. Здесь использован алгоритм, основанный на формуле:

log(x – x/n) = log(x * (1 – 1/n)) = log(x) + log(1 – 1/n)

В программе имеется таблица LNT значений log(1 – 1/n) (точнее, –log(1 – 1/n)) для n = 2^k, k = 1 … 24 (по числу бит мантиссы). Алгоритм напоминает алгоритм деления (в программе даже вынесена вспомогательная подпрограмма, которая используется и в делении, и в логарифме). Алгоритм следующий:

  1. Нормализуем (сдвигами влево или вправо) аргумент x, чтобы он находился в пределах 1<=x<2, подсчитываем число сдвигов p. Поскольку аргумент задан с плавающей точкой, то он уже нормализован, в качестве x берём мантиссу, а в качестве p – порядок;
  2. Присваиваем: r = 0; k = 1;
  3. Вычисляем: b = x >> k;
  4. Если x – 1 >= b, то выполняем: x – = b; r += LNT[k]; иначе выполняем: k += 1;
  5. Повторяем шаги 3-4 пока k <= 24;
  6. После выполнения шагов 1-5, x будет иметь значение, близкое к единице, а r – приближённое значение логарифма нормализованного значения х. Нужно ещё учесть значение порядка p. Для этого нужно умножить значение p на константу ln(2) и результат прибавить к r: r += p * ln(2)
  7. В результате r содержит вычисленное значение логарифма x.

На шаге 6 можно избежать умножения, если взять не натуральный, а двоичный логарифм. Для работы схемы это несущественно, от этого только изменится значение параметра B. Но для двоичного логарифма (в отличие от натурального) значения в таблице LNT получаются «некруглые», погрешность вычисления с ними будет больше.

Порядок работы. При включении питания сначала выполняется тест индикатора — в течение примерно 2 сек. горят одновременно все сегменты. Затем происходит переход в режим измерений. Нажатием и удержанием кнопки в течение примерно 2-3 сек можно перезапустить устройство (watchdog'ом). Других функций у кнопки в этом режиме нет.

Порядок калибровки. Перед первым использованием или после замены датчика, термометр необходимо откалибровать. Для этого нужно выполнить минимум два измерения известных температур (реперных точек), и ввести их значение. Реперных точек может быть и больше (ограничено до 9, но теоретически ограничений нет), параметры для расчёта температуры определяются методом наименьших квадратов. Весь расчёт заложен в прошивку. Каналы можно калибровать либо одновременно, либо каждый по отдельности. Порядок ввода данных о реперных точках значения не имеет, между вводом отдельных точек допускается отключение питания — накопленные данные сохраняются в энергонезависимой памяти микроконтроллера (EEPROM), при необходимости их можно оттуда прочитать программатором (и записать заново).

Для входа в режим калибровки, нужно выполнить перезапуск устройства (длинным нажатием на кнопку или кратковременным отключением питания, и пока выполняется тест индикатора, дважды нажать на кнопку. На индикаторах при этом в старшем разряде появляется символ «P», а в младшем — цифра — число уже введенных реперных точек для данного канала. Одиночным коротким нажатием на кнопку можно выбрать канал для калибровки (при этом второй индикатор гаснет), либо оба сразу (горят оба). Двойное нажатие на кнопку — начало калибровки выбранного канала (каналов). Длинным нажатием и отпусканием кнопки можно сбросить накопленные данные и начать калибровку сначала — число точек при этом сбрасывается в ноль (реально данные стираются не сразу, а после ввода первой точки). Пауза в 10 секунд приводит к выходу из режима калибровки и переходу в обычный режим измерения температуры.

После входа непосредственно в режим калибровки (по двойному нажатию из режима выбора каналов) на индикаторах показывается некоторое значение температуры. При этом десятичная точка мигает — это признак режима калибровки. Устройство может находиться в этом режиме неограниченно долго (до отключения питания). Выйти из этого режима в режим выбора каналов можно двойным нажатием кнопки (без ввода реперной точки). Затем нужно поместить калибруемый датчик в среду с известной температурой, и дождаться установления неизменных показаний. Затем нажать и удерживать кнопку — при этом значение на индикаторе начнёт увеличиваться, сначала медленно, затем быстрее. Если отпустить кнопку и снова нажать и удерживать — теперь показания начнут уменьшаться. При следующем длинном нажатии — снова увеличиваться, таким образом нужно добиться нужного известного значения температуры. Короткое нажатие значение не меняет, но переключает направление изменения показаний для последующего длинного нажатия. Двойное нажатие завершает ввод реперной точки — калибровочные данные записываются в энергонезависимую память, параметры для расчёта температуры пересчитываются. Пауза в 10 секунд означает отказ от ввода точки — устройство возвращается в режим отображения температуры (но остаётся в режиме калибровки). В процессе ввода температуры нет необходимости постоянно держать датчик в среде с известной температурой, показания фиксируются в момент первого длинного нажатия на кнопку.

Автор выполнял калибровку следующим образом. Первая реперная точка — тающий лёд: в пластиковый стакан налита вода и заморожена. Затем датчики были помещены в растаявшую воду, при этом в воде плавал лёд. Вода непрерывно перемешивалась в течение нескольких минут (показания при этом оказывались заметно ниже чем без помешивания), и затем эта точка была зафиксирована как 0 °С. Затем для первого датчика введена вторая реперная точка — температура тела по медицинскому термометру. Следующая реперная точка (третья для первого датчика, и вторая для второго) — кипящая вода. Её температура зависит от атмосферного давления, барометр в наличии имелся, расчётная температура получилась +99,2 °С. Столько было и введено (при этом первый датчик, уже откалиброванный по двум точкам показывал +106 °С). И наконец была контрольная проверка второго датчика по температуре тела с целью узнать: достаточна ли калибровка по двум точкам. Индикатор показал +35,6 °С, медицинский термометр +36,6 °С. После ввода этого значения как третьей реперной точки показания изменились на +35,8 °С. Вероятно, это уже неточность модели.

Схема в формате PDF

Прошивка

Весь проект

Термометр в сборе:

Печатная плата:

Датчики

Термометр в работе

Copyright (c) Sergey Mudry