Термометр на DS18B20 и Arduino Nano. Для дома и работы

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

*Откопал черновик из июня 2019-го — не выбрасывать же?

Контроллер —  Arduino Nano. Удобно и доступно, даже не побоюсь этого слова — «изподножно».

Датчики
— две микросхемы DS18B20. Заказчик хотел именно так, потому что одну можно прислонить к детали, а второй измерять температуру помещения. Или обеими снимать показания с разных точек детали, а потом вывести среднее. Измеряемый диапазон: -55…+125 градусов Цельсия — хватит и мороз в холодильнике проверить, и нагрев ноутбука. Датчики берут питание от выводов A0 и A2 — сначала так было удобнее на время тестов, а потом прижилось. Вообще их можно подключить к пяти вольтам и «земле».

Дисплей — первый попавшийся LCD 1602 с I2C-адаптером. Отображает показания каждого датчика и третью величину: среднее значение или разницу между ними.

N. B.! I2C-адаптеры собраны на микросхеме PCF8574 или PCF8574A. Они отличаются диапазоном адресов: по умолчанию 0x27 для PCF8574 и 0x3F для PCF8574A. Подойдёт любая — термометр сам выбирает между этими двумя адресами. Спасибо terog с «Пикабу» за код.

Вспомогательное — резистор 4,7 кОм (R1).

Дальше наши с Димоном устройства разделились. Он собрал термометр из пяти деталей, припаявшись проводами прямо к «Нане». Я нарисовал плату и добавил кнопку, чтобы переключать режимы «среднее/разница». Её «земля» так же включается на вывод A0, но можно и на «землю» схемы.


Печатную плату делал по размеру дисплея и его I2C-адаптера, но регулировочное отверстие под потенциометр всё равно немного не совпало.

Резисторы — 0805, перемычки — 1206, конденсаторы — 0805 и 1206. Диод в SMA-корпусе. Впрочем, они с micro-USB разъёмом оказались совсем лишними — я вывел наружу разъём, который включается в «Нану», чтобы можно было с ней общаться по UART.


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


Корпус оказался маловат — пришлось подпиливать плату напротив разъёма первого датчика и по-уродски выводить кабель до mini-USB штекера (он упирается в стенку, а провода под 90 градусов заворачивают вниз). На свободное место так и просится литиевый аккумулятор с зарядным устройством и «повышайкой». Димон по итогу так и сделал со своим термометром, я же питаюсь от USB.

Разъём питания и связи с ПК — M12 4-pin

Разъём для датчика — M12 3-pin

Кнопка с подсветкой — GQ12H

О работе прибора

N. B.! Гальваноразвязки, защиты от переполюсовки или превышения питающего напряжения нет. Одна моя «Нана» уже вкусила 24 вольта по входному разъёму, и больше температуру не измеряла.


При включении термометр мигает светодиодом в кнопке, показывая пользователю, сколько датчиков подключено. Два мигания — два датчика. Одно — работа с одним датчиком по упрощённому алгоритму, без вывода среднего значения или разницы. Нет датчиков — индикатор светится постоянно, а на дисплее висит надпись «Подключи и перезагрузи». Все стыковки-расстыковки надо делать на выключенном устройстве — программа не поддерживает горячей замены датчиков. Это происходит потому, что у каждой DS18B20 есть уникальный серийный номер. Термометр ищет датчики только при включении, а затем сортирует их по возрастанию номеров. Поэтому неважно, какой датчик в какой из двух разъёмов подключать — первым будет всегда более ранний серийный номер. Я своим сделал пометки красной и зелёной «термоусадкой», и уже знаю, что первый — это красный.

Дисплей, помимо температуры с обоих датчиков, показывает среднее их значение или разницу. Режимы «среднее/дельта» переключаются умеренно долгим нажатием кнопки, а очень долгое нажатие включает-выключает подсветку дисплея. Может быть полезно, если надо оставить термометр на ночь, но не хочется, чтобы он светил в глаза.


Ещё термометр отправляет в COM-порт температуру по каждому датчику, среднюю и разницу. Причём его можно подключить не только к компьютеру, но и к телефону — через OTG-кабель.

Сфера применения устройства довольно широка:

  • узнать нагрев микросхемы очередной «понижайки» с Алиэкспресса;
  • проверить точность термометра-гигрометра с «Алиэкспресса»;
  • убедиться, что холодильник на съёмной квартире приказал долго жить, и внутри постоянно плюс девять;
  • узнать, какую температуру даёт строительный фен на минимальном положении регулятора;
  • подключить герметичный датчик на основе DS18B20, чтобы измерять температуру воды в детской ванне;
  • многое, многое другое.

Дополнение от 31.10.20


Немного обновил прошивку: кнопка больше не тупит, поэтому режимы «среднее/дельта» переключаются по короткому нажатию. Индикаторы датчиков сделал более наглядными. В скетче появилась закомментированная строка:

//#define REQUEST_PERIOD 2000

С её помощью задаётся период опроса датчиков и вывода температуры на экран и в UART. Когда строка закомментирована, то период определяется библиотечным минимумом 750 мс. Если вам не хочется, чтобы цифры часто мельтешили, ставьте 2000 или 5000 мс.

В архиве к тому же лежат уже скомпилированные файлы .hex, которые можно скормить ISP-программатору.

Скетч и прошивки в .hex

Печатная плата в формате .lay6

Запись опубликована в рубрике Arduino, Печатные платы, Электроника. Добавьте в закладки постоянную ссылку.

21 отзыв на “Термометр на DS18B20 и Arduino Nano. Для дома и работы

  1. R3R:

    А точно нет ошибки в скетче? У меня ide ругалось на lcd.begin поменял на lcd.inst проверку прошло.

    • Спасибо, что обратили внимание. Я тоже ловил этот глюк, и так же решал его заменой lcd.begin() на lcd.init(). Возможно, за это время библиотека обновилась, и дисплей уже инициализируется иначе, или я с самого начала скачал библиотеку с другой реализацией, а потом уже добавил ссылку.

  2. R3R:

    Кстати, а не думали несколько изменить скетч, вместе с показаниями датчиков, справа отображать время работы термометра. То есть с кнопки добавить возможность переключения на время/средние показания и дэльту?

    • Можно и время добавить, но у меня такой задачи не было. Хотя в целом ваша мысль мне понятна: засекать, за сколько минут тот же холодильник выйдет на режим. Тогда уже удобнее не аптайм, а секундомер с возможностью паузы и сброса делать. Мне нравится DS3231, она бы в таком применении хорошо прижилась — компактно. Но пока что улучшать термометр нет надобности, а модернизация с литиевой батареей, её зарядником и компактной двухсторонней платой так лежит в списке проектов, за которые лень браться.

      • R3R:

        Да я хочу ваш термометр использовать для самогоноварения) Меня просто стандартные щупы с аппаратом не сильно устраивают. Видел системы авторизации, но для меня пока что они излишние. Время мне нужно, чтобы просто для себя засекать, сколько часов ушло на один и второй перегон, то есть нужно как раз время работы в часах и минутах. А так же надо в идеале глянуть, как прикрутить возможность контроля температуры, было бы супер добавить сигнализацию при изменение температуры на 0.1С. То есть надо подумать как прописать алерт, с возможностью его вкл/выкл и настройкой. На первом перегоне он не нужен, только на дробном.

      • Здорово, так его ещё не использовали :D

        Не уверен, что для точности 0,1 градуса DS18B20 будет хорошим решением. Несмотря на разрешение 0,0625 градуса в 12-битном режиме, у неё по паспорту точность 0,5 градуса. Может, для вашей более высокой точности надо поискать и более точные измерители.

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

        Насчёт часов — наверное, даже лучше прикрутить дисплей 2004. По скетчу изменения минимальные, зато не надо переключаться между экранами: можно выводить два датчика, дельта/среднее и часы одновременно. А, ну и при желании термометр можно масштабировать — добавить дополнительных датчиков в параллель к существующим, и по аналогии прописать их в скетче.

      • R3R:

        И снова здравствуйте) Решился на добавление ещё пары датчиков с выводом их показаний вместо среднего значения и дельты, хотел у вас уточнить пару моментов, а именно в самом начале скетча область с байтами за что отвечает, там где 1 и 2. А так же есть ещё 2 вопроса) Какая область скетча отвечает за переключение информации на экране, в будущем хочу сделать несколько страниц и с помощью кнопки/энкодера осуществлять навигацию по ним, а так же, не подскажите как осуществить алгоритм работы с заданием максимальной температуры, то есть например я выставил 78° на одном из датчиков, мне необходимо чтобы при превышение на 0.2° происходила сигнализация на зумер.

      • 1. Область с байтами — это нестандартные символы для дисплея. Мой не может в кириллицу, поэтому byte D[8], byte L[8] и byte soft[8] задают очертания букв «Д», «Л» и «Ь». byte one[8] и byte two[8] — изображения единицы и двойки в квадратике. Потом я передаю значения этих переменных в модуль инициализации дисплея: lcd.createChar(0, D) — во внутренней памяти дисплея под нулевым номером появится мой символ в виде буквы «Д». Последний шаг — вывожу на дисплей букву «Д» в нужном месте: lcd.printByte(0). Всего дисплей поддерживает до восьми пользовательских символов; удобная рисовалка. Можете в этом же стиле нарисовать 3 и 4 в квадратиках.

        2. Переключение информации — файл display.h, ищите конструкцию switch (mode). В режиме 0 показывает среднее, в режиме 1 — дельту. Функции draw_mean() и draw_delta() описаны в начале этого же файла. Можете написать свои функции и переключать их этим же switch(mode). Сама же переменная mode увеличивается на единицу по клику кнопки, смотрите if (butt1.isClick()) в файле button.h. У меня два режима, поэтому if (mode > 1) mode = 0. Так я закольцовываю «пункты меню».

        3. У вас в файле daq.h есть переменные tempC1 и tempC2, плюс наверняка вы разобрались, как добавить больше датчиков. Значит, в этом же файле можно дописать отдельную функцию типа

        if (tempC1 - 78 > 0.2) digitalWrite (13, HIGH);
        else if (tempC1 - 78 <= 0.2) digitalWrite (13, LOW);

        Это самая простая логика опроса одного датчика с сигнализацией на 13-м выводе (не забудьте ему прописать pinMode(13, OUTPUT)). Если ещё немного постараться, то можно дописать таймер, чтобы сигнал срабатывал, если температура выше уставки в течение 5 секунд — чтобы вас помехи не задалбывали, например.

  3. R3R:

    О да у меня стандартные щупы имеют большую погрешность) Мне больше важна динамика роста, чтобы она была достаточно точной и с нормальной скоростью. Щупы представляют из себя термопары и температура на них достаточно медленно изменяется. Сейчас собрал ваш термометр на макетке, в целом меня устраивает как на нем изменяются показания, если сравнивать со стандартными щупами, то ds18b20 раз в 10 минимум быстрее измеряют). По экрану, у меня как раз 2004. Надо будет сегодня скетч поковырять) на предмет добавления времени работы.

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

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

      Этот термометр отключаться не будет: гоняем на работе по восемь часов уже почти два года. Может, ещё допилю прошивку, чтобы при обрыве датчика не -127 показывал, а писал ERROR.

      • R3R:

        У меня на термопаре не одно устройство есть) Там есть свои плюсы, в том что они могут измерять достаточно высокие температуры, но у всех них есть недостаток, в том что температура на них достаточно медленно растёт. Например ту же теплопроводность/теплорассеиваемость очень проблемно посчитать. Опять же минус ещё в том, что у стандартных щупов площадь контакта маловата. А готовые китайские с резьбой имеют достаточно высокую погрешность из-за пустотелого исполнения, на удивление у тех термометров что шли с самогонным аппаратом, термопара имеет весьма не плохой контакт на металлический зонд. А по поводу error, там же вроде надо только одну строчку кода поменять!?

      • Это да, тип К — до плюс тысячи. Терморезистор или DS-ка так не сумеет.

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

        Я думал дописать что-то типа:
        if ("измеренная температура с датчика N" == -127)
        {
        lcd.setCursor(столбец, строка);
        lcd.print ("ERROR");
        }

  4. R3R:

    А так, при точности измерения в самогоноварение, она нужна больше в автоматическом режиме, и то там каждый раз надо делать коррекцию на давление. Много раз обращал внимание на то, что температура стабилизации в колонне, каждый раз разная. Когда то 78°, иногда 79°, а может быть и 80°. Главное успевать отслеживать динамику роста и уменьшать мощность в кубе или добавлять воду в дефлегматор. Плюс меня бесит, что стандартные щупы постоянно отключаются) и за перегон приходится их раз 5 включать.

  5. R3R:

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

    • В скетче *.ino подключаем библиотеку под 2004:
      #include
      LiquidCrystal_I2C lcd(0x27, 20, 4);

      В инклюде display.h всё отображение. Для отображения времени я бы написал отдельную функцию и вызывал бы в loop(), для дополнительных датчиков задействовал бы draw_display() и там бы дописал по аналогии.

      Как писать в 3-ю и 4-ю строки:

      lcd.setCursor(0, 2);
      lcd.print("3 stroka");
      lcd.setCursor(0, 3);
      lcd.print("4 stroka");

      Не забывайте зарисовывать информацию, которой больше нет. Скажем, чтобы перейти от значения на дисплее «100» к «99», я на месте единицы рисую пробел: " 99".

      • R3R:

        Понял, спасибо. Буду ковырять) Хочу ещё добавить один датчик, bmp280. Вывести с него на 4ю строку показания давления и температуры в помещении. Потом думаю попытать удачу сделать карту с эталонными значениями, для более оптимальной настройки пид регулятора.

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

        Думаю, вам удобнее написать в инклюде дисплея отдельную функцию, которая будет эксклюзивно писать в 4-ю строку данные с этого датчика. Я люблю всё разбивать по функциям, потому как если что не работает — последовательно можно закомментировать кусок кода, чтобы отдельно проверить кнопку, дисплей, опрос датчиков, вывод в порт и так далее.

      • R3R:

        Таки ура) Сделал вывод времени работы и оно нормально показывает. Пришлось правда в периоде опроса старт тайма изменить с миллис на микрос. А миллис использовал для подсчета времени.

      • Отлично! Допилили термометр под свои нужды.

        Период опроса срабатывает, если раскомментирована строчка //#define REQUEST_PERIOD 2000.
        В противном случае участок кода
        #ifdef REQUEST_PERIOD
        current_time = (millis() - start_time);
        if (current_time > REQUEST_PERIOD)
        {
        start_time = millis();
        #endif

        просто игнорируется компилятором, а DS-ки опрашиваются с максимально возможной скоростью.

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

  6. Иван:

    Добрый день, сколько будет стоить термометр с тремя датчиками, длина проводов датчиков не менее 2 м?

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s