Работа с датчиком температуры DS18B20
Дата: 15 Мая 2014. Автор: Алексей
В библиотеке AXLIB есть набор функций для работы с данным датчиком.
Весна в полном разгаре. Скоро лето, жара. А жара это сколько? Надо померить. А как? Вот и решил я поработать с датчиком температуры DS18B20. Благо он дешевый и его можно купить где угодно. И еще под этот датчик в CVAVR есть библиотека. Но.... После ковыряния с этим датчиком и библиотекой от CVAVR я окончательно решил слезть с этой пакости. Я пол дня угробил на состыковку библиотечных функция с динамической индикацией. Все вроде работает нормально, но когда доходит до опроса датчика, то индикация спотыкается на секунду. Жуть!!! Короче пообщавшись с умными людьми на форуме, я залез внутрь библиотеки и нарыл тело функции чтения температуры и о чудо! Там за каким-то лешим после команды на старт преобразования стоит пауза на 550 мс. Зачем? Для тех кто все же останется преданным CVAVR, эту паузу можно стереть. Заработало немного быстрее. Еще остался вопрос, а где лежат функции для работы с шиной 1-wire? Только хедер и все. Просто возник еще вопрос. Если при динамической индикации использовать таймер и в прерывании выводить цифры, то фигня выходит. Терзают меня смутные сомнения, что при обработке функций шины 1-wire запрещаются прерывания. Короче мне эти непонятки надоели и я переехал на AVRStudio 6.1 и ни капли не сожалею. Ну и еще получил пинок для изучения принципа работы шины 1-wire.
Перед тем как писать код, давайте окунемся немного в теорию. Сразу оговорюсь, я рассчитываю на то что статьи такого типа читают люди которые чуть ли не впервые взяли в руки паяльник. И если начать трактат о временных слотах и тому подобное, то многие прокиснут и скажут, а ну его на фиг. Поэтому я буду объяснять на пальцах как сам это понимал.
Для начала определимся с планом действий. Задача: Один датчик, берем из него температуру и по необходимости выводим куда-нибудь. Алгоритм из мануала на датчик.
- 1. Подать команду сброса.
- 2. Получить подтверждение о наличии хотя бы одного датчика.
- 3. Читать РОМ код (эта фигня с его идентификационным номером. Нужно для работы не с одним датчиком).
- 4. Передать настройки
- 5. Подать команду на начало преобразования температуры
- 6. Получить данные
- 7. Преобразовать в человеческий вид
Теперь все по порядку.
Перед тем как начать рассказ о командах, давайте пробежимся по физике шины. У датчика есть три ноги, две для питания(возможна работа от паразитного питания, но о ней мы пока говорить не будем. Считаем что у нас есть полноценное питание и оно подведено к датчику). Третья нога как раз для передачи данных. Но тут есть свой нюанс. Просто дергать ногу верх и вниз нельзя. Между этой ножкой и плюсом питания стоит резистор на 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 есть набор функций для работы с данным датчиком.
Архив с файлами.
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 моя почта. Можно более
подробно и сформулировано объяснить что
нужно сделать. И при чем здесь РОН?
Обязательно на ассемблере? Какой МК
рулить всем этим будет? Нужна
конкретика, ТЗ. Напишите поверхностный
псевдо-код, что должно происходить в
течении работы устройства. На какой шине
висят радио модуль и ВТ модуль. Зачем
вообще ВТ? Связь с телефоном?
Григорий 18.05.18 16:10
Здравствуйте, а скажите насколько точно он меряет температуру. У меня он по ощущениям на 3-4 градуса завышает. Минусовую вроде точно выводит. Также хочу заметить, что нет смысла выводить десятые доли градуса при такой точности. Тогда температуру можно получать так temper = (temp_0>>4)+(temp_1<<4)-4; здесь отнимаю 4 так как он завышает температуру. Мне сказали, что он разогревается из-за того, что я его часто опрашиваю, нужно мол не чаще 2 раз в минуту.
Алексей 19.05.18 15:08
В документации на датчик написано, что погрешность составляет ±0.5° при измерении между -10° и +85°, а при измерении между -55° и +125° будет ±2°. Страница 2, таблица DC Electrical Characteristics, строка Thermometer Error.
Андрей 04.09.18 15:07
Можете подсказать что не так?
owire_init ();
owire_write (0xCC); owire_write (0x44); _delay_ms(250); owire_init (); owire_write (0xCC); owire_write (0xBE); temp[0]=owire_read (); temp[1]=owire_read (); znak=0; if (temp[1]&0x80)
{
temp[0] = (~temp[0])+1;
temp[1] = ~temp[1]; znak=1; }
temper = ((temp[1]<<8)|(temp[0]* 5));
lcd_clear ();
sprintf (lcd_buffer,"Temp=%i" "C
",temper);
lcd_gotoxy (0,0);
lcd_str_out (lcd_buffer);
_delay_ms(500);
Так вот выводится Temp=5C
{
temp[0] = (~temp[0])+1;
temp[1] = ~temp[1]; znak=1; }
temper = ((temp[1]<<8)|(temp[0]
_delay_ms(500);
Так вот выводится Temp=5C
Алексей 05.09.18 18:24
В aixlib есть готовые функции для датчика))
Андрей 05.09.18 19:37
Фантастика Алексей, а я по Вашему какую либу использую?
Алексей 06.09.18 19:41
Вот кино.
Николай 26.10.18 16:12
Добрый день! Перехожу с CodeVision на Atmel studio 7, неделю писал свои библиотеки, потом случайно наткнулся на ваши. Большое спасибо за огромный труд!!! Но не все так гладко: ваша функция ds1820_all() не поддерживает датчик ds18B20 - а это сейчас наиболее популярный датчик. В общем в протеусе на датчике установлена температура 34.4, а функция считывает 42.0 и только при 1-м чтении, при последующих всегда 0.00.
Алексей 26.10.18 16:43
Точно так и есть. Поэтому лучше использовать функцию WORD ds1820_read_t(BYTE *rom);
Николай 29.10.18 09:18
Спасибо за ответ! Переделал - но стало еще хуже. Теперь показывает 85.0, хотя на датчике 34.4. Причем показывает 85.0 только если вторая строка закоментирована:
ds1820_rom_code(rom);
//sprintf(str, "%02X %02X %02X %02X %02X %02X %02X %02X", rom[0], rom[1], rom[2], rom[3], rom[4], rom[5], rom[6], rom[7]);
если ее раскоментировать - то показывает 0.00. В Virtual terminal выводит адрес датчика нормально.
Как я понимаю это компилятор ведет себя неадекватно - я с таким уже столкнулся, когда писал свои функции - если я их вызывал вначале программы - работали, если в конце - то возвращали неожиданные результаты. Может в этой студии где размер стека надо увеличить?
Еще - при попытке вывода в USART заметил что на частоте 1Мгц выводилась хрень, а на 8Мгц - норм.
Если в студии что-то подобное #if _MCU_CLOCK_FREQUENCY_ == 8000000 ?
ds1820_rom_code(rom);
//sprintf(str, "%02X %02X %02X %02X %02X %02X %02X %02X", rom[0], rom[1], rom[2], rom[3], rom[4], rom[5], rom[6], rom[7]);
если ее раскоментировать - то показывает 0.00. В Virtual terminal выводит адрес датчика нормально.
Как я понимаю это компилятор ведет себя неадекватно - я с таким уже столкнулся, когда писал свои функции - если я их вызывал вначале программы - работали, если в конце - то возвращали неожиданные результаты. Может в этой студии где размер стека надо увеличить?
Еще - при попытке вывода в USART заметил что на частоте 1Мгц выводилась хрень, а на 8Мгц - норм.
Если в студии что-то подобное #if _MCU_CLOCK_FREQUENCY_ == 8000000 ?
Николай 29.10.18 09:26
Последний вопрос снимаю - есть же #define F_CPU 8000000UL
Алексей 29.10.18 19:45
Вообще 85.0 датчик выводит при первом запросе после подачи питания. Это температура у него в регистре до первого преобразования. Вообще функции запроса ром кода и температуры должны работать как часы. Я их дорабатывал фиг знает сколько раз.
Николай 30.10.18 09:57
Подскажи еще пожалуйста:
sprintf(str, "T %0.1f", (ADATA)(temperatura/10));
выводит на LCD если на датчике 34.4 :
34.0
0.000
68.00
34.0.0
162.0
34.00
34.0.0
34.000
34.06.0
но я еще ни разу не видел 34.4, подозреваю что где-то поддержку float надо включить - но где?
sprintf(str, "T %0.1f", (ADATA)(temperatura/10));
выводит на LCD если на датчике 34.4 :
34.0
0.000
68.00
34.0.0
162.0
34.00
34.0.0
34.000
34.06.0
но я еще ни разу не видел 34.4, подозреваю что где-то поддержку float надо включить - но где?
Николай 30.10.18 10:30
В общем дело не в sprintf - в самой переменной temperatura значение 340, соответсвенно и выводит 34.
Но почему не 344?? В CVAVR выводит корректно - 34.4
Но почему не 344?? В CVAVR выводит корректно - 34.4
Алексей 30.10.18 15:15
Потому что датчик настроен на вывод температуры с точностью до 0,5°.
Борис 06.01.19 12:21
какое время должно пройти между командой считывания температуры и самим считыванием.
Алексей 07.01.19 09:39
750мс
Борис 07.01.19 14:02
миллисекунды или микросекунды, а то получается ждать почти секунду.
Алексей 07.01.19 15:09
Именно миллисекунды. Вообще по хорошему нужно код пересмотреть. С разрешением +/- 0.5 градуса датчик должен преобразовывать очень быстро.
Алексей 07.01.19 15:11
В доке написано что при 9-ти битном режиме преобразование длится 94 миллисекунды.
Александр 15.01.19 19:21
Можно ли повторно залить видео. Похоже что видео удалено. Заранее спасибо!
Алексей 15.01.19 22:23
Того видео больше нет. На моем Ютуб канале есть серия видео про библиотеку. Вот ссылка.
Александр 17.01.19 19:39
Ребята кто разобрался с ds18b20 прошу помощи. Потратил три дня и никак не вижу температуру только -0.1 с реальным датчиком и в проеус всо тоже самое. Может кто глянет проект https://yadi.sk/d/ELDUjp1PaBl8Rg
Александр 17.01.19 20:04
Температуру с датчика ds18s20 читает корректно. Сломал голову. Может проблема с библиотекой 1w.h
Алексей 18.01.19 07:48
Адрес битый. Переходи на форум и я там тебе помогу.
Александр 19.01.19 12:08
Создал ветку на форуме "не могу прочитать температук ds18b20"
Алексей 19.01.19 16:32
Работаю над этим. РОМ код получаю, а температуру нет. Это какой-то косяк седьмой студии. На шестой все было пучком.
Александр 19.01.19 17:57
Студия 6.2. Ставил седьмую не понравилась. Снес, поставил 6.2
Александр 19.01.19 17:59
Может какие то хвосты седьмой остались. Хотя на работе тоже 6.2
Алексей 19.01.19 18:26
Ну я все поправил. Займусь перепилом под седьмую.
Григорий 29.03.19 11:28
Здравствуйте, Алексей.
Григорий 29.03.19 11:29
Помощь нужна по DS18B20?
Григорий 29.03.19 11:29
Или уже разобрались?
Александр 29.03.19 18:43
Не работает функция resolution температура отображается с разрешением 0.5 градуса
Александр 29.03.19 18:46
Может кому нужно сделал библиотеку для датчика абсолютного давления bmp180, и электронный эквалайзера tda7439 могу выложить
Алексей 29.03.19 20:56
Если не жалко, кидай мне на почту, опубликую. А на счет датчика эта тема давно тянется. Нет времени поправить.
Алексей 29.03.19 21:02
Добрый день, Григорий. С датчиком проблем нет. Изучен вдоль и поперек и по диагонали. Есть проблема в функции задания разрешения датчика в библиотеке axlib. В чем проблема известна, нет времени поправить.
Александр 29.03.19 21:45
Может не внимательно читал ветки, не нашел. Интересует обработчик кнопок на прерываниям, желательно опробованная версия, а так же многоуровневое меню. У кого есть предложения кидайте ссылки.
Александр 29.03.19 21:49
Делаю управление tda7439 с управлением экодер + кнопка
Алексей 29.03.19 22:37
С энкодером лучше работает stm32. У МК есть аппаратная поддержка.
Александр 29.03.19 23:02
STM32 будет следующий этап в освоении. Программа без прерываний подтормаживает, пропускает некоторые щелчки энкодера. Нашел проект микроменю, но пока не разобрался. Да и плата для стм32 пока не дешёвая
Григорий 27.06.19 10:59
Александр, не видел ваш ответ по датчику, и не смог вам ответить. У меня была проблема с ним, что он некорректно отображал температуру завышал на 2-3 градуса. Проблема была в том, что при монтаже на плату очень коротко обрезал его контакты. Надо стараться ставить его именно так как он есть, с о всей длиной ног. Так его контакты работают как теплоотвод и он стал показывать точно. Библиотеки есть для него
Моя электронка asdfgj@mail.ru, напишите мне и я вам скину. есть код для кнопок также, но через прерывания, там просто я еще дополнительно цикл организовывал. Если интересно тоже могу поделиться. Но по правильному надо использовать входы INT я думаю.
Моя электронка asdfgj@mail.ru, напишите мне и я вам скину. есть код для кнопок также, но через прерывания, там просто я еще дополнительно цикл организовывал. Если интересно тоже могу поделиться. Но по правильному надо использовать входы INT я думаю.
Александр 28.06.19 20:13
Спасибо за ответ. С датчиком разобрался ранее. Сейчас делаю делаю зарядку для тяговых аккумуляторов. С ШИМ как то быстро разобрался. Трудность возникла только с ILI 9341. У меня предложение. Так как у админа нет времени для новых проектов на AVR может будем выкладывать свои наработки в ветки форума данного сайта через файлообменник
Григорий 30.07.19 08:53
Здравствуйте, Александр. Вы случайно не работали с датчиком DHT22?