Работа с датчиком температуры DS18B20


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Васил: Загрузчик для AVR микроконтроллеров
Ошибка #ifdef ST...

Алексей: Загрузчик для AVR микроконтроллеров
Да, есть такая фи...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


   
				

Работа с датчиком температуры DS18B20

	
	
	

Дата: 15 Мая 2014. Автор: Алексей

	
	
В библиотеке AXLIB есть набор функций для работы с данным датчиком.

Весна в полном разгаре. Скоро лето, жара. А жара это сколько? Надо померить. А как? Вот и решил я поработать с датчиком температуры DS18B20. Благо он дешевый и его можно купить где угодно. И еще под этот датчик в CVAVR есть библиотека. Но.... После ковыряния с этим датчиком и библиотекой от CVAVR я окончательно решил слезть с этой пакости. Я пол дня угробил на состыковку библиотечных функция с динамической индикацией. Все вроде работает нормально, но когда доходит до опроса датчика, то индикация спотыкается на секунду. Жуть!!! Короче пообщавшись с умными людьми на форуме, я залез внутрь библиотеки и нарыл тело функции чтения температуры и о чудо! Там за каким-то лешим после команды на старт преобразования стоит пауза на 550 мс. Зачем? Для тех кто все же останется преданным CVAVR, эту паузу можно стереть. Заработало немного быстрее. Еще остался вопрос, а где лежат функции для работы с шиной 1-wire? Только хедер и все. Просто возник еще вопрос. Если при динамической индикации использовать таймер и в прерывании выводить цифры, то фигня выходит. Терзают меня смутные сомнения, что при обработке функций шины 1-wire запрещаются прерывания. Короче мне эти непонятки надоели и я переехал на AVRStudio 6.1 и ни капли не сожалею. Ну и еще получил пинок для изучения принципа работы шины 1-wire.

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

Для начала определимся с планом действий. Задача: Один датчик, берем из него температуру и по необходимости выводим куда-нибудь. Алгоритм из мануала на датчик.


Теперь все по порядку.
Перед тем как начать рассказ о командах, давайте пробежимся по физике шины. У датчика есть три ноги, две для питания(возможна работа от паразитного питания, но о ней мы пока говорить не будем. Считаем что у нас есть полноценное питание и оно подведено к датчику). Третья нога как раз для передачи данных. Но тут есть свой нюанс. Просто дергать ногу верх и вниз нельзя. Между этой ножкой и плюсом питания стоит резистор на 4,7К, который подтягивает ногу к плюсу питания. То есть если мы шину не трогаем(нет передачи) то на линии висит плюс питания. Также надо запомнить, что все начала передач инициируем мастер. Датчик всегда сидит и нюхает шину, а как только там что-то появилось, отвечает.

Подаем команду сброса.
Для того чтобы подать команду сброса, нужно прижать линию данных к нулю и удержать в таком состоянии не менее 480 мкс. Потом просто отпустить линию. Тот резистор, о котором я говорил ранее, подтянет шину к плюсу питания. Далее после того как мы отпустили шину ждем 15 мкс и смотрим. Если шина упала к нулю и так продержалась не менее 60 мкс, то значит на шине висит датчик и он нам ответил " Я тут". Если на шине после выжидания 15 мкс ноль не появился, значит на шине кроме мастера никого больше нет. Вот и вся команда. Если на шине никого нет, то забиваем на все и занимаемся чем-нибудь другим, а вот если кто-то есть, а скорее всего наш датчик, то мы имеем полное право ему дать команду.

Следующая команда по очереди должна быть чтение РОМ кода. Что такое РОМ код. Это группа из 8 байтов которая несет в себе некую информацию, а именно: Младший байт содержит код семейства. В мануале написано что равен 0х28, но я почему-то получал 0х10. Следующие 6 байтов это идентификационный номер датчика. Как я понял он уникален или фирма выпустила больше 281474976710655 датчиков. Я даже не знаю как это число произнести)). И последний байт это CRC контрольная сумма предыдущих байт. Получить ее можно подав команду 0х33. Но тут тоже не все так просто. Команда 0х33 это запрос РОМ кода если датчик один, а чтоб выудить их из кучи датчиков, то нужно сказать 0хF0. Мудрено? Да... Но если вспомнить что мы хотим общаться с одним датчиком, то нам этот РОМ код ваще читать не надо. Но мануал требует обязательного чтения РОМ кода. Что делать? А вот что. Есть такая команда под названием "Гей хлопцы се кричим!". То есть пишем 0хСС. Это означает пропустить РОМ код и всем устройствам на шине принять команду. В научном мире это называется широковещательная передача. То есть не важно сколько там устройств на шине, следующая после 0хСС команда одресованна всем.

Замечательно, подготовили устройство к получению команды и оно напряглось. Что дальше. А дальше нам нужно сказать ему "А нука друг измерий ка мне температурку. И шлем ему код 0х44. Тот получив приказ, тут же подрывается на работу. Вопрос. А как узнать когда датчик измерил температуру? А просто. Пока он меряет, то прижимает шину к нулю. Отсюда мы нюхаем шину и как только получили единицей по носу, о! Измерил.

Получение температуры. Датчик туп как пробка. Получив приказ измерить температуру он это сделал и положил данные в память. А дальше выпучив глаза ждет очередной команды. Мы в ту же очередь, получив единицей по носу, говорим 0хВЕ. Датчик получив эту команду понимает что надо передать данные из памяти. А какие? Память датчика состоит из 9 байт. Первые два это температура. Потом два байта тревог по превышению верхнего или нижнего предела температуры.(некий термостат). Следующий байт это конфигурационный регистр. Ну мол как цифровать температуру. Далее три байта в резерве. И наконец последний CRC. Помним что это). Так вот при подачи команды 0хВЕ датчик не будет думать о том что надо передать, а просто вывалит все девять байт в шину. Но мы все получать не будем. Мы получим только первые два байта. Ведь мы работаем только с одним датчиком и нас интересует только температура. Получив первые два байта переходим к их дешифровке, а остальные байты пускай затеряются на шине.

Преобразование данных в человеческий вид. Получив два байта нам нужно сделать из них температуру. Ну для начала надо понять что температура бывает как положительной, так и отрицательной. А с учетом того что у нас два байта, то и выделять под переменную нам надо типа int. Далее вроде все просто. Младший байт в младший инта, а старший в старший. Да не все так просто. Я долго вкуривал в это безумие и так и не понял)) Но всеми известный научный метод тыка пока не кто не отменял. Короче берем старший байт и кладем его как есть в старший байт инта, а младший сначала умножаем на 5, а потом кладем в младший байт того же инта. Все, вот наша температура правда умноженная на 10. То есть если температура 23,5 гр. то в инте будет 235. А если температура отрицательная? Во подстава. Глядя в таблицу температур датчика я понял что ее передают в, как по научному вроде, обратной нотации что ли. Короче, после получения данных от датчика, нужно проверить старший бит у старшего байта на 0. Если ноль, значит плюс, а если единица, значит зима) А дальше склеиваем как плюсовую, а потом инвертируем каждый бит. То есть те что были нулями должны стать единицами, а единицы нулями. После прибавляем единицу и получаем температуру так сказать по модулю. Выводим как плюсовую, только не забываем поставить знак минус.

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

DS18B20 плюсовая температура

DS18B20 минусовая температура

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

В библиотеке AXLIB есть набор функций для работы с данным датчиком.

Архив с файлами.



jon    29.09.14

Алексей, вопрос - я могу с помощью команды читать ROM, определить наличие датчика? Скажем, выдать 0x33, и прочитать в первом байте код семейства DS18B20. Если он не равен 0x28 - значит, датчика нет. Или так не не годится?

Алексей    29.09.14

А чем не устраивает команда сброса? Или на шине еще что-то висит?

jon    30.09.14

Но, ведь по команде сброса можно только определить - есть ли любые устройства 1- wire или нет. А хотелось бы именно удостовериться в отсутствии термодатчика DS18B20. Есть чужой исходник на ассемблере на два термометра с батарейным питанием на разных шинах, захотелось кое-что переделать по своему вкусу. Лезть в сами процедуры работы с датчиком особо не хочется, вроде нормально и так работает. Поэтому и возникла идея - дать команду 0x33, потом принять первый байт из 8, и его проанализировать на наличие кода семейства. Типа, если там есть 0x28 -

Алексей    30.09.14

Хорошо. Если есть два датчика НО НА РАЗНЫХ шинах, то какая разница как определить наличие датчика. Подали команду сброса и все. Датчик ответил, значит все в порядке. Не ответил, увы. Команды на обнаружение по семейству нужно подавать только тогда, когда на шине висит больше одного датчика. А если один, то зачем такие сложности. Или я что-то не понимаю в вашем вопросе.

АНОНИМ    01.10.14

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

Алексей    01.10.14

Собственно, а почему нет. Если известен адрес датчика и он ответил на любую команду значит он априори жив и здоров.

jon    01.10.14

Меня как раз интересовал способ, при котором неизвестен адрес датчика, сидящего на отдельной шине. Зачем полностью читать все 64 бита идентификации, вполне хватит и 8-ми бит, в которых есть код семейства. Например, 0x28 для DS18B20. Если принят любой другой код - значит, датчика нет, он не тот, или неисправен, что в конкретном случае почти одинаково.

Алексей    01.10.14

Стоп, стоп, стоп. Это сработает при широковещательном запросе при условии только одного датчика на шине. С тем же успехом можно и команду сброса подать. Если будет больше устройств на шине, то на широковещательный запрос ответят все. Иначе по адресу. Ну это же логично. Если вы отправите письма с запросом нескольким людям, они все вам и ответят. А если просто одному человеку в комнате крикните, "Эй, ты!". Он один и ответит.

jon    01.10.14

Правильно, я и написал - "...датчика, сидящего на отдельной шине...". У меня как раз ситуация, когда каждый датчик термометра - сидит на отдельной шине. Именно поэтому и возник такой вопрос. И потом, стоит задача определения наличия именно DS18B20, мало ли что там народ еще может подключить. А так - датчик ответил кодом 0x28, значит все в порядке.

jon    01.10.14

Алексей, еще поясните такую вещь, если не трудно, а то что-то в даташите про это нигде не сказано. Я подал команду записать в датчик 0x33 (чтение ROM), затем должен сколько-то подождать, или могу сразу читать с датчика? Где-то в сети народ жаловался на то, что типа, пока не поставил между командами записи-чтения задержку около 1 миллисекунды - датчик не отзывался вовсе, или вывдавал всякую белиберду.

Алексей    01.10.14

А это зависит от дискретизации(точности) измерений. При запросе на вычисления температуры датчик может, зависать аж по моему до 750 мс. Давненько я с ним не работал не помню. Проще шину нюхать. Если после команды на преобразования шина в нуле, значит не готов. Как шина к поднялась к единице, можно читать температуру. С этой проблемой часто сталкиваются те кто выводит температуру на динамический индикатор.

jon    02.10.14

Когда нужна температура, задержка обычно подразумевается. Потому что делать поллинг (опрос бита готовности), не всегда удобно. А вот когда пишется команда, не связанная с преобразованием температуры? Например, та же 0x33 - чтение ROM.

Алексей    02.10.14

Ну я не знаю. Вообще задержка не нужна. Ради собственного удовлетворения то пару миллисекунд вляпать можно. Если это не дипломная работа, то я бы воспользовался импирикой и не парил себе мозг. :)

krokodandi    20.10.14

Есть желание немножко усложнить конструкцию? Я очень хочу поработать с вами вместе. Передо мной была поставлена интересная задача. Денежкой поделюсь. Жду ответа тут

Алексей    20.10.14

А по конкретнее какая задача. Точнее ТЗ.

Как-тотак    20.10.14

Нужно сделать два термометра МК1 и МК2. На мк1 навшано BT модуль HC-05, ds18b20,радио NRF24L01. На мк2 ds18b20,радио NRF24L01. ----------------мк1----------------- мк 1 измеряет temp_mk1 пишем в РОН инициируем подключение по радио NRF, если есть подключение, кидаем ему общую уставку Y и просим передать temp_mk2 c MK2 (пишем в POH) -инициируем подключение по БТ,если есть отправляем temp_mk1 и temp_mk2 и просим получить уставку Y(получаем и копируем в РОН) - считаем ошибку температуры мк1, если отрицательная включаем реле. -------------Мк2---------------- Измеряем температуру и пишем в РОН слушаем эфир NRF, если есть отправляем _температуру и просим уставку. Сравниваем, результат в ошибку. Если отрицательная, включаем реле. Это регулятор для фуры отца. Будет греть прицеп. Говорит, мол не обойтись. Платит мне 10К а я все нее могу с модулями и ассемблером разобраться. Нашел ваш терморегулятор. Разбираю ваш пример пока. Изложение мысли понравилось.

krokodandi    20.10.14

Такой регулятор...Как связаться с вами?

krokodandi    20.10.14

Отлаживаю на плате STK500 в связке с STK502. Примерную схему я набросал в ИГЛКАД Для связи могу предложить скайп. Мой логин : 819 готов отдать 7К

Алексей    20.10.14

Честно, я ничего не понял. avrki@avrki.ru моя почта. Можно более подробно и сформулировано объяснить что нужно сделать. И при чем здесь РОН? Обязательно на ассемблере? Какой МК рулить всем этим будет? Нужна конкретика, ТЗ. Напишите поверхностный псевдо-код, что должно происходить в течении работы устройства. На какой шине висят радио модуль и ВТ модуль. Зачем вообще ВТ? Связь с телефоном?




Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  








Вверх


Рейтинг@Mail.ru Яндекс.Метрика