6 марта 2012 г.

Подключаем аналоговый температурный сенсор к Arduino и калибруем его

У Arduino есть два типа температурных сенсоров - цифровые и аналоговые. Аналоговые имеют в своей основе терморезистор, или термистор - полупроводниковый резистор, у которого явно выражена зависимость сопротивления от температуры, и она представляет собой гладкую функцию. Соответственно, измеряя его сопротивление, можно измерять температуру среды.



Схема измерения температуры с термистором

Мы помним, что на плате Arduino UNO есть шесть аналоговых входов, которые, по сути, являются каналами АЦП. В один из таких каналов мы и включим термистор. Однако как померить его сопротивление, если АЦП умеет измерять только напряжение? Умные ребята придумали для этого использовать схему простого делителя:
Здесь U0 - известное напряжение, R0 - известное сопротивление, RT - сопротивление, зависящее от температуры, Uизм - измеряемое напряжение. Из рисунка очевидно, что для измеряемого напряжения справедливо соотношение:
Откуда сопротивление термистора выражается так:
Однако померить сопротивление мало, нам ведь нужно получить температуру!

Уравнение Стейнхарта-Харта

Типовая зависимость  сопротивления термистора от температуры выглядит так:




Уважаемые господа Джон Стейнхарт и Стэнли Харт в 1968 году опубликовали свою работу, посвященную калибровочным кривым термисторов, в которой экспериментально вывели уравнение, связывающее сопротивление и температуру полупроводниковых термисторов. Вот это уравнение:
Здесь a, b и с - калибровочные константы, так называемые коэффициенты Стейнхарта-Харта. Это уравнение аппроксимирует кривую с хорошей точностью при подобранных коэффициентах для конкретного термистора.

Коэффициенты Стейнхарта-Харта могут указываться в даташите производителем термистора.  А могут вместо них указываться табличные значения температур и сопротивлений для конкретного устройства.

Я понятия не имею, какой термистор в моем сенсоре, кто его произвел, какая у него модель, какие характеристики. Поэтому коэффициенты я буду искать сам. Магазин, в котором я покупал сенсор, предлагает использовать какие-то коэффициенты, однако китайцы такие китайцы и им не стоит доверять. Тем более, я читал, что если дисковые терморезисторы калибруются партиями на заводе, то каплевидные - вообще оторви да выбрось требуют индивидуальной калибровки.

Сенсор в студию

Мой аналоговый температурный сенсор выглядит так:


Черная круглая блямба на переднем плане - и есть термистор. На нем написано "103", а это значит что при комнатной температуре он имеет сопротивление 10 КОм (103=10*10^3). Далее идет микросхемка, которая есть ни что иное, как операционный усилитель LM358P. Есть еще 2 простых резистора, на которых тоже написано 103, один из которых никуда не подключен. Еще помните формулу для RT? Вот мы и нашли для нее R0, оно равно 10 КОм. А U0 равно 5 В, я вам так скажу. Больше на плате ничего нет!

Сенсор очень просто подключается к Arduino Sensor Shield, который, в свою очередь, надевается на Arduino [в этом соль Arduino, кто еще не понял], прям как у меня вот так:


Ну собственно все - железо готово к лабораторной работе.

Калибровочная установка

Для калибровки понадобится печка, которая показывает свою температуру, и держит ее при этом (!). Нет проблем - пошел в ИНХ СО РАН, их там в каждой лабе по несколько штук. Выбирай по цвету, что называется. Приглянулась мне вот такая:


Вообще это типа нагревательный столик (30...300 градусов Цельсия), который суют под микроскоп и рассматривают всякие штуки, нагревая их. Вот почему такой странный дизайн.

Собираем установочку: Arduino в комп, сенсор в крышечку с водой, крышечку на печку, хвостик под лавочку, накрываем печку колпачком из кварца.


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

Методика калибровки 

Пристально смотрим на уравнение Стейнхарта-Харта и видим в нем три неизвестных. Это означает, что нам достаточно провести три измерения и получить, таким образом, три уравнения.

Выбираем три точки на температурной шкале. Мне нравятся, например, 30, 40 и 50 градусов Цельсия. Нагреваем печку до одной из температур, ждем 10 минут, чтобы все термодинамические процессы произошли и энтропия вселенной увеличилась, замеряем сопротивление. Потом повторяем все для второй и третьей температур.

Составляем три уравнения и решаем систему (линейных кстати) уравнений. Нам лениво и мы заставим это делать Mathcad, который нам таки-выдаст коэффициенты Стейнхарта-Харта.

Думаю, тут все понятно.

Serial Communication

Есть у Arduino такая классная штука - serial communication. Это есть явление общения компа с Arduino во время выполнения программы. Происходит это через USB-порт, который эмулирует COM-порт. Это позволяет мониторить состояние платы в реальном времени и даже посылать на нее команды с компа.

Чтобы вызвать Serial monitor, выберите в меню Tools->Serial Monitor или нажмите хитрую комбинацию из трех клавиш ctrl+shift+M во время выполнения программы.

Чтобы заставить Arduino вывести что-то в последовательный поток, просто воспользуйтесь функцией Serial.println(число) или Serial.println("текст").

Последовательный обмен необходимо инициализировать в setup(){}, всунув туда команду Serial.begin(бодрейт). Бодрейт (baudrate) - количество информации, передаваемой в единицу времени (не путать с битрейтом). Arduino предлагает на выбор: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 бод. Вот что бывает, если не согласовать бодрейт в своей программе и в мониторе последовательного порта:


У вас это и должно произойти, когда вы впервые откроете монитор. Не пугайтесь.

Кодим

Напишем коротенький код, чтобы мониторить измеряемое значение напряжения и вычисляемое значение сопротивления:



void setup() {
  Serial.begin(115200);           //стартуем последовательное соединение
}


void loop() {
  double rt;                      //измеряемая величина
  Serial.println("voltage:");     //пишем в поток слово для красоты
  rt=(analogRead(0));             //читаем значение с сенсора
  Serial.println(rt);             //выводим значение с сенсора в поток
  rt = ((10240000/rt) - 10000);   //вычисляем сопротивление по формуле
  Serial.println("resistance:");  //пишем в поток еще одно слово для красоты
  Serial.println(rt);             //выводим значение сопротивления в поток 
  delay(5000);                    //ничего не делаем 5 секунд
}

В результате все красиво:



Вычисляем коэффициенты Стейнхарца-Харца

По описанной выше методике выписываем на листочек три значения сопротивления при трех разных температурах. Подставляем их попарно в три уравнения Стейнхарца-Харца и решаем систему. Вот фотка моего маткадовского файлика:

Обратите внимание, что я вместо коэффициента "c" написал "се" [цэ], потому что маткад не дает использовать символ "с" кроме как в значении скорости света.

Нижний вектор-столбец и есть наши искомые коэффициенты.

Еще раз кодим

Теперь напишем скетч, который позволит Arduino измерять температуру.



#include <math.h>    //подключаем свою библиотеку с блэкджэком и логарифмами


double Steinhart(int value) {
  double Temp;                  //в итоге эта переменная станет температурой
  Temp = log((10240000/value-10000));    //считаем логарифм
//считаем температуру из уравнения Стейнхарта-Харта
  Temp = 1/(0.001768+0.00005719*Temp+0.000001354*Temp*Temp*Temp);
  Temp = Temp-273.15;//переводим температуру в градусы Цельсия         
  return Temp; //передаем температуру обратно в loop
}


void setup() {
  Serial.begin(115200); //стартуем последовательное соединение
}


void loop() {
//передаем в функцию Steinhart измеренное значение и выводим температуру, которую она вернет
  Serial.println(int(Steinhart(analogRead(0)))); 
  delay(2000); //ничего не делаем 2 секунды
}


Резюме


Температура меряется все равно корявенько, дает расхождение до трех градусов. Процесс калибровки - сложная штука в плане правильного нагрева термистора и поддержания определенной температуры. Улучшение методики калибровки - подключение дополнительных термопар, создание термостатированной камеры, возможно, сильно изменят результаты в лучшую сторону. Кстати, неплохая темя для курсовой физика-второкурсника. Если у вас есть знакомый физик-второкурсник, посоветуйте ему эту идею! 

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