Программная компенсация температуры "холодного спая" при работе с термопарой

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

Под катом много математики и нет картинок и одна картинка ).

И чтобы далеко не ходить, обещанная картинка с температурой в доме:
Дома сейчас 24.4 градуса. Весна. Батареи на всю катушку жарят...

Для тех, кому надо результат:
Берем приложенный файл. Делаем 3 замера:
Нагреваем плату с «холодным спаем» и измеряем температуру 100 градусов (кипящую воду).
Остужаем плату (например в холодильнике), и снова измеряем темепературу 100 градусов и 0 градусов.
Заносим данные в верхний левый угол таблицы.
Подбираем коэффициент КТ (первая срока), так, чтобы ошибка была минимальной.
Полученные 4 числа: КТ, С, К1 и К2 используем для перевода «попугаев» в температуру.
Если хочется оптимизаций, то она описана в конце статьи.
Все. Дальше, только математика :)

Постановка задачи:
Мы измеряем температуру с помощью термопары, и неким образом знаем температуру «холодного спая» (например припаяв рядом специальную микросхему и читая ее данные).
Задача: нужно минимизировать ошибку измерения имея на входе некое волшебное число А — величина с термопары («горячий спай») и некое волшебное число B — величина температуры «холодного спая», а так-же найти коэффициент самой термопары.

Предварительные мысли:
Как правильно обратил внимание уважаемый DeepSOIC в комментарии к первоначальной статье:
Напряжение на термопаре пропорционально разности температур между её спаем и её разъёмом. Разъём называют «холодный спай» — cold junction — который кстати вовсе не обязательно холодный, просто так называется. Т.е. термопара измеряет не температуру, а разность температур. Чтобы получить полную температуру, нужно измеренную разность температур приплюсовать к температуре холодного спая.
Как бы это все понятно, но для себя в мозгу фразу:
термопара измеряет не температуру, а разность температур
я уяснил только прочитав этот комментарий. Спасибо огромное!!!

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

Эврика:
А зачем нам все это делать? Если мы допустим, что закон линеен (не линейный закон, мы все равно не вычислим, да и точность нам нужна не до тысячных), то получается элементарная задача:
Дано: 2 числа А и В. Необходимо:
1) Найти КТ
2) Вычислить некое число, линейно зависящее от А, В и КТ.
Из математики, мы получаем единственный вариант:
ЧИСЛО (Ч) = ВОЛШЕБНАЯ КОНСТАНТА (С) + ВОЛШЕБНЫЙ КОЭФФИЦИЕНТ 1 (К1) * А + ВОЛШЕБНЫЙ КОЭФФИЦИЕНТ 2 (К2) * В
Все что нам необходимо, это найти 3 волшебных числа. Т.е. решить систему линейных уравнений с 3-мы неизвестными. Для этого нужно иметь 3 уравнения. Не вопрос: проводим 3 замера (и еще 3 для контроля), подставляем, решаем. Важное дополнение по итогам обсуждения:
необходимо 3-е измерение брать при значительном изменении температуры «холодного спая». Это даст более точное решение.
Например так:
Нагреваем плату с «холодным спаем» и измеряем температуру 100 градусов (кипящую воду).
Остужаем плату (например в холодильнике), и снова измеряем темепературу 100 градусов и 0 градусов.

Остается найти КТ, как число, которое дает минимальную ошибку для тестовых замеров. ВСЕ!!! Самое интересное, что система не явно, дает самый точный результат, при правильно КТ. Т.е. мы можем просто менять в условиях задачи КТ и смотреть, где ошибка меньше, там точнее КТ.
Математика за нас, учла и смещение 0, и взаимное влияние коэффициентов друг на друга и КТ. Для каждой схемы, решение будет разное. Но решение не зависит от внешних факторов. Оно зависит только от реализации схемы, и учитывает все погрешности и не точности (например разброс номиналов резисторов) — они получаются учтены в результатах тестовых измерений, и в решении они тоже учитываются. Кроме того, системе не важно в каких «попугаях» заданы числа А и В. Единственное требование: (достаточно точная для задачи) линейность этих «попугаев».

Пример из моей задачи:
КТ = 5
Температура Горячий спай Холодный спай
    0          -116	    3334
    0          -122	    3488
    0          -124	    3500
   100          389	    3432
   100          382	    3564
Система уравнений:
28,7414	= C + К1 * -116 + К2 * 3334
28,5902	= C + К1 * -122 + К2 * 3488
30,9189	= C + К1 *  389 + К2 * 3432

Решение:
K1 = 0,0044687231
K2 = -0,000878236
C = 32,1877900423

Итог для последнего измерения:
Ч = 32,1877900423 + 0,0044687231 * 382 - 0,000878236 * 3564 = 30,7648
Смещение = 3564 / 30,7648 = 115,8466
Результат = 382 + 115,8466 = 497,8466
Температура = 497,8466 / 5 = 99,5693
Все результаты:
Смещение	Результат	Температура	Ошибка
116,0000	  0,0000	   0,0000	 0,00
122,0463	  0,0463	   0,0093	 0,01
122,5497	 -1,4503	  -0,2901	 0,29
111,0248	500,0248	 100,0050	 0,00
115,8466	497,8466	  99,5693	 0,43

Должен заметить, что коэффициент КТ, подобран по минимальной ошибке.
Например, при КТ = 6 получается так:
Смещение	Результат	Температура	Ошибка
116,0000	  0,0000	   0,0000	 0,00
119,4133	 -2,5867	  -0,4311	 0,43
119,5223	 -4,4777	  -0,7463	 0,75
206,0085	595,0085	  99,1681	 0,83
208,3491	590,3491	  98,3915	 1,61


Для упрощения расчетов, я приложил файлик с готовыми формулами. Надо только подставить данные и подобрать КТ.
ВНИМАНИЕ: никаких макросов я не использовал. Если они есть, значит это вирус!!! Будьте внимательны!!!

Оптимизация:
Если посмотреть на алгоритм, то расчеты это куча умножений и делений дробных чисел. Это и на ПК не быстро, а уж в МК и подавно… Поэтому я использую хитрость: работу с фиксированной запятой. В итоге, работа только с целыми числами!!!
Суть: все 3 коэффициента: С, К1 и К2 я умножаю на 65536 (думаю понятно почему 65536 :)):
K1 = 0,0044687231 * 65536 = 293
K2 = -0,000878236 * 65536 = -58
C = 32,1877900423 * 65536 = 2109459

В результате, число Ч автоматически увеличивается в 65536 раз. Только все операции целочисленные. При вычислении смещения, мы предварительно умножаем значение холодного спая на 65536 и при ЦЕЛОЧИСЛЕННОМ делении 65536 исчезает… :) Конечно, точность немного страдает… Но скорость вырастает на порядки…
Но и тут еще можно поднять точность, используя целые числа, т.к. смещение число не большое, и 1-ка очень важна (1% точности). Мы умножаем значение холодного спая не на 65536, а на 131072. И после деления, прибавляем единичку и делим на 2, чтобы компенсировать ошибку. В итоге получаем округление до 0.5 )
В приложенном файле, есть оба варианта (дробное и целое).
Целое дает ТОЧНЫЙ(!!!) результат на тестовых данных. Ошибка 0.

ОБНОВЛЕНИЕ:
Пояснения по решению, или ответы на вопросы:
По сути мы хотим получить две прямые (но нас интересует их сумма).

Первая прямая — горячий спай,
t1 = k1 * A + c1
Вторая — холодный
t2 = k2 * B + c2

Нас интересует их сумма
t = k1 * A + k2 * B + c (где с = с1 + с2)
0          -122         3488
0          -124         3500
100          389         3432
      1   -116   3334
      1   -122   3488
      1    389   3432
К сожалению, мы НЕ ищем прямое преобразование А-В в температуру и НЕ решаем описанные уравнения. Это было бы идеально. И для расчетов (2 умножения, 2 сложения) очень просто и не напряжно для МК. Проблема в том, что это НЕ работает :(

По факту, как правильно заметили:
Вообще самое правильное это сначала измеренную температуру холодного спая преобразовать в эквивалентное термо ЭДС (Как если бы холодный спай был при нуле, а рабочий при измеренной температуре), затем сложить это напряжение с измеренным с термопары, а потом уже обратно преобразовать эту сумму в температуру. Таким образом полностью компенсируются нелинейности.
Т.е. системой уравнений, мы как раз и ищем КОЭФФИЦИЕНТЫ для расчета КОЭФФИЦИЕНТА КОМПЕНСАЦИИ «холодного спая» для заданных условий.
Не понятно откуда взялись числа 28,7414 28,5902 30,9189
Это как раз и есть КОЭФФИЦИЕНТы КОМПЕНСАЦИИ «холодного спая» для заданных условий. Они разные для разных данных.
При дальнейших расчетах, мы делим на этот коэффициент, тем самым внося нелинейность в формулу перевода «попугаев» в температуру.

Пояснение 2, математическое:
Пусть:
t – измеряемая температура
vx – измеренное значение «холодного спая»
vg — измеренное значение «горячего спая»
vg0 — измеренное значение «горячего спая» если бы измерение проводилось при vx = 0
КТ – коэффициент перевода vg0 в t:
(1)	t = vg0/КТ

Но как правило, vx не равно 0, поэтому нам надо привести vx к нулю, изменив vg на некую величину, зависящую от vx:
Пусть kx – коэффициент компенсации:
(2)	vg0 = vg + vx/kx,     vx = 0

Предположим, что kx линейно зависит от vx и vg:
(3)	kx = c + k1 * vx + k2 * vg

Для нахождения c, k1 и k2, необходимо решить систему линейных уравнений с 3-мя неизвестными для известных kx, vx, vg. vx и vg мы измеряем непосредственно.
kx мы находим по формуле (1) и (2), зная температуру в точках измерения:
(4)	kx = vx/(vg0 - vg) и vg0 = t * KT 	=>	 kx = vx/(t * KT - vg)

Итого из (3) и (4):
(5)	vx/(t * KT - vg) = c + k1 * vx + k2 * vg

Но (5) это уже не линейное уравнение, поэтому проще всего подобрать КТ по минимальной ошибке решая систему линейных уравнений для каждого КТ.
Файлы в топике: thermocouple.zip

Комментарии (22)

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

По сути мы хотим получить две прямые (но нас интересует их сумма).

Первая прямая — горячий спай,
t1 = k1 * A + c1
Вторая — холодный
t2 = k2 * B + c2

Нас интересует их сумма
t = k1 * A + k2 * B + c (где с = с1 + с2)

Математически верно, но в А и В есть погрешность измерения. Чтобы максимально точно (в данном случае) построить каждую прямую по двум точкам, нужно чтобы эти точки были максимально удалены друг от друга. Чем дальше — тем лучше, тем меньше будет сказываться погрешность.

Для горячего спая (А) у вас разница в 100 градусов, что ИМХО, достаточно для Вашего случая. А вот для холодного — у Вас разница на уровне шума датчика, и вычисленные значения к2 и с2 будут очень грубыми.

Описание получилось путанным, но я думаю суть понятна. Я бы предложил отдельно «линеаризировать» холодный спай на значительной разнице температур (охлаждая и нагревая все устройство).
+2
Да. Согласен. Но к сути идеи это не относиться. В своем устройстве я еще буду проводить эксперименты.
0
Дописал в статью пояснения.
0
Хм, просмотрел еще раз внимательно Ваш пост и запутался окончательно. Плюс, в ОпенОфисе приатаченный файл открывается с битой кодировкой.

Давайте начнем с стемы уравнений. Я сразу решил, что в правой части уравнений у вас температура, но там непонятные для меня величины (28,7414 и т д).
Далее, на основании 3-х измерений решили систему уравнений. Получили формулу зависимости.

Теперь в эту формулу мы подставляем результаты 5-го измерения. И что мы получаем? По логике, результат вычисления это апроксимированное значение этой самой «непонятной для меня величины» для 5-го измерения. Только зачем находить ее аппроксимированное значение, ели мы, на сколько я понимаю, можем измерить ее прямыми методами (как для предыдущих случаев). Дальше я совсем потерялся в смысле вычислений.

Если не тяжело, объясните смысл Вашего метода более подробно, с описанием физического смысла получаемых величин (потому как понятие «волшебное число» не способствует пониманию)

мы делим на этот коэффициент, тем самым внося нелинейность в формулу перевода «попугаев» в температуру.

Ели мы просто делим на константу — откуда берется нелинейность?
0
1) Мы должны компенсировать «холодный спай», фактически просто прибавив термоэдс «холодного спая» к «горячему спаю», чтобы получить ситуацию, как будто холодный спай находиться при 0.
1.1) Для этого, мы просто умножаем «холодный спай» на некий коэффициент.
1.2) Коэффициент мы находим по формулам.
2) После этого, мы переводим значение «горячего спая» в температуру, умножая на некий другой коэффициент.

Г — горячий спай
Х — холодный
КТ — коэффициент термопары

температура = (Г + Х * Ч) * КТ
где Ч = С + К1 * Х + К2 * Г — коэффициент компенсации «холодного спая»
0
Честно говоря, ситуация для меня не прояснилась. Возможно я где-то сильно торможу :)
Вот ниже есть pdf. В тех расчетах все понятно — берем температуру холодного спая, через многочлен с заданными в таблице коэффициентами вычисляем ЭДС «холодного спая». Потом ЭДС «холодного» и «горячего» спая суммируем, и (через другой многочлен) приходим к температуре.

А вот в Вашем случае я не могу понять логику расчетов. Для начала не понятно — откуда возись цифры 28,7414 28,5902 30,9189 (каков их смысл).

Ели вы их как-то получили/вычислили экспериментально, то зачем вы сначала аппроксимируется результаты трех измерений к линейной функции, а потом, на основе этой функции, вычисляете значение для вашего 5-го эксперимента.

тем самым внося нелинейность в формулу перевода «попугаев» в температуру

И откуда берется нелинейность, ели вы оперируете линейными функциями?
0
Дописал чисто математическое описание с формулами.
0
«Если ученый не может объяснить восьмилетнему мальчику, чем он занимается, то он шарлатан». (с) Курт Воннегут, Колыбельная для кошки.
Вот поэтому я и не ученый, т.к. не хочу быть шарлатаном )
0
Файлик перезалил.
0
Не понятно откуда взялись числа 28,7414 28,5902 30,9189. Ну и выше коммент правильный, про плохую обусловленность при таком выборе точек измерения. Мне помогает смотреть на ранг матрицы коэффициентов системы уравнений,

0          -122         3488
0          -124         3500
100          389         3432

Здесь видно, что две верхние строки «почти» линейно зависимы и ранг меньше 3, если не обращать внимания на «слабые» отличия. Есть более строгие способы, но они сложнее.
+1
Ошибся, матрица должна была быть такая,


      1   -116   3334
      1   -122   3488
      1    389   3432
0
числа 28,7414 28,5902 30,9189 это искомые коэффициенты, для учета холодного спая.
мы знаем, что мы должны получить на выходе: 0 и 500. Мы знаем значение «горячего спая» — значит знаем смещение. Мы знаем значение «холодного спая» — значит знаем коэффициент перевода == «холодный спая» / смещение.

По поводу ранга матрицы: почти в линейной алгебре не считается. )
А в целом, я согласен с вами. Нужно 3-й отсчет брать при значительной разнице «холодного спая». Допишу в статью.
0
Дописал в статью пояснения.
0
Вообще самое правильное это сначала измеренную температуру холодного спая преобразовать в эквивалентное термо ЭДС (Как если бы холодный спай был при нуле, а рабочий при измеренной температуре), затем сложить это напряжение с измеренным с термопары, а потом уже обратно преобразовать эту сумму в температуру. Таким образом полностью компенсируются нелинейности. Полиномы есть для прямого и для обратного преобразования www.omega.com/temperature/z/pdf/z198-201.pdf
0
Вот это я и сделал ) Просто чтобы не заморачиваться с полиномами, я решил простую систему уравнений и подобрал один коэфициент.
0
Еще вопрос. Я не силен в полиномах. Можете расшифровать документ. Можно только в части термопар типа «K». Буду очень благодарен.
0
С полиномами всё просто, хотя тут уж слишком высокой они степени. Сn это коэффициенты соответствующей степени(для разных диапазонов они немного отличаются). Тоесть E=C0+C1*T+C2*(T^2)+C3*(T^3)+C4*(T^4)… Аналогично и обратное преобразование, но коэффициенты другие.
0
Т.е. если мы говорим про линейное преобразование, то мое решение особо ничем не отличается, кроме того, что искать нужные полиномы не надо? Тут еще момент, что данные в полиномах требуют возведения экспоненты в некоторую степень. Это очень не быстро…
0
Хотя немного недоглядел, на положительной температуре там к полиному надо ещё прибавлять ещё кусок с е в степени. И эдс E в микровольтах. Но если точности в сотки не нужно, тогда вам вполне наверно хватит полинома второй или третьей степени. Самое простое в экселе построить график таблицы температур и ЭДС, добавить на графике линию тренда степенную, выбрать нужную степень и отобразить уравнение.
0
Здравствуйте! Хорошая статья про термопару!

Хотел заметить, что с моей точки зрения для вычисления коэффициентов любого нелинейного преобразования, которое линейно по своим подбираемым коэффициентам, вроде подходит линейная регрессия.
|A| = (tr(|X|)*|X|)^(-1)*tr(|X|)*|Y|, где

|X| — матрица, строки которой показания из микроконтроллера, преобразованные Вашим линейным или нелинейным преобразованием,

|Y| — матрица, строки которой — желаемые результаты, т.е. скалярное значение температуры в данном случае.

Результатом |A| получится столбец коэффициентов.

Полученные коэффициенты |A| будут оптимальны в смысле суммы квадратов отклонений. Эмпирически по смыслу чем больше снять показаний, тем точнее будет совпадение.
0
делал для дипломной систему измерения сигналов термопар
тоже преобразовывал температуру холодного спая в эквивалентную термо-ЭДС, складывал с ЭДС горячего и преобразовывал в температуру горячего
прямые и обратные преобразования делал по таблице и не парился
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.