Главная » Статьи » Как подключить

Работа с датчиком температуры DS18b20. Делаем термометр

  Для измерения температуры в бытовых целях хорошо подходят цифровые датчики DS18B20. Эти датчики способны измерять температуру в пределах от -55 до 125 °C, с заявленной точностью от производителя в 0,5 °C. Для большинства гражданских нужд такой диапазон и такая точность измерения вполне приемлема (какую-нибудь систему термоконтроля собрать или еще чего). Поэтому решил попрактиковаться с этим датчиком, обязательно пригодится.


 Работает датчик по однопроводному интерфейсу 1-Wire. Здесь я описывать этот протокол не буду, так как информации и так достаточно. Отличное описание работы интерфейса 1-wire и методика работы с датчиком ds18b20 можно почитать на http://samou4ka.net/
 
 Для нас самое важное, что нужно знать на первом этапе лишь то, что сигнальный провод необходимо подтягивать к шине питания подтягивающим резистором номиналом примерно 4,7к. Если длина сигнального провода увеличивается, необходимо снижать сопротивление подтягивающего резистора. Читал о том, что датчик соединяли с МК проводом длинной 90 метров, для исправной работы датчика сопротивление резистора составило 3к. 

  У себя для освоения работы с датчиком использовал микроконтроллер Atmega32 и выводил показания на двухстрочный алфавитно-цифровой ЖКИ. 

  Что касается программной части, в Bascom-AVR имеется библиотека работы с протоколом 1-Wire. Ее и задействуем. В программе полученные результаты с датчика немного корректируются, иначе при отрицательных температурах результат будет ложным на 1 градус, и нулевая температура выводится без знака.



$regfile = "m32def.dat"
$crystal = 1000000          ' 1 MHz


 '*** Конфигурируем ЖКИ
Config Lcd = 16 * 2
Config Lcdpin = Pin, Rs=Portc.5, E=Portc.4, Db4=Portc.0, Db5=Portc.1, Db6=Portc.2, Db7 = Portc.3

 ' ***Конфигурируем однопроводную шину

Config 1wire = Portb.7

 ' *** Заводим переменные

Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Sign As String * 1
Dim T As Byte
Dim T1 As Byte
Dim T2 As Byte


Cls
Cursor Off

 
 '***ОСНОВНАЯ ПРОГРАММА

Do                         ' начало цикла

1wreset

If Err = 1 Then            'если при опросе небыло ответа ставим флаг ошибки

Cls

Rem датчик
Rem не подключен
Lcd " гaїАёє "             ' выводим надпись об отсутствии датчика
Locate 2 , 1
Lcd " Ѕe ѕoгє»ЖАeЅ"

Wait 1

Else                       ' иначе, если ошибки не было, продолжаем опрос датчика

1wwrite &HCC               ' Выдаем команду чтения ПЗУ
1wwrite &H44               ' Запуск измерения

Waitms 750                 ' Ждем окончания преобразования

1wreset
1wwrite &HCC
1wwrite &HBE               ' Команда чтения ОЗУ датчика


Byte0 = 1wread()           ' Читаем нулевой байт

Byte1 = 1wread()           ' Читаем первый байт

If Byte1 > 248 Then        ' Проверка на отрицательность температуры
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Sign = "-"

Else
Sign = "+"
End If

T1 = Byte0 / 16           ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16           ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)

T1 = T1 + T2              ' Формируем результат для вывода на дисплей


 ' *** Коррекция полученных значений

If Sign = "-" Then        ' для корректного вывода отрицательных температур
 T1 = T1 + 1
End If

If Sign = "+" And T1 = 0 Then     ' убираем знак "+" с нулевой температуры
 Sign = " "
End If

Cls

' *** Выводим результат на дисплей

Rem Температура
Lcd " Teјѕepaїypa"                ' тут пишем что измеряем

Locate 2 , 6
Lcd Sign ; T1 ;                   ' выводим знак и температуру на дисплей
Locate 2 , 9

Lcd Chr(223) ; "C"                ' Сhr(223) - символ "градус"

Cursor Off

End If

Wait 1                            ' ждем 1 секундy

Loop                              ' повторяем цикл

End


  Датчик не подключен, выводится соответствующее сообщение:


  А это с подключенным датчиком, при комнатной температуре:


Ниже можете скачать исходник, файл в протеусе и откомпилированный файл:

Скачать
Категория: Как подключить | Добавлено: 13.03.2011
Просмотров: 26803 | Комментарии: 35 | Теги: 18b20, датчик, ЖКИ, 1-Wire | Рейтинг: 4.8/5
Всего комментариев: 351 2 »
35 exersizze   (17.07.2012 13:11)
Протеус всего лишь симулятор, со своими упрощениями и косяками. Поэтому проверять работоспособность схем нужно только в железе.

34 MC_Zver   (17.07.2012 12:15)
Частоту менял в программе и, соответственно, в протеусе при значении $crystal = 8000000 ну вообщем больше 1Mhz уже не правильно считает :'( Кстати вариант на семисегментных индикаторах тоже в моем протеусе не заработал :(

33 exersizze   (17.07.2012 11:42)
Частоту в программе менять не забыли? Все остально сделает компилятор. У меня таких проблем не было ниразу.

32 MC_Zver   (17.07.2012 11:00)
Добрый день, такая проблема при поднятии частоты процессора считываются ошибочные показания датчика. В протеусе значение переменных при частоте 4Mhz удваиваются, а при 8Mhz даже страшно смотреть :) и часто датчик при 8Mhz просто отдает код ошибки :( зависят ли тайминги ожидания результатов от частоты процессора ?
PS. Даже на вашем примере такая засада :( может протеус косячит ?

31 casino777   (11.04.2012 13:21)
спасибо всем, кто помогал. Проблема была в датчике, заменил на новый и всё тип-топ

+1   Спам
30 pchela5   (10.04.2012 21:21)
попробуй перекомпилировать и прошить на 8

29 casino777   (10.04.2012 19:40)
тоже сначала думал фьюзы но стоят правильно на 1 МГц

+1   Спам
28 pchela5   (10.04.2012 19:13)
Резистор маловероятно. Проверь фьюзы перво-наперво. У меня такое было. А датчик я спалил, когда пытался его всунуть, в грузовой автомобиль недалеко от ВВ-проводов. Контроллер был защищен, а датчик - нет - вылетел сразу-же.

27 casino777   (10.04.2012 18:48)
появляется

Rem датчик
Rem не подключен
Lcd " Datchik " ' выводим надпись об отсутствии датчика
Locate 2 , 1
Lcd " Ne wkluchen"

Резистор 4,7к покупал, завтра съезжу еще возьму

+1   Спам
26 exersizze   (10.04.2012 11:13)
от перегрева его можно убить но те так просто, что появляется на дисплее и резистор точно 4,7к?

25 casino777   (10.04.2012 11:03)
не работает (
вроде датчик правильно через резистор подключаю.
Может я его спалил когда провода припаивал?

+1   Спам
24 kip96   (07.03.2012 21:26)
В Баскоме это очень просто! Попробуйте немного изменить программу:
переменные:
Dim I1 As Integer , Ss As String * 6
вместо
Byte0 = 1wread()
Byte1 = 1wread()
пишем- I1 = 1wread(2)
и преобразуем
I1 = I1 * 10
I1 = I1 \ 16
Ss = Str(i1)
Ss = Format(ss , " 0.0")
дальше выводим на экран

23 exersizze   (07.03.2012 17:17)
royal33917, посмотри этот топик, там есть исходник для термометра с выводом десятых долей градуса
http://bascomavr.3bb.ru/viewtopic.php?id=169#p1207

22 royal33917   (06.03.2012 17:04)
так и не понял как вычитывать десятые доли градуса. понятно что информация находится в первых 4х битах младшего байта а как ими воспользоваться так и не понял...подскажите пожайлуста . Спасибо

21 exersizze   (27.01.2012 00:22)
ок, получил

20 4ester   (26.01.2012 21:51)
вообщем таки разобрался я с этим вопросом, если нужно могу скинуть вам исходник чтоб на основе него сделать статью если конечно хотите.

+1   Спам
19 4ester   (25.01.2012 10:22)
Надо будет подробней разобраться с этим делом и вывести в отдельный пост.
Было бы не плохо, и думаю многие были бы благодарны.

18 exersizze   (24.01.2012 21:04)
с динамической индикацией есть свои особенности, как вы правильно подметили во время ожидания ответа от датчика останавливается и индикация.
Вот тут есть пример как организовать совместную работу датчика с семисегментниками http://avrproject.ru/publ....-1-0-29

17 Алексей_bird   (24.01.2012 20:18)
Отличное описание работы датчика, но я пытаюсь использовать семисегментный индикатор, например взяты отсюда: http://avrproject.ru/index....-17 . Так вот когда нет кода датчика, особенно той части где задержка 750 мс, то индикация работает приемлемо, а как добавляю, возникает ооочень сильная задержка. Видимо индикацию надо организовывать по другому?

16 exersizze   (17.01.2012 01:37)
Удалось проверить приведенный код с двумя датчиками, исходник целиком под мегу8

Code
$regfile = "m8def.dat"
$crystal = 8000000

Config 1wire = Portd.7

Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
Config Lcd = 16 * 2
Cursor Off
Cls
Lcd "dual ds18b20"
Wait 5

Cls

     Dim Signtemperatura As String * 1 , Celsium As String * 5
     Dim Byte0 As Byte , Byte1 As Byte , T As Byte
     Dim Dsid1(8) As Byte , Dsid2(8) As Byte
     Dim Temp As Byte , X As Byte
     Dim W As Word

     W = 1wirecount()
     Dsid1(1) = 1wsearchfirst()
     Do
     Dsid2(1) = 1wsearchnext()
     Loop Until Err = 1

     Do

     Gosub Convallt
     1wverify Dsid1(1) : X = 1 : Gosub Temperature
     1wverify Dsid2(1) : X = 2 : Gosub Temperature
     Waitms 300

     Loop

     End

     Convallt:
     1wreset
     1wwrite &HCC
     1wwrite &H44
     Waitms 750
     Return

     Temperature:
     If Err = 0 Then
     1wwrite &HBE
     Byte0 = 1wread()
     Byte1 = 1wread()
     If Byte1 >= 248 Then
     Byte0 = &HFF - Byte0
     Byte1 = &HFF - Byte1
     Signtemperatura = "-"
     Else
     Signtemperatura = "+"
     End If
     Temp = Byte0 / 16
     T = Byte1 * 16
     Temp = Temp + T
     Celsium = Signtemperatura + Str(temp) + "C"
     Locate X , 1
     Lcd Celsium
     End If
     Return




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

15 4ester   (14.01.2012 01:44)
спасибо как сделаю отпишушь

+1   Спам
14 exersizze   (13.01.2012 18:30)
вот есть у меня код подключения двух датчиков к меге
Code
$regfile = "m8def.dat"    
$crystal = 1000000    

$lib "lcd4.lbx"    

Config 1wire = Portd.0    
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.2 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 20 * 4     
Cursor Off    
Cls    

Dim Signtemperatura As String * 1 , Celsium As String * 5    
Dim Byte0 As Byte , Byte1 As Byte , T As Byte    
Dim Dsid1(8) As Byte , Dsid2(8) As Byte    
Dim Temp As Byte , X As Byte    
Dim W As Word    

W = 1wirecount()    
Dsid1(1) = 1wsearchfirst()    
Do    
Dsid2(1) = 1wsearchnext()    
Loop Until Err = 1    

Do    

Gosub Convallt    
1wverify Dsid1(1) : X = 1 : Gosub Temperature    
1wverify Dsid2(1) : X = 2 : Gosub Temperature    
Loop    

End    

Convallt:    
1wreset    
1wwrite    
&HCC    
1wwrite &H44
Waitms 750    
Return    

Temperature:    
If Err = 0 Then    
1wwrite &HBE
Byte0 = 1wread()    
Byte1 = 1wread()
If Byte1 >= 248    
Then    
Byte0 = &HFF - Byte0    
Byte1 = &HFF - Byte1    
Signtemperatura = "-"    
Else    
Signtemperatura = "+"    
End If    
Temp = Byte0 / 16    
T = Byte1 * 16    
Temp = Temp + T    
Celsium = Signtemperatura + Str(temp) + "C"    
Locate X , 1
Lcd Celsium    
End If    
Return

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

13 4ester   (13.01.2012 10:36)
в процессе попытки написания своей первой программы возник такой вопрос с этим

1wreset
If Err = 1 Then

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

12 4ester   (03.01.2012 18:57)
спасибо

11 exersizze   (03.01.2012 16:10)
Вот глянь исходник, там все просто

10 4ester   (03.01.2012 00:59)
если не трудно не могли бы вы объяснить как считывать температуру с десятками то есть к примеру +15,5?

+1   Спам
9 exersizze   (27.10.2011 12:26)
Спасибо! Так намного ловчее!


+2   Спам
8 amv2000   (26.10.2011 22:12)
Для отображения кириллицы в протеус надо файл LCDALPHA.DLL
брал здесь http://www.picbasic.ru/_fr/1/LCDALPHA.dll заменяете тот что в протеус, или помещате в папку с проектом

7 exersizze   (26.10.2011 21:34)
Ну отлично, советую не останавливаться на достигнутом. У меги16 большой потенциал, можно не только температуру мерять)

6 Lex51   (26.10.2011 15:07)
Спасибо! Перекомпилировал под Мегу16. Заработало сразу!

1-30 31-35
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]





авторизация
Логин:
Пароль:


Комментарии
Вывод текста на экран телевизора с помощью MAX7456
24.10.2014 - sany2:
Polle ,Вы писали:
маленькую прогу для вывода на монитор одного слова с по...
Вывод текста на экран телевизора с помощью MAX7456
23.10.2014 - Polle:
я и не говорю что без подпрограмм, просто распишите по подробней что делает кажд...
Вывод текста на экран телевизора с помощью MAX7456
23.10.2014 - sany2:
Здесь без подпрограмм не обойтись.Вам видимо надо обратиться к тому ,кто пишет н...
Вывод текста на экран телевизора с помощью MAX7456
23.10.2014 - Polle:
Videotext это целая подпрограмма, а мне надо без констант и подпрограмм, что име...
Ультразвуковой дальномер HC-SR04
23.10.2014 - pv_serg:
Собрал-работает. Только хотелось предупредить, у кого не верно показывает и т.д....
Вывод текста на экран телевизора с помощью MAX7456
22.10.2014 - sany2:
Да вообще-то собственно наипростейшая прога здесь уже есть.
строка:
...
Часы-будильник по мотивам "необычных часов"
22.10.2014 - Scorpushka:
запустил такой дисплей, не совсем понятно, откуда берутся координаты от сенсора,...
Вывод текста на экран телевизора с помощью MAX7456
22.10.2014 - Polle:
Помогите пожалуйста разобраться с MAX7456. PDF на английском, а на BASCOM-AVR пр...
Контроллер лабораторного блока питания
18.10.2014 - Dmitriy:
Замечательный контроллер, все отлично заработало настройку произвел на двадцатис...