ESP32. Урок 40. RMT. DS18B20. Инициализация

 

 

 

Продолжаем работать с модулем RMT и в прошлом занятии мы смогли обращаться к устройствам с уже известными ROM-кодами и сверять коды данных устройств с уже известными.

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

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

На данном занятии мы пока произведём только инициализацию датчика, но а вернее — инициализацию шины под работу с датчиком DS18B20.

Схема урока пока будет такая же, как и в прошлом уроке — с одним датчиком, остальные мы также подключим чуть позже

 

 

Проект урока также был сделан из проекта прошлого урока с именем RMT_ONEWIRE_SEARH_KNOWN_ROM и назвали мы его RMT_DS18B20_INIT.

Откроем наш проект в Espressif IDE и для красоты в файле Kconfig.projbuild изменим наименование пункта согласно нашей теме

 

menu "DS18B20 Configuration"

 

Также создадим два файла, в котором мы будем работать именно с нашим датчиком — ds18b20.h и ds18b20.c

 

 

 

В файле CMakeLists.txt подключим наш новый файл

 

set(COMPONENT_SRCS "main.c owb.c ds18b20.c")

 

Также нашу библиотеку подключим в файле main.h

 

 

Также чтобы проект не ругался на false и true, подключим надлежащий заголовочный файл

 

 

Попробуем собрать наш проект, и если всё нормально собралось, в файле ds18b20.h объявим перечисляемый тип для различных разрешений значений датчика, а также тип структуры для хранения нужной информации о датчике

 

 

В функции app_main файла main.c объявим указатель на массив типов структуры, который мы только что объявили

 

 

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

В файле ds18b20.c добавим функцию для запроса памяти под переменную типа нашей структуры, а также заполнения данной памяти нулями

 

 

Объявим на данную функцию прототип в заголовочном файле и в функции app_main файла main.c организуем цикл, равный количеству найденных устройств, в котором объявим переменную на тип нашей структуры и с помощью только что добавленной функции запросим память и инициализируем её нулями

 

 

Присвоим адрес данного указателя адресу соответствующего элемента массива

 

 

В файле ds18b20.c добавим функцию первичной инициализации переменно типа структуры информации о датчике

 

 

Разрешающую способность пока не устанавливаем.

Ниже функции ds18b20_malloc добавим функцию, которая будет узнавать текущую разрешающую способность датчика

 

 

Объявим структуру, в которой будет храниться текущее состояние памяти датчика — показание температуры в целом числе и прочие нужные показатели

 

 

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

 

 

В файле ds18b20.h объявим перечисляемый тип, хранящий различные варианты ошибок датчика

 

 

Вернёмся в файл ds18b20.c и ниже функции _is_init_ds добавим функцию, которая будет читать память датчика

 

 

В теле данной функции мы установим размер скратчпада, равный размеру структуры

 

 

Выше добавим функцию, которая будет определять минимальное значение из двух возможных

 

 

Вернёмся в функцию _read_scratchpad и узнаем, что больше: значение в переменной или размер структуры

 

 

Если мы в режиме отладке, то выведем размер в терминал

 

 

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

 

 

В файле owb.c исправим для начала ошибку в функции owb_verify_rom. Данная ошибка была допущена, когда я писал код во время видеоурока, в текстовой версии урока данной ошибки нет. Я забыл после строки

 

_search(bus, &state, &is_found);

 

добавить условие, был просто блок.

Исправим данный недочёт

 

 

Ниже данной функции добавим функцию перезагрузки устройства, которая будет использовать уже готовую функцию

 

 

Объявим на данную функцию прототип в заголовочном файле, вернёмся в файл ds18b20.c и в функции _address_device сбросим наш датчик, если он инициализирован, если не инициализирован, выведем соответствующее сообщение в терминале

 

 

В файле owb.c ниже функции owb_read_bytes добавим функцию, которая будет отправлять байт в шину

 

 

Ниже добавим функцию, которая будет отправлять в шину несколько байтов

 

 

Ещё ниже добавим функцию, которая будет отправлять в шину ROM-код устройства для того, чтобы мы могли обратиться к нужному датчику

 

 

Объявим на данные три функции прототипы в заголовочном файле owb.h и также в нём добавим макросы ещё двух команд — команды пропуска чтения ROM-кода и команды отправки кода в случае наличия нескольких устройств

 

 

Вернёмся в файл ds18b20.c и в функции _address_device, если у нас только одно устройство, отправим соответствующую команду в шину

 

 

В противном случае мы отправляем другую команду и отправляем код устройства

 

 

Добавим макрос с командой чтения скратчпада

 

 

В файле owb.h добавим прототип для функции генерации контрольной суммы

 

 

Также добавим прототип для функции чтения нескольких байтов

 

 

Вернёмся в файл ds18b20.c и в функции _read_scratchpad прочитаем скратчпад, сохранив значения в соответствующих полях переменной структуры по указателю во входном параметре

 

 

Выше функции _address_device добавим функцию, которая будет узнавать, находится ли разрядность возвращаемого значения температуры датчика в пределах от 9 до 12 бит

 

 

В функции ds18b20_read_resolution прочитаем скратчпад и проверим, что наша разрядность находится в необходимых пределах

 

 

Ниже добавим функцию инициализации датчика, если он только один на шине

 

 

 

Объявим на данную функцию прототип в функции app_main файла main.c вызовем нашу функцию инициализации в случае присутствия на шине только одного датчика

 

 

Попробуем собрать код и прошить контроллер и посмотрим, что у нас в терминале

 

 

Мы видим, что у нас хотя бы ошибок нет.

Посмотрим теперь, что в логическом анализе

 

 

Там также всё хорошо.

Подключим ещё один датчик

 

 

Проверять код нет смысла, так как мы ещё не написали его для нескольких датчиков.

Поэтом идём в файл ds18b20.c и выше функции ds18b20_init_solo добавим ещё одну подобную функцию, которая будет инициализировать уже несколько устройств

 

 

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

Объявим на данную функцию прототип в заголовочном файле и в функции app_main файла main.c в случае присутствия нескольких устройств на шине вызовем нашу функцию

 

 

Соберём код, прошьём контроллер и посмотрим результат в терминале

 

 

Код отработал правильно. Ошибок нет, просто у нас пока отсутствует третий датчик, а проверка выше у нас была трёх датчиков. Подключим третий

 

 

Перезагрузим контроллер и посмотрим результат сначала в терминале

 

 

А затем и в программе логического анализа

 

 

Здесь тоже всё правильно, команды теперь отправляются без пропуска ROM-кода.

В файле ds18b20.c выше функции ds18b20_read_resolution добавим функцию установки использования или неиспользования контрольной суммы

 

 

Выше функции ds18b20_init добавим функцию, которая будет устанавливать разрядность величины температуры

 

 

В данной функции мы аналогично прочитаем скратчпад

 

 

Далее запишем в поле переменной пока начальное значение

 

 

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

Выше функции ds18b20_malloc добавим пока заготовку такой функции

 

 

Объявим макрос команды записи скратчпада

 

 

В функции _write_scratchpad отравим данную команду в шину, и затем отправим 3 байта, которые находятся по указателю во входном параметре, вернее в поле trigger_high, которое соответствует тому месту в памяти датчика, где находятся необходимые значения для разрядности температуры. После этого мы считаем данное значение обратно из датчика и сравним его со значением, находящимся в поле, тем самым проверив, правильно ли у нас всё прописалось в память датчика. Если нет, то выведем ошибку в терминал

 

 

То есть у нас не совсем полноценная функция записи скратчпада, которая умеет писать только 3 байта, которые требуются для установки значения разрядности. А полноценная нам и не нужна, так как кроме этого нам отправлять в датчик нечего.

Вернёмся в функцию ds18b20_set_resolution и отправим значение разрешающей способности в датчик, затем, если всё удачно отправилось, то запишем данное разрешение в соответствующее поле переменной структуры свойств датчика, а если нет, то прочитаем разрешающую способность из датчика и присвоим тогда его значение полю

 

 

Объявим прототипы на наши функции ds18b20_use_crc и ds18b20_set_resolution в заголовочный файл, а затем в файле main.c объявим макрос со значением желаемой разрешающей способности

 

 

В функции app_main вызовем наши функции

 

 

Извлечём пока дополнительные два датчика, соберём код, прошьём контроллер и посмотрим результат в терминале

 

 

Ошибок не замечено.

Посмотрим результат в логическом анализе

 

 

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

Добавим остальные датчики обратно в схему и перезагрузим контроллер

 

 

Ошибок также не обнаружено.

Для полноправной инициализации давайте также проверим факт  наличия на шине устройств с паразитным питанием.

Для этого в файле ds18b20.c выше функции ds18b20_init добавим функцию, которая поможет нам решить данную задачу

 

 

В теле данной функции произведём сброс устройства и отправим байт с командой пропуска чтения ROM-кода

 

 

Объявим макрос для команды определения, использует ли устройство паразитное питание

 

 

Вот выдержка из технической документации с кодами команд

 

 

Вернемся в функцию и передадим в шину данную команду

 

 

Перейдём в файл owb.c и выше функции owb_read_bytes добавим функцию чтения одного бита. Она нужна нам для определения уровня

 

 

Объявим прототип для данной функции в заголовочном файле и в функции ds18b20_check_for_parasite_power файла ds18b20.c, вызовем функцию чтения бита и запишем его значение в переменную present по указателю. В принципе, тип bool, как и бит имеет только два значения

 

 

Объявим на данную функцию прототип и в функции app_main файла main.c с помощью данной функции узнаем, есть ли у нас устройства с паразитным питанием

 

 

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

В файле owb.c выше функции owb_read_rom добавим функцию, которая соответствующему полю переменной структуры свойств шины присвоит значение использования или неиспользования режима наличия устройства на шине с паразитным питанием

 

 

Объявим на данную функцию прототип в заголовочном файле и в функции app_main файла main.c вызовем данную функцию в том случае, если такое устройство на шине было обнаружено

 

 

Соберём код, прошьём контроллер и посмотрим результат в терминале

 

 

Результат тот же, что и ранее, значит никаких устройств с паразитным питанием на нашей шине нет.

В программе логического анализа мы видим, что команда наша в шину передана

 

 

После передачи команды шина осталась в высоком состоянии, значит данных устройств нет

 

 

Итак, на данном уроке мы написали инициализацию датчика DS18B20 с использованием модуля RMT контроллера. Осталось нам теперь научиться читать значения температуры со всех датчиков на шине.

 

Всем спасибо за внимание!

 

Предыдущий урок Программирование МК ESP32 Следующий урок

 

Исходный код

 

 

Недорогие отладочные платы ESP32 можно купить здесь:

На AliExpress Недорогие отладочные платы ESP32

На Яндекс.Маркет Недорогие отладочные платы ESP32

Недорогие отладочные платы ESP32-S3 можно купить здесь:

Недорогие отладочные платы ESP32-S3

Датчик температуры в экране с проводом можно приобрести здесь:

На AliExpress DS18B20 в экране с проводом

На Яндекс.Маркет DS18B20 в экране с проводом

Логический анализатор 16 каналов можно приобрести (AliExpress) здесь

 

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP32 RMT. DS18B20. Инициализация

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

ESP32 RMT. DS18B20. Инициализация

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*