Работа с датчиком температуры ds18b20 в bascom-avr
Работа с датчиком температуры DS18b20. Делаем термометр
Источник: http://AVRproject.ru/publ/kak_podkljuchit/termometr_na_ds18b20_mega32/2-1-0-15
Урок 12. Измерение температуры при помощи AVR. Простой термометр на AVR
Продолжаем осваивать периферию, на очереди измерение температуры. Рассмотрим вариант измерения, при помощи датчика температуры DS18b20.
Характеристики датчика: диапазон измерения от -55 до +125°С. Точность измерения ±0,5°С гарантируется в диапазоне от -10 до +85°С. Возможность измерения с разрешением 9, 10, 11 и 12 бит, т.е.
с шагом 0,5; 0,25; 0,125; 0,0625°С. Для обмена информацией с AVR микроконтроллером используется 1-Wire протокол.
Каждый датчик имеет свой уникальный адрес, поэтому имеется возможность посадить на шину сразу несколько датчиков.
Для сборки схемы понадобится жк дисплей, датчик и резистор на 4,7кОм. Теперь перейдем непосредственно к прошивке.
Для измерения температуры в бытовых целях хорошо подходят цифровые датчики DS18B20. Эти датчики способны измерять температуру в пределах от -55 до 125 °C, с заявленной точностью от производителя в 0,5 °C. Для большинства гражданских нужд такой диапазон и такая точность измерения вполне приемлема (какую-нибудь систему термоконтроля собрать или еще чего). Поэтому решил попрактиковаться с этим датчиком, обязательно пригодится. Работает датчик по однопроводному интерфейсу 1-Wire. Здесь я описывать этот протокол не буду, так как информации и так достаточно. Отличное описание работы интерфейса 1-wire и методика работы с датчиком ds18b20 можно почитать на http://samou4ka.net/ Для нас самое важное, что нужно знать на первом этапе лишь то, что сигнальный провод необходимо подтягивать к шине питания подтягивающим резистором номиналом примерно 4,7к. Если длина сигнального провода увеличивается, необходимо снижать сопротивление подтягивающего резистора. Читал о том, что датчик соединяли с МК проводом длинной 90 метров, для исправной работы датчика сопротивление резистора составило 3к. У себя для освоения работы с датчиком использовал микроконтроллер Atmega32 и выводил показания на двухстрочный алфавитно-цифровой ЖКИ.
$regfile = “m32def.dat” ‘*** Конфигурируем ЖКИ Config Lcd = 16 * 2 ‘ ***Конфигурируем однопроводную шину Config 1wire = Portb.7 ‘ *** Заводим переменные Dim Byte0 As Byte Dim Byte1 As Byte Cls Cursor Off ‘***ОСНОВНАЯ ПРОГРАММА Do ‘ начало цикла 1wreset If Err = 1 Then ‘если при опросе небыло ответа ставим флаг ошибки Cls Rem датчик Rem не подключен Wait 1 Else ‘ иначе, если ошибки не было, продолжаем опрос датчика 1wwrite &HCC ‘ Выдаем команду чтения ПЗУ 1wwrite &H44 ‘ Запуск измерения Waitms 750 ‘ Ждем окончания преобразования 1wreset 1wwrite &HCC Byte0 = 1wread() ‘ Читаем нулевой байт Byte1 = 1wread() ‘ Читаем первый байт If Byte1 > 248 Then ‘ Проверка на отрицательность температуры Byte0 = &HFF – Byte0 Else Sign = “+” 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 If Sign = “+” And T1 = 0 Then ‘ убираем знак “+” с нулевой температуры Sign = ” “ Cls ‘ *** Выводим результат на дисплей Rem Температура Lcd ” Teјѕepaїypa” ‘ тут пишем что измеряем Locate 2 , 6 Lcd Sign ; T1 ; ‘ выводим знак и температуру на дисплей Lcd Chr(223) ; “C” ‘ Сhr(223) – символ “градус” Cursor Off End If Wait 1 ‘ ждем 1 секундy Loop ‘ повторяем цикл End Датчик не подключен, выводится соответствующее сообщение: А это с подключенным датчиком, при комнатной температуре: Ниже можете скачать исходник, файл в протеусе и откомпилированный файл: Скачать | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include #include // 1 Wire Bus functions #asm .equ __w1_port=0x18 ;PORTB .equ __w1_bit=2 #endasm #include #include // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include #include char lcd_buf[17]; void main(void) { float temper; lcd_init(16); w1_init(); ds18b20_init(0,-20,50,DS18B20_12BIT_RES); while(1) { temper=ds18b20_temperature(0); sprintf(lcd_buf,”t=%.1fxdfC”,temper); lcd_clear(); lcd_puts(lcd_buf); delay_ms(1500); }; } |
#include #include // 1 Wire Bus functions #asm .equ __w1_port=0x18 ;PORTB .equ __w1_bit=2 #endasm #include #include // Alphanumeric LCD Module functions #asm .
equ __lcd_port=0x12 ;PORTD #endasm #include #include char lcd_buf[17]; void main(void) { float temper; lcd_init(16); w1_init(); ds18b20_init(0,-20,50,DS18B20_12BIT_RES); while(1) { temper=ds18b20_temperature(0); sprintf(lcd_buf,”t=%.
1fxdfC”,temper); lcd_clear(); lcd_puts(lcd_buf); delay_ms(1500); }; }
Теперь обо всем по порядку:
1 2 3 4 | #asm .equ __w1_port=0x18 ;PORTB .equ __w1_bit=2 #endasm |
#asm .equ __w1_port=0x18 ;PORTB .equ __w1_bit=2 #endasm
Данный код означает, что датчик подключен к порту В, PB2 ножке
1 2 | #include #include |
#include #include
Используется протокол 1wire, тип датчика ds18b20
1 2 3 | float temper; w1_init(); ds18b20_init(0,-20,50,DS18B20_12BIT_RES); |
float temper; w1_init(); ds18b20_init(0,-20,50,DS18B20_12BIT_RES);
Переменная temper (с плавающей точкой) используется для хранения температуры, w1_init(); — ищем датчик, ds18b20_init(0,-20,50,DS18B20_12BIT_RES); — настройка датчика: 0-номер датчика, -20 -нижний предел измерения, 50 — верхний предел измерения,
DS18B20_12BIT_RES используется 12 битный режим(с шагом 0,0625°С). В принципе настройку можно не производить, по умолчанию выставлен 12 битный режим. Показано лишь для того, чтобы вы могли самостоятельно изменить режим измерения, если это понадобится.
1 2 3 4 5 6 | temper=ds18b20_temperature(0); sprintf(lcd_buf,”t=%.1fxdfC”,temper); lcd_clear(); lcd_puts(lcd_buf); delay_ms(1500); |
temper=ds18b20_temperature(0); sprintf(lcd_buf,”t=%.1fxdfC”,temper); lcd_clear(); lcd_puts(lcd_buf); delay_ms(1500);
temper=ds18b20_temperature(0); — читаем значение температуры с датчика sprintf(lcd_buf,»t=%.1fxdfC»,temper); преобразовываем к понятному для lcd виду %.1f — вывод числа с плавающей точкой 1 знак после запятой, не забываем в свойствах проекта указать (s)printf features float.
xdf — вывод на экран значка градуса.
В результате должно получиться нечто похожее
Отрицательной температуры поблизости не было :D, поэтому попробовал остудить бутылочкой соуса из холодильника, результат что то не сильно впечатлил.
Зато от нагрева рукой, температура довольно быстро повысилась.
Проект доступен тут
Проект для DS18s20
Проект для двух датчиков
Проект для DS18b20 на семисегментниках
Проект Алексея(Alyes)для Atmega16 и шести сегментов + бонус видео устройства
Источник: http://avr-start.ru/?p=796
Микроконтроллер AVR и датчик DS18B20
Доброго дня уважаемые друзья!
Приветствую Вас на сайте «Мир микроконтроллеров»
Последовательность операций для работы с датчиком DS18B20
При работе с датчиком DS18B20 очень важно выполнять последовательность выполнения операций:
1. Инициализация
2. Команда ROM
3. Функциональная команда
Если не следовать этой последовательности (что-то пропустить, или поменять местами), то датчик DS18B20 откажется общаться с микроконтроллером
Инициализация датчика DS18B20
В прошлой статье мы рассматривали этот вопрос (инициализация датчика DS18B20), но повторимся, что бы не прыгать по страницам сайта.
Процесс инициализации DS18B20 состоит из трех пунктов:
Исходное состояние — на выводе порта, к которому подключен вывод DQ датчика (шина DQ) — логическая 1 (за счет подтягивающего резистора)
1.
Микроконтроллер передает в линию импульс сброса (длительность 480 микросекунд): — переводит шину DQ в состояние логического нуля (вывод микроконтроллера переводится на вывод информации и в него записывается логический ноль) на время не менее 480 микросекунд (я обычно округляю длительность импульса до 500 микросекунд) — через 480 микросекунд (или 500) микроконтроллер переводит шину DQ на ввод информации, в результате чего за счет подтягивающего резистора на шине восстанавливается логическая единица
— микроконтроллер ждет импульс присутствия от датчика DS18B20
2. Датчик DS18B20 передает в линию импульс присутствия (общая длительность 480 микросекунд): — при переводе микроконтроллером шины в логический ноль на время не менее 480 микросекунд, датчик понимает, что к нему обращаются
— через 15-60 микросекунд, после того как МК перевел шину в состояние логической единицы, датчик передает импульс присутствия — переводит шину DQ в состояние логического нуля на время 60-240 микросекунд
3. Прием импульса присутствия: — через 15-60 микросекунд, после того как микроконтроллер перевел шину в состояние логической единицы, проверяется наличие логического нуля на шине DQ (брать лучше по максимуму — 60 микросекунд) — если на линии — логический ноль — значит датчик присутствует на шине и можно продолжать дальнейшую работу
— так-как общая длительность импульса присутствия должна быть не менее 480 микросекунд, микроконтроллер формирует дополнительную паузу длительностью 420 микросекунд
https://www.youtube.com/watch?v=ks4_XXK1B8w
В ходе процесса инициализации могут возникнуть три ошибки, которые мы разберем непосредственно в программе:
Процесс инициализации датчика DS18B20 оформляется в виде подпрограммы, в данном случае имя подпрограммы «DS_Reset_Pulse» В этой подпрограмме: — Term_Error1 — переменная, в которой будет хранится код ошибки
— DQ_Pin, DQ_Port, DQ_DDR — присвоенные мной имена выводу порта к которому подключен датчик.
Делается это не только для наглядности (можно конечно и ничего не присваивать) но в больше степени для быстрой смены вывода порта в программе, если мы вдруг захотим подключить датчик к другому выводу (не надо будет по всей программе искать где этот РВ6, чтобы заменить его, к примеру, на РС5 — проще один раз поменять в таблице)
Ну а теперь рассмотрим подробно саму подпрограмму «Инициализация датчика DS18B20» :
1.
Обнуляем переменную в которую будет записан код ошибки («Term_Error1») 2. Проверяем, есть ли на шине DQ логическая единица: — если на шине присутствует высокий уровень (логическая единица), то переходим к формированию импульса сброса — если на шине нет высокого уровня, то записываем в переменную «код ошибки» — 1 (код ошибки отсутствия высокого уровня на шине DQ) и выходим из подпрограммы. Затем, при выводе данных на индикатор, высвечиваем, к примеру, — «Er1».
Отсутствие высокого уровня в 99 случаях означает, что не подключен подтягивающий резистор формирующий высокий уровень на шине. 3. При высоком уровне на шине микроконтроллер формирует импульс сброса продолжительностью не мене 480 мкс, путем перевода вывода порта в режим «выхода» и записи в него логического нуля. 4. Микроконтроллер отпускает шину путем перевода вывода порта в режим «входа» 5.
Через 60 мкс МК поверяет наличие импульса присутствия от датчика (на шине должен присутствовать низкий уровень (логический ноль) 6. Проверяем, есть ли на шине DQ логический ноль: — при низком уровне на шине, означающем что датчик выдал импульс присутствия, МК формирует паузу в 420 мкс — высокий уровень на шине означает, что датчик не выдал импульс присутствия.
В этом случаем записываем в переменную «код ошибки» — 2 (код ошибки отсутствия импульса присутствия от датчика), а при выводе данных на индикатор — выводим «Er2» 7.
После паузы в 420 мкс проверяем наличие высокого уровня на шине после окончания импульса присутствия: — если на шине логическая единица, значит датчик отработал и выходим из подпрограммы инициализации датчика — если на шине логический ноль, значит датчик не вернул шину в высокий уровень. Записываем в переменную «код ошибки» — 3 (код ошибки «не восстановлен высокий уровень после импульса присутствия») На этом инициализация датчика заканчивается. Если ошибок нет, то МК переходит к выполнению следующих шагов — посылает на датчик команду ROM, а затем функциональную команду.
Читайте также: Многофункциональный ваттметр с гальванической развязкой
Если ошибка присутствует, то микроконтроллер дальше не идет, а постоянно выполняет подпрограмму инициализации до устранения ошибки.
Команда ROM DS18B20
Мы рассмотрим работу микроконтроллера с одним датчиком температуры, это несколько проще в том смысле, что статья получится короче, ну а разобраться как работать с двумя и более датчиками будет, я думаю, не очень сложно.
Итак, мы выполнили первый шаг — инициализация датчика DS18B20, убедились что с датчиком все в порядке, ну а датчик приготовился к приему очередных команд и выдачи нужных нам результатов. Приступаем ко второму шагу — подаем нужную нам команду ROM.
Так как датчик у нас один, нам потребуется для работы одна команда ROM из пяти — SKIP ROM — пропуск ROM, так как мы не определяли 64-разрядный код датчика (для одного датчика этого делать не надо), соответственно отпадают и другие команды.
Практически, при одном датчике на шине, используется только одна команда ROM — SKIP ROM, и очень редко — ALARM SEARCH — Поиск Тревоги.
Перед тем как передать команду ROM на датчик, давайте разберемся как вообще передавать какие-либо данные по шине 1-Wire. Сразу скажу, самое главное в этом деле строго соблюдать временные интервалы.
Давайте посмотрим на временной график записи данных в датчик и на его основе составим подпрограмму записи данных в DS18B20:
Расшифровываем график: 1. Слот времени передачи одного бита должен иметь продолжительность не менее 60 мкс и не более 120 мкс 2. Датчик DS18B20 гарантированно определяет логический уровень на шине через 30 мкс (минимум — 15 мкс, максимум — 60 мкс) 3.
Так как датчику необходимо максимум 60 мкс для приема и записи бита информации, то делать продолжительность слота времени более 60 мкс смысла нет 3.
После окончания слота времени для передачи логического нуля необходимо не менее 1 мкс для перевода шины в высокое состояние (я беру 5 мкс) 4.
При передаче логической единицы в начале слота времени передачи МК должен перевести шину в низкое состояние на время от 1 до 15 мкс (я беру 5 мкс) Я в программе общения МК с датчиком процессы записи в датчик логических уровней оформил в виде 2-х подпрограмм: — запись логического нуля — запись логической единицы
Теперь посмотрите на мои подпрограммы и, исходя из выше сказанного, я думаю алгоритм передачи одного бита информации датчику будет понятен:
Теперь давайте посмотрим как передать байт информации датчику (все команды для датчика однобайтовые).
Запись байта информации в датчик также оформлена в виде подпрограммы:
Temp — рабочий регистр, в который предварительно записываем код передаваемой команды >Temp>> — операция логического сдвига вправо с переносом рабочего регистра Temp Передача байта информации от МК датчику производится побитно, начиная с младшего, т.е. сначала нулевой бит, затем первый и т.д.
Такую операцию очень удобно проводить с помощью команды «Логический сдвиг вправо с переносом», команда работает с регистрами общего назначения. При логическом сдвиге вправо с переносом, младший байт заносится в бит «С» регистра SREG, а содержимое РОН сдвигается вправо на 1 бит. Алгоритм работы подпрограммы: 1.
Задаем цикл, в ходе выполнения которого над регистром Temp будет восемь раз произведена операция логического сдвига вправо с переносом. В ходе выполнения цикла каждый бит регистра Temp, начиная с младшего «пройдет» через бит С регистра SREG 2.
После каждого логического сдвига с переносом проверяем что записалось в бит С регистра SREG: — если записан логический ноль — переходим к подпрограмме передачи нуля
— если записана логическая единица — переходим к подпрограмме передачи единицы.
Функциональные команды DS18B20
Как и команды ROM, функциональные команды однобайтовые и процесс их передачи датчику аналогичен процессу передачи команды ROM. В основном используются две функциональные команды: — «Конвертировать температуру», по этой команде датчик «измеряет температуру»
— «Чтение памяти», по этой команде датчик передает МК результаты конвертирования температуры
Конвертировать температуру (измерить температуру) DS18B20
Эта команда имеет одну особенность, которая заключается в том, что датчику надо время на выполнение этой команды и МК не должен мешать датчику в этот промежуток времени.
Датчик в процессе конвертирования температуры удерживает шину DQ в низком состоянии, а по окончании конвертации переводит шину в высокое состояние.
МК должен отслеживать этот процесс — на шине логический ноль — значит идет конвертация, на шине логическая единица — значит датчик закончил конвертацию, и можно переходить к считыванию результатов измерения.
Посмотрим на примере алгоритм подачи команды на конвертирование температуры:
Как видно из приведенной программы, для измерения температуры датчиком, МК должен выполнить следующий алгоритм: 1. Инициализация датчика. Если возникла ошибка — выход из подпрограммы 2.
Подать команду «Пропуск ROM», где: — DS_SKIPROM — константа, в которой записан код команды $CC — для наглядности — DS_Command — переменная, в которую записываются команды от МК — DS_Send_Command — подпрограмма, в ходе выполнения которой код команды сначала записывается в рабочий регистр Temp, а затем происходит переход к подпрограмме передачи байта датчику.
Можно, конечно, присвоить имя DS_Command не переменной, а сразу рабочему регистру, или записывать код команды в рабочий регистр Temp, чтобы не делать лишних движений (это называется оптимизация кода). 3. Подать команду «Конвертировать температуру»
4. Перевести шину DQ на вход и постоянно проверять ее состояние — как только на шине будет логическая единица — выходим из подпрограммы.
Чтение памяти DS18B20
По команде «Чтение ROM» датчик передает на МК содержимое всей своей оперативной памяти — 9 байт информации, при этом результаты конвертирования находятся в первых двух байтах. Мы можем в любой момент времени прервать операцию чтения. К примеру, если нам нужны только данные измерения температуры — считываем первые два байта и прерываем процесс.
Для чтения результатов конвертирования температуры необходимо предварительно назначить две переменные, к примеру: — DS_Temp_Lo — для первого байта — DS_Temp_Hi — для второго байта
Посмотрим на подпрограмму чтения результатов конвертирования температуры датчиком (подпрограмма называется Read_Temp_1):
Алгоритм: 1. Инициализация датчика 2. Команда ROM — «Пропуск ROM» 3. Функциональная команда — «Чтение памяти» 4. Переход к подпрограмме чтения байтов МК (DS_Read_Byte)
5. Запись результатов в переменные
Рассмотрим как происходит чтение информации от датчика.
Временной график слотов времени передачи битов данных от датчика:
Расшифруем график: 1. Слоты времени считывания как логического 0, так и логической 1 должны быть продолжительностью не менее 60 мкс, и разделяться между собой промежутками не менее 1 мкс 2.
Для считывания бита информации МК переводит шину в низкое состояние на время не менее 1 мкс (у меня — 3 мкс), а затем возвращает шину в высокое состояние (Эта процедура является командой для датчика на передачу одного бита информации) 3.
Через 15 мкс датчик передает или логическую единицу, или логический ноль: — если логический 0 — датчик переводит шину в низкое состояние на время 45 мкс — если логическая 1 — датчик ничего ни делает, шина остается в состоянии логической единицы 4.
Через 15 мкс, после того, как МК перевел шину в низкое состояние, а затем вернул в высокое, в течение 45 мкс МК может считать данные с шины (у меня — через 23 мкс)
Давайте посмотрим подпрограмму чтения байта:
Подпрограмма чтения байта от датчика очень похожа на подпрограммы передачи данных от МК. Также используется цикл и команда логического сдвига вправо с переносом регистра Temp, датчик данные передает начиная с нулевого бита. Давайте посмотрим 1 цикл выполнения подпрограммы: 1.
МК переводит шину МК в низкое состояние на 3 мкс, а затем обратно в высокое 2. Через 20 мкс МК анализирует логический уровень на шине: — если на шине низкий уровень — в бит С регистра SREG записывается 0 — если на шине выокий уровень — в бит С регистра SREG записывается 1 3.
Производится логический сдвиг вправо с переносом регистра Temp, при этом содержимое бита С регистра SREG записывается в старший бит Temp.
В последующем, все данные в регистре Temp будут поочередно перемещаться в сторону младшего бита.
Считанные байты мы записываем в назначенные переменные. Хочу обратить ваше внимание на то, что в первом байте результатов конвертирования температуры, в первых четырех битах записаны «Десятые градуса» в виде какого-то числа.
К примеру, при 12-битной разрешающей способности датчика, это число может быть от 0 до 14, поэтому десятые градуса рассчитываются самостоятельно.
Старшие 4 бита 1-го байта и младшие четыре байта 2 байта содержат информацию о целых градусах именно в градусах.
Это не очень удобно для работы, и поэтому сначала надо выделить «десятые» в отдельный байт путем записи первых 4-х битов 1-го байта в отдельную переменную. Старшие 4 бита 1-го байта записываем в младшие 4 бита другой переменной, и в эту же переменную, в старшие 4 бита, записываем младшие 4 бита 2-го байта. К примеру так (заодно и определяем знак температуры):
И последнее, если температура отрицательная, то данные в датчике хранятся в виде дополнительного кода.
Чтобы привести их в «нормальное состояние», необходимо, после того как выделим «десятые» и «целые» градуса в разные байты, проинвертировать их содержимое — 0 поменять на 1, а 1 — на 0, а затем, к полученному результату прибавить единицу. Для этого удобно применить двойной регистр (X, Y или Z).
Предыдущие статьи:
1. Устройство цифрового термометра DS18B20
2. Система команд датчика DS18B20
3. Подключение DS18B20 к микроконтроллеру
Источник: https://microkontroller.ru/praktikum-mikrokontrollershhika/programmirovanie-rabotyi-datchika-ds18b20-s-mikrokontrollerom/
Работа с датчиком температуры DS18B20
avrki@avrki.ru
Дата: 15 Мая 2014. Автор: Алексей
В библиотеке AXLIB есть набор функций для работы с данным датчиком. Весна в полном разгаре. Скоро лето, жара. А жара это сколько? Надо померить. А как? Вот и решил я поработать с датчиком температуры DS18B20. Благо он дешевый и его можно купить где угодно. И еще под этот датчик в CVAVR есть библиотека. Но….
После ковыряния с этим датчиком и библиотекой от CVAVR я окончательно решил слезть с этой пакости. Я пол дня угробил на состыковку библиотечных функция с динамической индикацией. Все вроде работает нормально, но когда доходит до опроса датчика, то индикация спотыкается на секунду.
Жуть!!! Короче пообщавшись с умными людьми на форуме, я залез внутрь библиотеки и нарыл тело функции чтения температуры и о чудо! Там за каким-то лешим после команды на старт преобразования стоит пауза на 550 мс. Зачем? Для тех кто все же останется преданным CVAVR, эту паузу можно стереть. Заработало немного быстрее.
Еще остался вопрос, а где лежат функции для работы с шиной 1-wire? Только хедер и все. Просто возник еще вопрос. Если при динамической индикации использовать таймер и в прерывании выводить цифры, то фигня выходит. Терзают меня смутные сомнения, что при обработке функций шины 1-wire запрещаются прерывания. Короче мне эти непонятки надоели и я переехал на AVRStudio 6.
1 и ни капли не сожалею. Ну и еще получил пинок для изучения принципа работы шины 1-wire. Перед тем как писать код, давайте окунемся немного в теорию. Сразу оговорюсь, я рассчитываю на то что статьи такого типа читают люди которые чуть ли не впервые взяли в руки паяльник. И если начать трактат о временных слотах и тому подобное, то многие прокиснут и скажут, а ну его на фиг.
Поэтому я буду объяснять на пальцах как сам это понимал.
Для начала определимся с планом действий. Задача: Один датчик, берем из него температуру и по необходимости выводим куда-нибудь. Алгоритм из мануала на датчик.
- 1. Подать команду сброса.
- 2. Получить подтверждение о наличии хотя бы одного датчика.
- 3. Читать РОМ код (эта фигня с его идентификационным номером. Нужно для работы не с одним датчиком).
- 4. Передать настройки
- 5. Подать команду на начало преобразования температуры
- 6. Получить данные
- 7. Преобразовать в человеческий вид
Читайте также: Электрошок от 5 в
Теперь все по порядку. Перед тем как начать рассказ о командах, давайте пробежимся по физике шины.
У датчика есть три ноги, две для питания(возможна работа от паразитного питания, но о ней мы пока говорить не будем. Считаем что у нас есть полноценное питание и оно подведено к датчику). Третья нога как раз для передачи данных. Но тут есть свой нюанс. Просто дергать ногу верх и вниз нельзя.
Между этой ножкой и плюсом питания стоит резистор на 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. Если ноль, значит плюс, а если единица, значит зима) А дальше склеиваем как плюсовую, а потом инвертируем каждый бит. То есть те что были нулями должны стать единицами, а единицы нулями. После прибавляем единицу и получаем температуру так сказать по модулю. Выводим как плюсовую, только не забываем поставить знак минус.
Ну вроде и все. Вот фотки плюсовой и минусовой температуры. Правда минус не совсем низкий так как сейчас за окном май месяц, а от куска мяса из морозилки много не выдавишь но все же работу программы надо показать)
Программный код я здесь выкладывать не буду, так как это лишнее. Я выкладываю архив в котором лежат файлы основной программы и подключаемого хедера с функциями передачи команд. Каждая строка подробно закоментированна. Если все же возникнут вопросы, то я на связи. Удачи! В библиотеке AXLIB есть набор функций для работы с данным датчиком.
Архив с файлами.
Алексей, вопрос – я могу с помощью команды читать ROM, определить наличие датчика? Скажем, выдать 0x33, и прочитать в первом байте код семейства DS18B20. Если он не равен 0x28 – значит, датчика нет. Или так не не годится?
А чем не устраивает команда сброса? Или на шине еще что-то висит?
Но, ведь по команде сброса можно только определить – есть ли любые устройства 1- wire или нет. А хотелось бы именно удостовериться в отсутствии термодатчика DS18B20.
Есть чужой исходник на ассемблере на два термометра с батарейным питанием на разных шинах, захотелось кое-что переделать по своему вкусу. Лезть в сами процедуры работы с датчиком особо не хочется, вроде нормально и так работает.
Поэтому и возникла идея – дать команду 0x33, потом принять первый байт из 8, и его проанализировать на наличие кода семейства. Типа, если там есть 0x28 –
Хорошо. Если есть два датчика НО НА РАЗНЫХ шинах, то какая разница как определить наличие датчика. Подали команду сброса и все. Датчик ответил, значит все в порядке. Не ответил, увы. Команды на обнаружение по семейству нужно подавать только тогда, когда на шине висит больше одного датчика. А если один, то зачем такие сложности. Или я что-то не понимаю в вашем вопросе.
Спасибо за ответ. Просто хотел уточнить, возможен ли такой вариант определения наличия датчика.
Собственно, а почему нет. Если известен адрес датчика и он ответил на любую команду значит он априори жив и здоров.
Меня как раз интересовал способ, при котором неизвестен адрес датчика, сидящего на отдельной шине. Зачем полностью читать все 64 бита идентификации, вполне хватит и 8-ми бит, в которых есть код семейства. Например, 0x28 для DS18B20. Если принят любой другой код – значит, датчика нет, он не тот, или неисправен, что в конкретном случае почти одинаково.
Стоп, стоп, стоп. Это сработает при широковещательном запросе при условии только одного датчика на шине. С тем же успехом можно и команду сброса подать.
Если будет больше устройств на шине, то на широковещательный запрос ответят все. Иначе по адресу. Ну это же логично. Если вы отправите письма с запросом нескольким людям, они все вам и ответят.
А если просто одному человеку в комнате крикните, “Эй, ты!”. Он один и ответит.
Правильно, я и написал – “…датчика, сидящего на отдельной шине…”. У меня как раз ситуация, когда каждый датчик термометра – сидит на отдельной шине. Именно поэтому и возник такой вопрос. И потом, стоит задача определения наличия именно DS18B20, мало ли что там народ еще может подключить. А так – датчик ответил кодом 0x28, значит все в порядке.
Алексей, еще поясните такую вещь, если не трудно, а то что-то в даташите про это нигде не сказано.
Я подал команду записать в датчик 0x33 (чтение ROM), затем должен сколько-то подождать, или могу сразу читать с датчика? Где-то в сети народ жаловался на то, что типа, пока не поставил между командами записи-чтения задержку около 1 миллисекунды – датчик не отзывался вовсе, или вывдавал всякую белиберду.
А это зависит от дискретизации(точности) измерений. При запросе на вычисления температуры датчик может, зависать аж по моему до 750 мс. Давненько я с ним не работал не помню. Проще шину нюхать.
Если после команды на преобразования шина в нуле, значит не готов. Как шина к поднялась к единице, можно читать температуру.
С этой проблемой часто сталкиваются те кто выводит температуру на динамический индикатор.
Когда нужна температура, задержка обычно подразумевается. Потому что делать поллинг (опрос бита готовности), не всегда удобно. А вот когда пишется команда, не связанная с преобразованием температуры? Например, та же 0x33 – чтение ROM.
Ну я не знаю. Вообще задержка не нужна. Ради собственного удовлетворения то пару миллисекунд вляпать можно. Если это не дипломная работа, то я бы воспользовался импирикой и не парил себе мозг. 🙂
Есть желание немножко усложнить конструкцию? Я очень хочу поработать с вами вместе. Передо мной была поставлена интересная задача. Денежкой поделюсь. Жду ответа тут
А по конкретнее какая задача. Точнее ТЗ.
Нужно сделать два термометра МК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К а я все нее могу с модулями и ассемблером разобраться. Нашел ваш терморегулятор. Разбираю ваш пример пока. Изложение мысли понравилось.
Такой регулятор…Как связаться с вами?
Отлаживаю на плате STK500 в связке с STK502. Примерную схему я набросал в ИГЛКАД Для связи могу предложить скайп. Мой логин : 819 готов отдать 7К
Честно, я ничего не понял. avrki@avrki.ru моя почта. Можно более подробно и сформулировано объяснить что нужно сделать. И при чем здесь РОН? Обязательно на ассемблере? Какой МК рулить всем этим будет? Нужна конкретика, ТЗ. Напишите поверхностный псевдо-код, что должно происходить в течении работы устройства. На какой шине висят радио модуль и ВТ модуль. Зачем вообще ВТ? Связь с телефоном?
Читайте также: Управление lm317t от шим сигнала
Здравствуйте, а скажите насколько точно он меряет температуру. У меня он по ощущениям на 3-4 градуса завышает. Минусовую вроде точно выводит. Также хочу заметить, что нет смысла выводить десятые доли градуса при такой точности. Тогда температуру можно получать так temper = (temp_0>>4)+(temp_1
Источник: http://www.avrki.ru/articles/content/ds18b20/
Скачать и слушать бесплатно музыку mp3
Улети by T-Fest
Между нами ток by Татьяна Котова
Tell Me Who (feat. Eneli) [Slider & Magnit Remix] by Vanotek
Got U (Ready or Not) by Kokab
Сегодня я нашел тебя by Jah Khalib
Despacito (feat. Daddy Yankee) by Luis Fonsi
I Got Love (feat. Рем Дигга) by MiyaGi & Эндшпиль
Thunder by Imagine Dragons
Attention by Charlie Puth
Stole the Show (feat. Parson James) by Kygo
случайная by Loboda
Моя любовь by Макс Барских
Сансара (feat. Диана Арбенина, Александр Ф. Скляр, Сергей Бобунец, Sunsay, Скриптонит & Ант) by Баста
Львица by Lx24
Fetish (feat. Gucci Mane) by Selena Gomez
Believer by Imagine Dragons
Подсыпал by Елена Темникова
Одна на миллион by Наталья ВОВК
Между нами любовь by SEREBRO
Неделимы by Artik & Asti
Лейла (feat. Маквин) by Jah Khalib
Numb by LINKIN PARK
Дни и ночи by Джиган
Тает лёд by Грибы
На двоих by МакSим
ОТПУСТИЛ by ВЕТЕР
Потрачу by Егор Крид
Вдох by Елена Темникова
По волнам by Burito
#Тамада (feat. al l bo & Wooshendoo) by Miyagi & Эндшпиль
Move On (feat. Jabbar) by Deeperise
Vitamin D by MONATIK
Драмы больше нет by Полина Гагарина
Твои глаза by Loboda
Если ты меня не любишь by Егор Крид & MOLLY
Way Down We Go by Kaleo
Малополовин by Ольга Бузова
Shape of You by Ed Sheeran
Если чё, я Баха by Jah Khalib
Лирика (feat. Masha) by Filatov & Karas
In the End by LINKIN PARK
Feel It Still by Portugal. The Man
Love by Lana Del Rey
Туманы by Макс Барских
Talking to Myself by LINKIN PARK
One More Light by LINKIN PARK
Пахну лишь тобой (feat. Artik & Asti) by Глюк’oZa
УВЛИУВТ (Упали в любовь и ударились в танцы) by MONATIK
2U (feat. Justin Bieber) by David Guetta
Tell Me Who (feat. Eneli) by Vanotek
Источник: https://mp3-muzyka.ru/download/WSj1dMP3b-s/%D0%A3%D1%80%D0%BE%D0%BA-15-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%B4%D0%B0%D1%82%D1%87%D0%B8%D0%BA%D0%BE%D0%BC-%D1%82%D0%B5%D0%BC%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D1%83%D1%80%D1%8B-DS18B20-%D0%B2-BASCOM-AVR.html
Подключение датчика ds18b20 к микроконтроллеру ATmega8535
Источник: http://mega-avr.ucoz.ru/publ/ds18b20_connect_atmega8535/1-1-0-15
Спасибо за ваше внимание к сайту нашим новым публикациям.