Термометр на ATTINY2313+DS18B20 доработанный

AVR
Недавно занимался сборкой компьютера с полностью пассивным охлаждением. Чтобы было удобно контролировать температуру процессора, нужно было по быстрому собрать термометр. Всяческие программы типа «Everest», «Aida», и прочие мне не подходили по одной простой причине: хотелось контролировать температуру даже при выключенном мониторе. Или даже при полностью отключенном мониторе. Было решено собрать термометр на основе цифрового датчика DS18B20, дешёвого микроконтроллера AVR, и семисегментного индикатора. Сначала я хотел повторить схему термометра по одному из вариантов, предложенных в интернете. Но после анализа схем, размещённых в интернете, я пришёл к выводу, что придётся изобретать свой «велосипед».

Конструкции, представленные в интернете, имели ряд недостатков, а именно:
* низкая скорость динамической индикации (50...100 герц), изза которой становится некомфортно смотреть на индикатор, если быстро бросить на него взгляд, кажется что цифры «шевелятся»;
* не все конструкции адекватно измеряли весь диапазон температур (от -55 до +125), попадались например конструкции, не измеряющие температуру ниже нуля градусов, или некорректно измеряющие температуру выше 100 градусов;
* отсутствовала проверка контрольной суммы (CRC);
* общие выводы сегментов подключались к одной ножке микроконтроллера без ключевых транзисторов, ПЕРЕГРУЖАЯ ПОРТЫ МИКРОКОНТРОЛЛЕРА.



При перегрузке портов МК, яркость свечения индикатора может снизиться, а также можно пожечь ножки микроконтроллера. Несколько лет назад я собирал термометр на ATtiny2313+DS18B20 по схеме с интернета. Схема была без ключевых транзисторов. При температуре 18 градусов, цифра «1» светилась ярко, а цифра «8» светилась заметно тусклее, надеюсь всем понятно почему всё происходит именно так. Поэтому я пообещал себе в будущем не перегружать ножки МК. Вот кстати фотка того термометра, собранного по схеме из инета, думаю что в комментариях не нуждается:



Также хотелось сделать несколько доработок:
* вывести на индикатор символ градуса (десятые доли градуса мне были не так критичны);
* затактировать микроконтроллер от внешнего кварца, так как протокол «1-Wire», который использует датчик, критичен к формированию временнЫх интервалов (тайм-слотов), поэтому молиться о стабильности встроенного тактового генератора мне не хотелось;
* ввести в программу проверку контрольной суммы, при несовпадении контрольной суммы выводить на индикатор: «Crc»;
* добавить в схему диод (для защиты схемы от переполюсовки питания);
* при подаче питания в течении 1 секунды засветить все сегменты (так называемый тест сегментов).

Проект я написал в среде AVR Studio 5, функции работы с датчиком нашёл где-то в инете, а остальное переписал на свой лад, обильно снабдив комментраиями исходный код. В конце статьи есть ссылка на скачивание прошивки и исходника.

Семисегментный индикатор я использовал на 3 знакоместа, сегменты с общим анодом. Также в архиве (в конце статьи) есть прошивки под индикатор с общим катодом. Общие выводы сегментов я подключил сразу к двум выводам МК, соединённым параллельно. Таким образом, каждый общий вывод сегментного индикатора использует 2 ножки МК для повышения нагрузочной способности выводов.



Микроконтроллер я использовал ATtiny2313A (также можно использовать ATtiny2313 или ATtiny2313L), задействовал практически все свободные ножки (за исключением ножки сброса). Если собирать термометр на ATmega8, то можно соединять параллельно по 3 или по 4 ножки для повышения нагрузочной способности портов.

Схема девайса:



Прилагаю фотографии собранного термометра. Корпуса покачто нет, так как термометр будет встраиваться в корпус ПК.











Индикация.
Не подключен датчик температуры, либо короткое замыкание на линии данных:


Ошибка контрольной суммы (CRC):


Подключен датчик температуры, температура от -55 до -10 градусов:


Подключен датчик температуры, температура от -9 до -1 градуса:


Подключен датчик температуры, температура от 0 до 9 градусов:


Подключен датчик температуры, температура от 10 до 99 градусов:


Подключен датчик температуры, температура от 100 до 125 градусов:


Частота динамической индикации — несколько килогерц, благодаря чему мерцание на глаз не заметно даже при броском взгляде на индикатор.
Для желающих повторить конструкцию я скомпилировал несколько прошивок под разные кварцы: 4 МГц, 8 МГц, 10 МГц, 12 МГц, 16 МГц.
Также сделал прошивки под индикаторы с общим анодом (ОА), и с общим катодом (ОК). Все прошивки в архиве (см. ниже).

г.Вельск, Апрель 2014г.
P.S. Первоначально материал разместил тут.

UPD. Обновил прошивку. Мелкие исправления, мелкие плюшечки. Из основного — stdint типы данных, гибкая настройка ног под сегменты. Все изменения описаны в шапке исходника.
В связи с большим наплывом желающих выкинуть кварц из схемы, и не читающих зачем он в схеме нужен, отключил комментарии.
  • +8
  • 15 сентября 2014, 20:45
  • Zlodey
  • 4

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

RSS свернуть / развернуть
Даже с защитой от переполюсовки.
Красота!
0
  • avatar
  • dekar
  • 15 сентября 2014, 21:00
Мда, код просто атас… Модуль семисегментных индикаторов. Конечно, поделка может быть разовой, сделал и забыл. Но научитесь избавляться по возможности в своих программах от магических чисел. Модульность программ. Зато в следующий раз вы просто цепляете свою либу, правите пины МК, если требуется переменные, константы. И все. А так у вас сейчас сплошная простыня, в одном файле. И никакой возможности быстрой правки и добавления функционала.
+2
Ну так я и писал в стиле простыни. Устройство отладил и забыл. С другой стороны — ваш комментарий тоже по теме. Может на выходных поправлю чутка, добавлю дефайны для сегментов
0
Ну идея подключения общих катодов(анодов) на два (и более) порта МК не нова.
А за аккуратность исполнения однозначно +
0
Согласен, что идея не нова. В том проекте с радиокота:
-нет CRC
-нет кварца
-низкая скорость динамической индикации
-нет защиты от переполюсовки
-итд
0
А какие конкретно преимущества дало использование кварца в данном проекте?
0
см. комментарий 16 сентября 2014, 10:25
0
И что? Благородному дону «Calibrated internal RC Oscillator 8MHz» было недостаточно для этой поделки? Не верю ©
0
Надоело повторять. Изза высокой скорости динамической индикации (обновление всех сегментов более 1000 раз в секунду), тайминги DS18B20 затягиваются. Если ещё и поплывёт генератор, можем получить ошибку данных. Применение кварца снимает проблему нестабильности встроенного генератора.
Если вас устраивает обновление индикатора 20-50 раз/сек, и вам комфортно смотреть на такой индикатор, собирайте другие конструкции, коих в инете навалом.
0
1. Кварц в таком устройстве нужен как спойлер жигулю. Документация на ваш МК содержит информацию о -/+2% отклонении от номинальной частоты. Где вы видели в описании протокола 1-Wire допустимое отклонение временных интервалов меньше, чем -/+2%?
Это же какой отвратительный код нужен, чтобы при такой примитивной задаче не попадать в интервалы…
2. Кроме завышения частоты от мерцания индикаторов неплохо помогают изменение скважности и/или полупрозрачные крышки.
3. Если вас так напрягает «шевеление» цифр индикатора, можно было бы организовать даже статичное управление индикатором (2 разряда).
Замечание. Если рассматривать ваше устройство в контексте заявленного применения, то:
а) Если устройство ничем не управляет, то, наверняка, ваш ПК работает в допустимом диапазоне температур.
б) Тогда температура такого большого радиатора должна быть меньше чем 100 градусов. При условии нормального теплового режима процессора.
в) Тогда три разряда излишни, как и отрицательные температуры. А символ градуса и без МК можно реализовать.
В качестве адекватного ответа на этот комментарий предполагается:
1. Попробовать изменить скважность и уменьшить частоту. Рассказать читателям о результате.
2. Привести допустимые отклонения временных интервалов протокола 1-Wire.
0
1. Повторяюсь в третий раз, т.к. вы не читали комментарии. Временные интервалы 1W затягиваются, т.к. динамическая индикация шарашит постоянно!!! изза этого временные интервалы тайм-слотов немного увеличиваются!!!
2. С какой это стати изменение скважности влияло на частоту?? XD ппц бля, докатились. Крышки тоже не влияют на скорость переключения сегментов.
3. Имея 2 разряда, получается кастрированная версия термометра.
Замечание.
а, б) Совсем не обязательно использовать его совместно с компом. С его помощью, т.к. ОН ПОЛНОЦЕННЫЙ, МОЖНО ИЗМЕРЯТЬ ХОТЬ ЧЁ И ХОТЬ ГДЕ, В ДИАПАЗОНЕ -55...+125.
в) Изменение скважности — уменьшит яркость сегментов, при этом никак не повлияв на частоту переключения цифр. Я надеюсь, что вы знаете что такое скважность. По поводу интервалов 1W — ответил в (1)
+1
Вы пробовали быстро посмотреть на индикатор, который переключается 20-50 раз в секунду? Неужели не видите мерцания?? Тогда снимите такой индикатор на видеокамеру, возможно, цифры будут «весело скакать» на дисплее камеры. При динамической индикации более 1кГц, даже если быстро посмотреть на индикатор, мерцания не видно. При этом яркость индикатора не уменьшается. Если уж так придрались к кварцу, то при комнатной температуре — работает и на внутреннем генераторе. А уж если плату в -20 мороз вынести — фиг его знает. Поэтому поставил кварц, который 5 рублей стоит. Сильно я от этого не обеднел, пива пью больше :)
0
Спрошу исключительно из любопытства: зачем в ПК отрицательные температуры?
0
если уж делать, так полноценный девайс, а не кастрат
+2
нескромный вопрос — зачем кварц на 8 МГц? Встроенной тактовой не хватало?
0
Опять на индикацию выводится символ градуса, причём не всегда. Зачем? По мне, лучше полнее использовать возможности DS18B20. Кварц, в этой схеме, явно лишний.
Если бы была возможность программного определения (ОК или ОА) подключенного индикатора, 4-х разрядная ведущая по отношению к датчику индикация, паразитное питание датчика, то получился бы термометр. А так ..., ничего особенного.
0
  • avatar
  • akl
  • 16 сентября 2014, 08:31
1. Автор писал писал, что не будет перегружать ножки МК и все-таки поставит транзисторы. А что в итоге? В итоге имеем схему которая снова не содержит ни одного транзистора.
2. По схеме питание 5В, стоит диод, на котором упадет 0,7В. В итоге схема будет питаться 4,3В. А по факту на фото подключен аккум на 3,7В, после диода будет 3В. Я понимаю, что МК работает, но аккума хватит недолго, т.к. просадка напряжения батареи на 0,1В может стать критичной для устройства.
0
Диод- шоттки, на нём падает 0,3В примерно.
5 — 0,3 = 4,7В для питания — хватает.
При питании от заряженной батареи, соответственно 4,2 — 0,3 = 3,9В.
Аккум на фотке- исключительно для примера, питается всё это дело от USB компа.
Кварц — для стабильных таймингов, т.к. внутренний генератор плывёт от питания и температуры. Вообще в схемах, критичных ко временным интервалам, экономить на кварце — дурной тон.
+1
питается всё это дело от USB компа.
Там обычно чуть меньше 5В, 4.5-4.8.
Вообще в схемах, критичных ко временным интервалам, экономить на кварце — дурной тон.
Разве 1W так критичен к задержкам? У него же каждый бит синхронизируется, а запасы на тайминги — километровые. Сам датчик отрабатывает интервалы без всяких кварцев.
0
  • avatar
  • Vga
  • 16 сентября 2014, 10:10
Вчера замерял, 5.008 показывал китайский мультиметр. Не принципиально, будет работать и с напругой 4 В
Запасы километровые, согласен. Но не забываем что у меня ещё есть динамическая индикация выше килогерца. Думаете она не затягивает тайминги? Ещё как затягивает…
0
Влияние индикации таково, что разница между кварцем и внутренним генератором вообще исчезает. Эту проблему надо решать в софте — например, синхронизацией 1W с индикацией. Ну или реализацией 1W на уарте, тогда все критичные тайминги отработает железо.
0
  • avatar
  • Vga
  • 16 сентября 2014, 10:20
Согласен. Допустим, кварц плавает 7,5 — 8,5 МГц. Ввиду затяжки интервалов, схема оказывается работоспособна только в рамках 7,8 — 8,2 МГц.
Имея кварц, я стопудово попадаю в рабочий диапазон, т.к. имею железные 8 МГц.
Имея внутренний генератор, я молюсь что оно сегодня не уплывёт.
0
Не надо молиться, надо проектировать программу так, чтобы индикация не мешала обмену с термометром. И это вполне реализуемо.
Генератор там, ЕМНИП, не хуже 5% точность имеет. При подстройке его по опорной частоте на нем даже V-USB работает.
0
  • avatar
  • Vga
  • 16 сентября 2014, 21:23
Но эта же плата сделана без кварца, и ничего работает. Индикация вообще не видно что мигает. Как ни смотри, прямо или криво. Надо просто при методе стробирования переключать сегменты в прерывании какого либо аппаратного таймера микроконтроллера. И будет счастье.
0
Динамическая индикация ловится движением глаз — оно достаточно быстрое, чтобы обеспечить развертку картинки по сетчатке. 70Гц — без проблем, но несколько килогерц — перебор. Достаточно где-то герц от 200-400.
0
  • avatar
  • Vga
  • 16 сентября 2014, 21:50
50-200 Гц — вижу противное мерцание, если быстро бросать взгляд на индикатор. 1000 Гц — всё идеально во всех случайх, как ни крути
0
К счастью, меня и на 50Гц индикация не напрягает)
0
  • avatar
  • Vga
  • 16 сентября 2014, 22:30
ну тут частный случай, 50 Гц — кого то напрягает, кого то нет. 1000 Гц- не напрягает никого
+1
В большинстве подобных термометров «с инета», используется внутренний генератор, и медленная динамическая индикация, которая режет глаз
0
А зачем такая высокая частота? Достаточно обновлять индикатор с частой 60..70Гц, что бы даже при боковом взгляде не было видно мерцания.Так что частота тактовой выше 4МГц и не нужна, а это уменьшит изменение частоты при её дрейфе (в сравнении с 8 и 16) и не будет проблем с «затяжкой интервалов».

Если в программе есть задержка 100-500-1000 и более мс, стоит подумать о вводе контроллера в sleep(), даже если питание «халявное».

Зачем непрерывно опрашивать датчик, если температура инерционна и заметить изменение ранее чем 5-10 секунд (особенно охлаждение) невозможно. Тут тоже просится sleep().

Учитывая, что датчик подключен по 3-м проводам, нет смысла ждать «окончания температурного преобразования» впадая в задержку — можно проверять изменение ножки данных, а если её повесить на ножку с внешним прерыванием, то тогда вообще применение sleep() является де-факто.
+1
Та ну, если питание от USB, да ещё и потребление небольшое, зачем слип применять? Питание же не батарейное
0
Что бы эта и будущие программы выглядели и работали более профессионально, а не так как сейчас пишут почти всё ПО — весит гигабайты, жрёт в памяти гигабайты, а делает почти то же самое, что и версии несколько-летней давности, весом в десяток мегабайт… а, ну да, глянцевые иконки же
+1
Ну разве что ради этого- согласен. Только вот вопрос. Как динамическая индикация будет работать в режиме сна???
0
всё так же, только прерывание таймера будит контроллер, и в прерывании поднимаем флаг необходимости обновить показания. Затем в основной программе обработать этот флаг.

t0_int
{
    updateLCDflag=1;
}
.....
main
{
    ...
    while(1)
    {
        sleep();
        if(updateLCDflag)
        {
            //do LCD routines
            updateLCDflag=0;
        }
        else if(otherIntflag)
        {
            //do something
        }
    }

}

так же добавить счётчик, который инкрементируется каждое просыпание и в итоге раз в 5сек запускает опрос датчика.
0
так не прикольно. Самый экономичный режим Power Down — не получается, а режим Idle особо и не экономит ничего…
0
Не вижу тут критичности к интервалам, требующей применения кварца.
0
см. комментаий 16 сентября 2014, 10:25
0
>>>>и все-таки поставит транзисторы
А вот и нет, транзисторы я ставить не собирался. Перечитайте статью, там нет такого.
0
Схема была без ключевых транзисторов. При температуре 18 градусов, цифра «1» светилась ярко, а цифра «8» светилась заметно тусклее, надеюсь всем понятно почему всё происходит именно так. Поэтому я пообещал себе в будущем не перегружать ножки МК
Вот тут обещал не перегружать используя транзисторы в будущем.
Может это я читаю между строк, но действительно, игнорирование транзисторов в подобных схемах нежелательно.
+2
Про транзисторы в будущем я опять же не говорил. Я говорил что не буду перегружать ножки МК, что я и сделал. Распределил нагрузку на 2 ножки.
20 или 40 милиампер, поверьте, разница огромная. В даташите Absolute Maximum Ratings равен 40 мА.
Вы электролитический конденсатор, рассчитанный на 25В, включите в 25-вольтовую цепь? Я — нет. А вот в 12-вольтовую цепь — пожалуйста :)
0
Да как угодно соединяйте-параллельте, всё равно через 20 лапу при ОА будет течь весь ток; при ОК -через 10 лапу.
0
  • avatar
  • akl
  • 16 сентября 2014, 11:58
40 mA — максимальный ток через выходной транзистор. Ноги питания тут ваще причём??
-1
Ну, тогда Вас сюда
0
  • avatar
  • akl
  • 16 сентября 2014, 12:10
Для них же AMR миллиампер 200 или больше, не? Забавно что именно с внешними транзисторами можно вылететь за пределы по току через шины питания (8 сегментов по 20-30мА, итого 160-240мА через МК).
0
  • avatar
  • Vga
  • 16 сентября 2014, 21:26
8 сегментов по 5 мА не хотите?? из которых светятся далеко не все :)
0
Во первых, это в твоей конструкции 5мА (и она укладывается в AMR, да). Я же говорю в общем.
Во вторых, при расчете тока брать нужно худший случай.
0
  • avatar
  • Vga
  • 17 сентября 2014, 10:27
Впрочем, я не уверен, что у тебя там реально 5мА. Но и не более 10мА, что в принципе в AMR тоже укладывается.
0
  • avatar
  • Vga
  • 17 сентября 2014, 10:30
обычный светодиод, из которых собраны небольшие индикаторы, жрёт около 5 мА, 10-ти там точно нету
0
Жрет он столько, сколько ему дашь. С резистором 390 Ом ток там при питании 5В будет больше 5мА.
0
  • avatar
  • Vga
  • 17 сентября 2014, 13:42
Допустим, пусть будет ток 8 мА на сегмент, и светятся все 8 сегментов.
8 * 8 = 64мА
64мА / 2пина = 32мА
Максимум у нас 40 мА, такчто укладываемся :)
0
Но и не более 10мА, что в принципе в AMR тоже укладывается.
Тебе не кажется, что ты ломишься в открытую дверь?
0
  • avatar
  • Vga
  • 17 сентября 2014, 21:13
Не, фигню написал. Весь потребляемый ток будет идти через лапы питания. Посмотрел DS на ATtiny2313. 40мА\лапа, но не более 200 мА\лапы питания.
0
  • avatar
  • akl
  • 16 сентября 2014, 12:07
ахаха, я это узнал лет 5 назад :)
-1
Какой прелестный код)) Двухбайтовые digit1, digit2, digit3 безо всякого намека на атомарность направо и налево используются и в теле программы и в обработчике.
0
Старший байт всегда = 0. Да, кстати зачем-то я тип «int» поставил, когда можно было «char» обойтись. Поправлю, спасибо.
0
Лучше использовать stdint-типы. Стандартные char/int/etc сильно зависят от компилятора, а вот uint8_t — всегда беззнаковое восьмибитное целое.
+2
  • avatar
  • Vga
  • 16 сентября 2014, 21:28
ага, есть такая фича. Но при работе с AVR вродь как всё одинаково
0
Да, но вдруг я сейчас захочу по-быстрому перенести это на какой-нибудь stm. Было бы классно, если бы вы подумали о портабельности, когда это наиболее очевидно и просто. Иначе потом разбираться в деталях реализации сложнее.
+1
ок, переведу на stdint
0
Аккуратненько, да, нравится :)

А мне одному кажется, что со стороны монтажа и дорожек показана какая-то другая плата? Приглядитесь ;)
0
  • avatar
  • Ozze
  • 16 сентября 2014, 15:05
Не, не кажется :) Со стороны индикатора — первая версия платы, а со стороны дорожек- вторая исправленная. На первой плате диод защиты по питанию был «врезан» кое-как (боком), т.к. изначально он не был предусмотрен. Потом переделал плату, а сфоткать заново было лень :)
0
Няшечка) Аккуратно и красиво)
0
Вообще да. Тема с датчиком DS18B20 весьма популярна. Кстати я вот тоже недавно столкнулся с затеей сделать такой же измеритель. Тока решил сперва глянуть есть ли такой готовый. Оказывается есть. Вот такой. Только там добавлена одна фишка. Можно подробнее здесь почитать. Кстати там же можно купить датчик DS18B20 в обжатой гильзе и с проводом. Удобно, можно за окно датчик повесить и влага не страшна.


0
Кстати на Atmega8 сделан. Если что, то можно свою прошивку закатать туда, со своими функциями и пожеланиями.
0
десятые доли гредуса не имеют смысла, т.к. точность датчика +-0,5...1 градуса.
0
Интересно что согласно даташиту можно вывести и тысячные доли градуса. Зачем есть такая возможность, если такова точность?
0
Дискретность и погрешность — разные характеристики! Многие не читали даташит, и наивно думают что датчик имеет точность в тысячные доли градуса.
0
Кстати погрешность достигает 2 градусов в граничных пределах измерения.
0
точно, ошибся. Точность получается 0,5...2 градуса :)
0
У меня такой термометр на комнатной прибавляет 2 градуса, а если попытаться померять температуру тела, то более 32 не показывает, хотя, может торгаши китайское фуфло возят.
0
незнаю, с моими датчиками всё в порядке, и температуру тела показывают правильно
0
а если попытаться померять температуру тела, то более 32 не показывает
А где и как ты ее меряешь?
0
  • avatar
  • Vga
  • 16 сентября 2014, 22:55
ну если ладошкой греть, то 36 там точно не будет. Температура конечностей всегда ниже.
0
как и ртутным, можно под язык
0
Я собирался на этом датчике инкубатор сделать и перед выбором датчика погуглил вопрос. Говорят он может обеспечить точность 0,1 градуса, только его надо откалибровать для заданного диаппазона температур.
0
Ну и как получилось откалибровать?
0
Надо сначала эталон заиметь
0
Если иметь эталон, то тогда уж можно и на терморезисторе сделать, или на обычном диоде. Многие и отдают предпочтение этим датчикам только потому, что ожидают получить более-менее точный термометр с минимальным гемором, без калибровок, настроек и пр. плясок.
0
Имеется ввиду не сам датчик калибровать, а корректировать расчет температуры. А так же реже производить измерения, что бы небыло заморазогрева.
+1
Для примера есть Application Note 208: Curve Fitting the Error of a Bandgap-Based Digital Temperature Sensor.
Application Note 208
0
Тем не менее измерительные приборы обычно имеют разрешение выше, чем точность. И это нужно в некоторых случаях.
0
  • avatar
  • Vga
  • 16 сентября 2014, 21:32
А я вот не пойму почему на т.с. так накинулись. То транзисторы подавай, то кварц убирай. Комрад сделал девайс в точности с поставленным техническим заданием. Обосновал необходимые фишки. Указал на подводные камни. Проект заслуживает уважения.
+4
Не то чтоб я имел что-то против кварца, но когда 1-wire зависит от двухпроцентного отклонения частоты — это подозрительно.
0
  • avatar
  • Vga
  • 17 сентября 2014, 21:15
Спасибо за единственный адекватный комментарий. Просто купить кварц за 5 рублей у большинства религия не позволяет))
0
Автор топика запретил добавлять комментарии