Урок 24. Подключение аналоговых термодатчиков к Ардуино (LM35, TMP35, TMP36, TMP37). Рабочий проект термометра.

Lesson24_9

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

Предыдущий урок     Список уроков     Следующий урок

Этой публикацией я начинаю цикл уроков об измерении температуры в системе Ардуино. Всего планируется 4 урока посвященных различным типам датчиков температуры:

В каждом уроке я расскажу:

  • коротко о принципе работы и параметрах термодатчиков;
  • о схемах подключения термодатчиков к микроконтроллерам;
  • расскажу о программной обработке информации с термодатчиков;
  •  приведу схему термометра на базе платы  Ардуино и программное обеспечение для него.

 

В каждом уроке будет рассмотрен проект термометра на базе контроллера Ардуино работающий :

  • в автономном режиме с выводом информации на LED индикатор;
  • в режиме связи с компьютером, позволяющем не только отображать текущую температуру, но и регистрировать изменение температуры с выводом данных в графическом виде.

Интегральные датчики температуры с аналоговым выходом по напряжению.

При всем разнообразии этих устройств, им присущи следующие общие качества:

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

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

Существует множество термодатчиков, которые можно отнести к этой категории. Я бы выделил следующие типы датчиков температуры:

  • LM35;
  • TMP35;
  • TMP36;
  • TMP37.

Это самые распространенные, достаточно точные, недорогие устройства. Я писал статьи об этих датчиках. Можно посмотреть по ссылкам LM35 и TMP35, TMP36, TMP37. Там подробно описаны все параметры, технические характеристики устройств, типовые схемы включения.

 

Подключение термодатчиков к микроконтроллеру.

Удобнее всего использовать датчики в корпусе TO-92.

Корпус TO-92

Схема подключения для устройств в корпусе TO-92 выглядит так.

Схема подключения

По этой схеме будут работать все перечисленные датчики. Информацию о других схемах включения термодатчиков можно посмотреть по ссылкам LM35 и TMP35, TMP36, TMP37.

Основные параметры, различия датчиков.

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

  • TMP36 – единственный из перечисленных термодатчиков, способен измерять отрицательную температуру.
  • Датчики имеют различные диапазоны измерения температуры.

Речь идет о термодатчиках, подключенных по приведенной выше схеме. Например, есть схема включения LM35, позволяющая измерять отрицательные температуры. Но она сложнее в реализации и требует дополнительного питания. Лучше для отрицательных температур использовать TMP36.

Основные параметры термодатчиков  LM35, TMP35, TMP36, TMP37 для этой схемы я свел в таблицу.

Тип Диапазон измерения температуры,
°C
Смещение напряжения на выходе,
мВ
Масштабный коэффициент,
мВ/°C
Напряжение на выходе при +25 °C,
мВ
LM35, LM35A 0 … + 150 0 10 250
LM35C, LM35CA 0 … + 110 0 10 250
LM35D 0 … + 100 0 10 250
TMP35 + 10 … + 125 0 10 250
TMP36 - 40 … + 125 500 10 750
TMP37 + 5 … + 100 0 20 500

У всех термодатчиков напряжение на выходе может быть только положительным, но за счет смещения TMP36 способен измерять отрицательную температуру. Нулевое напряжение на его выходе соответствует температуре – 40 °C, а при выходном напряжении 0,5 В температура будет равна 0 °C. Я считаю TMP36 самыми удобными из аналоговых интегральных датчиков температуры и использую их достаточно широко.

 

Проект Ардуино термометра на датчиках температуры LM35, TMP35, TMP36, TMP37.

Разработаем термометр, который будет:

  • В автономном режиме отображать значение температуры на четырех разрядном семисегментном светодиодном (LED) индикаторе.
  • Передавать текущее значение температура на компьютер. Наблюдать его можно с помощью монитора последовательного порта Arduino IDE.
  • С помощью специальной программы верхнего уровня (я ее написал):
    • отображать измеренную температуру на мониторе компьютера.
    • регистрировать изменение температуры и отображать его в графическом виде.

Схема термометра на базе платы Arduino UNO R3.

К плате Ардуино необходимо подключить:

  • четырех разрядный семисегментный LED индикатор в мультиплексированном режиме;
  • датчик температуры TMP36 или подобный.

Я выбрал светодиодный  индикатор типа GNQ-3641BUE-21. Он яркий, оптимальных для этой задачи размеров. Мы подключали его к плате Ардуино в уроке 20. В этом уроке можно посмотреть документацию на индикатор, схемы подключения. Там же есть описание библиотеки управления семисегментными LED индикаторами.

Схема термометра на базе платы Arduino UNO R3 выглядит так.

Схема термометра на базе Aduino UNO R3

LED индикатор подключен к контроллеру в мультиплексированном режиме ( урок 19, урок 20).

Датчик температуры подключен к аналоговому входу A0. Конденсатор C1 – блокирующий питание датчика, R1 и C2 – простейший аналоговый фильтр. Если термодатчик установлен вблизи микроконтроллера, то фильтр можно исключить из схемы.

TMP35, TMP36, TMP37 допускают работу на нагрузку емкостью до 10 нФ, а LM35 – не более 50 пкФ. Поэтому, если датчик соединяется с контроллером длинной линией имеющей значительную емкость, то резистор R1 должен быть установлен со стороны датчика, а конденсатор C2 – со стороны контроллера. Блокировочный конденсатор C1 всегда устанавливается рядом с термодатчиком.

В любом случае в программе контроллера будет реализована цифровая фильтрация сигнала с датчика.

Для проверки я собрал устройство на макетной плате.

Ардуино термометр

Вычисление температуры.

Принцип простой. Для вычисления температуры датчиков  LM35, TMP35, TMP37 необходимо:

  • Считать код АЦП.
  • Вычислить напряжение на выходе датчика как
    • Uвых = N * Uион / 1024, где
    • Uвых – напряжение на выходе термодатчика;
    • N – код АЦП;
    • Uион – напряжение источника опорного напряжения (для нашей схемы 5 В);
    • 1024 – максимальное число градаций АЦП (10 разрядов).
  • Разделить напряжение на выходе датчика на масштабный коэффициент.
  • Для датчика TMP36 необходимо перед делением на масштабный коэффициент вычесть напряжение смещения (0,5 В).

Формулы вычисления температуры для разных датчиков при опорном напряжении 5 В выглядят так.

Тип датчика Формула вычисления температуры T (°C),
при опорном напряжении 5 В,
из кода АЦП - N.
LM35, TMP35 T = ( N * 5 / 1024 ) / 0.01
TMP36 T = ( N * 5 / 1024 – 0.5 ) / 0.01
TMP37 T = ( N * 5 / 1024 ) / 0.02

Если используется цифровая фильтрация, то необходимо еще учесть коэффициент для нее. Также надо понимать, что формулы расписаны в виде удобном для понимания. В реальной программе лучше рассчитать постоянную часть формулы заранее и использовать как коэффициент. Об этом подробно написано в уроке 13. Там же информация о чтении и цифровой фильтрации аналогового сигнала.

 

Программа Ардуино термометра.

Программа должна выполнять следующие функции:

  • считывать значения кодов АЦП;
  • усреднять их (цифровая фильтрация) для повышения помехозащищенности;
  • вычислять температуру из кода АЦП;
  • выводить значение температуры на четырех разрядный LED индикатор в формате:
    • знак;
    • десятки;
    • единицы;
    • десятые доли °C.
  • передавать раз в секунду значение температуры на компьютер в символьном формате.

Разработка программы строится по привычному принципу:

  • реализовано прерывание от таймера с периодом 2 мс;
  • в нем параллельным процессом происходит:
    • регенерация LED индикатора;
    • чтение кодов АЦП и усреднение их значений;
    • программные таймеры.
  • В основном асинхронном процессе происходит:
    • синхронизация от программного таймера 1 сек;
    • вычисление температуры;
    • передача значения температуры на компьютер.

Если Вы читали предыдущие уроки, то все будет понятно.

Должны быть подключены библиотеки MsTimer2.h и Led4Digits.h. Загрузить библиотеки можно из урока 10 и урока 20. Там же есть подробное описание и примеры. По поводу измерения напряжения аналоговых входов можно посмотреть урок 13.

Я сразу приведу  скетч программы.

// термометр, датчики LM35, TMP35, TMP36, TMP37
#include <MsTimer2.h>
#include <Led4Digits.h>

#define MEASURE_PERIOD 500  // время измерения, * 2 мс
#define ADC_RESOLUTION  4.8828125 // разрешающая способность АЦП, мВ (5000 мВ / 1024)
#define OFFSET  500. // смещение выходного напряжения, мВ (для TMP36)
#define SCALE_FACTOR 10. // масштабный коэффициент, мВ (для TMP36)

int timeCount;     // счетчик времени измерения
long  sumA0;       // переменная суммирования кодов АЦП
long  avarageTemp; // среднее значение температуры (сумма кодов АЦП, среднее значение * 500)
boolean flagTempReady;  // признак готовности измерения температуры
float temperature;  // рассчитанная температура, °C

// тип индикатора 1; выводы разрядов 5,4,3,2; выводы сегментов 6,7,8,9,10,11,12,13
Led4Digits disp(1, 5,4,3,2, 6,7,8,9,10,11,12,13);

void setup() {
  MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс
  MsTimer2::start();               // разрешаем прерывание по таймеру
  Serial.begin(9600); // инициализируем порт, скорость 9600 
}

void loop() { 

  if ( flagTempReady == true ) {
    flagTempReady= false;
    // данные готовы

    // вычисление температуры
    temperature = ( avarageTemp * ADC_RESOLUTION / 500. - OFFSET ) / SCALE_FACTOR;

    // вывод температуры на индикатор
    if (temperature >= 0) {
      // температура положительная
      disp.print((int)(temperature * 10.), 4, 1);  
    }
    else {
      // температура отрицательная
      disp.digit[3]= 0x40;  // отображается минус
      disp.print((int)(temperature * -1 * 10.), 3, 1);        
    }
    disp.digit[1] |= 0x80;  // зажечь точку второго разряда                
           
    // передача температуры на компьютер
    Serial.println(temperature);
    }   
}

//-------------------------------------- обработчик прерывания 2 мс
void  timerInterrupt() {
  disp.regen(); // регенерация LED индикатора

  // измерение среднего значения темпрературы
  timeCount++;  // +1 счетчик выборок усреднения
  sumA0+= analogRead(A0);  // суммирование кодов канала A0 АЦП

  // проверка числа выборок усреднения
  if ( timeCount >= MEASURE_PERIOD ) {
    timeCount= 0;
    avarageTemp= sumA0; // перегрузка среднего значения
    sumA0= 0;
    flagTempReady= true;  // признак готовности результата
    } 
}

Можете загрузить скетч по этой ссылке.

Загружаем, проверяем. Запускаем монитор последовательного порта и проверяем данные на компьютере.

Окно монитора последовательного порта

Программа разработана для датчиков TMP36, но ее легко адаптировать под другие типы датчиков. Для этого достаточно изменить значения масштабного коэффициента и смещения, заданные в начале программы операторами #define.

Тип датчика Коэффициент и смещение
LM35, TMP35 #define OFFSET  0.
#define SCALE_FACTOR 10.
TMP36 #define OFFSET  500.
#define SCALE_FACTOR 10.
TMP37 #define OFFSET  0.
#define SCALE_FACTOR 20.

Разрешающая способность и точность термометра.

Разрешающая способность АЦП в нашей схеме 5 В / 1024 = 4,88 мВ.

Разрешающая способность термометра:

  • при масштабном коэффициенте 10 мВ/°C (датчики LM35, TMP35, TMP36)  равна менее 0,5 °C;
  • при масштабном коэффициенте 20 мВ/°C (датчик TMP37)  равна менее 0,25 °C.

Вполне приличные параметры.

Что касается погрешности измерения – несколько хуже.

Погрешность измерения самих датчиков составляет:

  • не более 0,5  °C для LM35;
  • не более 1  °C для TMP35, TMP36, TMP37.

Погрешность измерения АЦП платы Ардуино.

В нашем устройстве мы использовали опорное напряжение 5 В,т.е. напряжение источника питания. В платах Arduino UNO R3 напряжение 5 В формируется на линейном стабилизаторе NCP1117ST50. Характеристики в формате PDF можно посмотреть по этой ссылке NCP117.pdf. Стабильность выходного напряжения этой микросхемы довольно высокая – 1%.

Т.е. общая погрешность измерения термометра составляет не более 2%.

Несколько повысить ее можно измерив напряжение 5 В на плате и задав в параметр разрешение АЦП не 5 В, а более точное значение. У меня на плате напряжение оказалось равным 5,01 В. В моей программе надо исправить:

#define ADC_RESOLUTION  4.892578 // разрешающая способность АЦП, мВ (5010 мВ / 1024)

Применение внешнего источника опорного напряжения для платы Ардуино.

Но есть радикальный способ улучшить, как точность измерения АЦП, так и разрешающую способность. Это применение внешнего источника опорного напряжения.

Самым распространенным источником стабильного напряжения являются микросхемы LM431, TL431 и т.п. Я собираюсь написать статью об этой микросхеме. Пока дам ссылку на информацию – LM431.pdf.

Приведу схему включения LM431 в качестве источника опорного напряжения 2,5 В для платы Ардуино.

Внешний источник опорного напряжения для Ардуино

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

#define ADC_RESOLUTION  2.44140625 // разрешающая способность АЦП, мВ (2500 мВ / 1024)

И в setup() подключить внешний источник опорного напряжения:

analogReference(EXTERNAL); // внешнее опорное напряжение

В результате разрешающая способность уменьшится в 2 раза, а стабильность – на порядок. Только все равно, для повышения точности необходимо измерить вольтметром реальное напряжение LM431 и подкорректировать его в программе.

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

 

Программа верхнего уровня для термометра.

Смотреть на бегущие строки чисел в окне монитора Arduino IDE, быстро надоедает. Хочется просто видеть значение температуры. К тому же для практического использования термометра с компьютером должно быть установлено программное обеспечение Arduino IDE. Не на всех компьютерах оно есть. Также людей часто интересует изменение температуры, процесс нагрева или охлаждения в динамике. Хочется иметь возможность регистрировать изменение температуры и отображать его в графическом виде.

Для этого я написал простую программу верхнего уровня, которая:

  • отображает текущее значение температуры;
  • регистрирует изменение температуры с дискретностью 1 сек;
  • выводит информацию об изменении температуры в графическом виде.

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

Программа работает под управлением операционных систем Windows 95, 98, XP, 7. С остальными - не пробовал.

Установка приложения.

  • Загрузите архивный файл Thermometer.zip.
  • Распакуйте его в рабочую папку. Можно оставить папку из архива Thermometer.

Приложение состоит из двух файлов:

  • Thermometer.exe – исполняемый файл;
  • Conf.txt – файл конфигурации.

Устанавливать программу не надо, просто запускается файл Thermometer.exe.

Подключение термометра к компьютеру.

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

Удобнее всего использовать виртуальный порт, который создает драйвер платы Ардуино. Порт появляется при подключении платы к компьютеру. Запускать Arduino IDE не надо. Номер порта можно посмотреть: Панель управления -> Система -> Диспетчер устройств -> Порты (COM и LPT)

Проверка номера порта

У меня COM5.

Можно подключить компьютер через какой-нибудь мост USB-UART. Я использую модули PL2303 USB UART Board. Как подключить написано в статье о программе Монитор холодильника на элементе Пельтье.

Если на компьютере есть штатный COM порт (интерфейс RS232), то никаких драйверов устанавливать не надо. Для подключения контролера в этом случае необходимо использовать преобразователь уровней RS232 – TTL, микросхемы ADM232, SP232,  MAX232 и им подобные.

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

Первый запуск программы.

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

Дальше запускаете программу Thermometer.exe. В файле конфигурации программы записан какой-то COM порт. Программа попытается открыть его при запуске. Если не получится, то она выдаст сообщение с номером ошибочного порта.

Сообщение об ошибке

Нажмите OK и откроется окно программы. Вместо температуры будут прочерки. Нет данных.

Окно программы

Выберете в меню (сверху) режим выбор порта. Откроется окно выбора.

Окно выбор порта

Задайте номер порта для Вашей платы. У каждого порта написано его состояние. Естественно, необходимо выбирать из портов с надписью “свободен”.

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

Если плата включена, программа загружена, все работает правильно, то раз в секунду должен мигать кружок-светодиод перед значением температуры. Он мигает при поступлении новых данных.

Окно программы Ардуино термометр

Регистратор.

В программе существует регистратор, который позволяет наблюдать динамику изменения температуры. Регистратор включается автоматически при запуске программы. Он записывает значения температуры с дискретностью по времени 1 секунда. Максимальное время регистрации 30 000 сек или 8,3 часов.

Чтобы посмотреть результаты записи необходимо нажать закладку меню ”Регистратор”.

Окно регистратор программы термометр

Это я паяльником нагрел датчик.

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

Окно регистратор программы термометр

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

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

 

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

Предыдущий урок     Список уроков     Следующий урок

19 комментариев на «Урок 24. Подключение аналоговых термодатчиков к Ардуино (LM35, TMP35, TMP36, TMP37). Рабочий проект термометра.»

  1. Здравствуйте Эдуард! Скажите, пожалуйста, в какой программе Вы писали верхний уровень?

  2. Здравствуйте, Эдуард! Спасибо за урок, он поможет мне определится с глюком моей стиральной машины. Супруга утверждает — машинка на программе 30 градусов портит вещи. Вещи садятся, как-будто вместо 30 идет нагрев до 90 (максимум). И сейчас я проверяю этот вариант. Удобнее смотреть лог через монитор порта, а не через программу, т.к. она глючит — при вызове регистратора и его закрытии и снова открытии идет всплеск по шкале температура 250 градусов, и так при каждом вызове регистратора; на стареньком нетбуке, который я поставил на кухне, вообще идет загрузка процессора на 50% и при вызове регистратора видны и всплески до 250 и провалы до 0. Хотелось бы, конечно, пользоваться программой из-за наглядности, если возможно — допилите ее, она того стоит!
    p.s. стиралка пока не глючила, нагревается до установленных температур, может все-таки ошибка «оператора»!

    • Здравствуйте! У меня программа работает идеально. Может у Вас совсем старый компьютер. Обратите внимание появляется ли у Вас ошибка обмена. Светодиод ОБМЕН красным или серым становится? Программа написана на Borland C++ Builder. У меня много подобных программ, работающих на разных компьютерах. Все работает замечательно. Даже не знаю, что «допиливать».

  3. Исправьте плиз баг в программе чтобы выше 10 порта можно было опрашивать. А то я через USB концентратор подключаюсь а это как правило 20 порт.

    • Выше 9го порта сделать не просто. А Вы переправьте порт в настройках оборудования. В статье про установку драйвера PL2303 написано как это сделать.

  4. Вот решил насесть на это чудо инженерной мысли. Есть пара задумок. Так что штудирую ваши уроки. Большое вам спасибо за труд.

  5. Может я не разглядел. Хотелось бы увидеть работу встроенного аналогова компоратора.

    • Это не библиотека. Это псевдооператор, который присваивает константе MEASURE_PERIOD значение 500.

  6. Привет дорогой автор! Я собрал термометр как у вас и я хотел кое что спросить. как ускорить передачу данных датчика или сделать так чтобы индикатор обновлялся чаще чем одна секунда? У меня термометр меняет цифры через каждую секунду в зависимости от температуры, но хочу чтобы он обновлялся хотя бы раз в полсекунды. Что нужно сделать??

    • Здравствуйте!

      Попробуйте изменить время измерения в строке
      #define MEASURE_PERIOD 500 // время измерения, * 2 мс
      на 250. Это будет пол секунды.

      И еще надо изменить строку вычисления температуры
      temperature = ( avarageTemp * ADC_RESOLUTION / 500. — OFFSET ) / SCALE_FACTOR;

      на строку
      temperature = ( avarageTemp * ADC_RESOLUTION / 250. — OFFSET ) / SCALE_FACTOR;

    • А почему комментарий к статье об аналоговых датчиках.
      У DS18B20 время преобразования зависит от точности измерения. При максимальной точности оно составляет 750 мс. Увеличить частоту измерения можно только за счет уменьшения точности термометра.

  7. Доброго вечера! Что-то не работает у меня программа термометра. Нет обмена данными. При включении один раз виртуальный светодиод мигнёт, ему в такт на ардуино Леонардо желтый RX. И всё, горят синие прочерки. Вин-10, СОМ-3 свободен, там висит плата. При этом монитор порта выдаёт данные в окне исправно.

    • Здравствуйте!
      Посмотрите в комментариях к уроку 10. Там пишут:

      Наверное стоит упомянуть в тексте урока что указанная библиотека MsTimer2 не будет работать Mega2650. Я уж думал что начал косячить от бессоницы, полез искать оригинальные библиотеки — а там оказывается есть варианты. Для Atmega2560 или Teensy надо использовать FlexiTimer2. Скачать можно здесь: http://playground.arduino.cc/Main/FlexiTimer2

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *