Avr — Как подключить датчик температуры к AVR


Содержание

Термометр.AVR+DS18B20.

Термометр на AtMega 8 и DS 18 B 20.

Датчик температуры DS18B20.

WH1602 или аналоги .

Резистор 4.7 кОм .

Источник питания 5в .

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

Сегодня мы соберем простейший термометр, показания которого будут выводиться на LCD WH 1602. Датчиком температуры выступит DS 18 B 20, который подключается к микроконтроллеру по однопроводному интерфейсу 1- wire .

Обозначение выводов DS18B20:

Для управления дисплеем используется 4 линии данных, что позволяет уменьшить количество задействованных контактов контроллера, и освободить их под другие нужды. Данные передаются дисплею тетрадами (по 4 бита) .

Чтение показаний температуры осуществляется по однопроводному интерфейсу 1 wire . Для удобства работы была написана простейшая библиотека на языке ассемблера.

В итоге получаем :

Любое копирование, воспроизведение, цитирование материала, или его частей разрешено только с письменного согласия администрации MKPROG . RU . Незаконное копирование, цитирование, воспроизведение преследуется по закону!

Похожие статьи

Термометр.AVR+DS18B20. : 22 комментария

Здравствуйте! У меня контроллер atmega32 LCD1602 ds18b20/
Все сделал как в статье только порты другие для lcd и датчика определил.
Слово Temperature is: появляется.
А где температура должна выводиться пишет: 0 С’ и все…
Что сделал не так.
Очень нужна помощь.

Здравствуйте!
Передача данных по шине 1-wire очень сильно зависит от временных задержек. Поэтому, проверьте тактирование контроллера (Должно быть 16 МГц, но Вы можете запросто это изменить).
Если это не поможет, пишите ещё, помогу переделать библиотеку под другую частоту.

Да конечно изменил частоту. У меня макетная плата на atmega32a где стоит кварц на 12. А где нужно указать частоту в проекте. Я работал в Atmel Studio 4, а ваш проект сделан в 6.2 я в ней только учусь…
И еще у вас функция используется printf для ее использования нужно в Atmel Studio 6.2 какие-то настройки делать.

Библиотека написана на ASM. Соответственно необходимо пересчитать задержки.
Переносил проекты из Atmel Studio 4 в Atmel Studio 6.2, ошибок не встретил. Обратно не переносил.
По поводу printf в Atmel Studio лучше будет загуглить. Там будет и с картинками и понятно)

Быть может в Вашем случае проще использовать C?

Ну проще конечно С.
Но если объясните где в коде надо изменить то думаю разберусь…Но если у Вас есть библиотека на С то было бы хорошо…

Посмотрите содержимое файла dela_16.h.
В нем определены функции задержек, для частоты в 16МГц. Их необходимо изменить для Вашей частоты. AVR Delay Calculator поможет(поищите в гугле).
Либо по образу и подобию моей библиотеки на ассемблере, напишите свою на С)

Вы можете мне помочь переделать библиотеку под мою частоту.

Так я и пытаюсь Вам помочь)
Либо ждите, и я напишу библиотеку на C.

Время через которое происходит прерывание важно. Я на 12мгц установил TCNT1=37383 В delay_16.s надо пересчитать .
global delay_480us
.global delay_60us
.global delay_420us
.global delay_750ms
.global delay_60ms
.global delay_100ms
Но если Вы на С напишите, то я подожду…

С нетерпением жду примера на С

12mГц у меня кварц. Может уже Вашу на ASM подогнать под 12 намекните на примере что в коде библиотеки надо менять с ассемблером не дружу, может научусь

Подогнал библиотеку на ASM под Вашу частоту. Так же перенес проект в 4 версию Atmel(AVR) Studio.
Ссылка в статье)
Или вот:
http://mkprog.ru/wp-content/uploads/2020/04/AVR_Thermometr_12.zip

Да спасибо увидел!
Вопрос:
В инициализации счетчика
Стоит TCNT1=60000;
А в самой функции прерывания TCNT1=49910;
Это правильно.

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

У меня макетка с atmega32a. Порт PORTD не могу использовать свободен PORTA. Пытаюсь подключить в проекте LCD на порт А мне куча ошибок вылетает…:
Build started 25.4.2020 at 10:26:15
avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT AVR_Thermometr_12.o -MF dep/AVR_Thermometr_12.o.d -c ../AVR_Thermometr_12.c
In file included from ../AVR_Thermometr_12.c:13:0:
../lcd_new.h: In function ‘lcd_init_4d’:
../lcd_new.h:58:2: error: ‘DDRA’ undeclared (first use in this function)
../lcd_new.h:58:2: note: each undeclared identifier is reported only once for each function it appears in
../lcd_new.h:58:17: error: ‘PORTA7’ undeclared (first use in this function)
../lcd_new.h:58:33: error: ‘PORTA6’ undeclared (first use in this function)
../lcd_new.h:58:49: error: ‘PORTA5’ undeclared (first use in this function)
../lcd_new.h:58:65: error: ‘PORTA4’ undeclared (first use in this function)
../lcd_new.h:60:19: error: ‘PORTA0’ undeclared (first use in this function)
../lcd_new.h:61:20: error: ‘PORTA1’ undeclared (first use in this function)
../lcd_new.h:63:5: error: ‘PORTA’ undeclared (first use in this function)
../lcd_new.h: In function ‘lcd_write_character_4d’:
../lcd_new.h:107:5: error: ‘PORTA’ undeclared (first use in this function)
../lcd_new.h:107:24: error: ‘PORTA1’ undeclared (first use in this function)
../lcd_new.h:108:24: error: ‘PORTA0’ undeclared (first use in this function)
../lcd_new.h: In function ‘lcd_write_instruction_4d’:
../lcd_new.h:115:5: error: ‘PORTA’ undeclared (first use in this function)
../lcd_new.h:115:25: error: ‘PORTA1’ undeclared (first use in this function)
../lcd_new.h:116:24: error: ‘PORTA0’ undeclared (first use in this function)
../lcd_new.h: In function ‘lcd_write_4’:
../lcd_new.h:123:3: error: ‘PORTA’ undeclared (first use in this function)
../lcd_new.h:123:22: error: ‘PORTA7’ undeclared (first use in this function)
../lcd_new.h:124:22: error: ‘PORTA6’ undeclared (first use in this function)
../lcd_new.h:125:22: error: ‘PORTA5’ undeclared (first use in this function)
../lcd_new.h:126:22: error: ‘PORTA4’ undeclared (first use in this function)
../lcd_new.h:128:23: error: ‘PORTA0’ undeclared (first use in this function)
make: *** [AVR_Thermometr_12.o] Îøèáêà 1
Build failed with 20 errors and 0 warnings…

Сделал проект с нуля ошибки исчезли.
Но опять показывает:
Temperature is:
0 C’

Что не так… :-(
Что-то беда у меняя какая-то немогу научиться измерять температуру а мне нужно!

Уже и не знаю чем Вам помочь.Ждите, напишу на C.На выходных скорее всего.

Жду на С мне будет легче разобраться конечно…

очень познавательно, не все еще понимаю, читаю, сам программист но на php))) решил попробовать себя в микроконтроллерах….у вас на сайте информация написана доступным мне языком без всяких там «да на Си только быдло пишет! пишите на асме» ) Гы) Еще раз спасибо!

Прикладное программирование с нуля.

AVR, STM, Android, IoT. Встраиваемые системы.

Датчик влажности DHT11.Подключаем к AVR.Часть 5. Шаг №20

Обновлено 5.01.16. Всем привет. Итак продолжим наработку нашего проекта. В предыдущей статье мы рассмотрели низкоуровневые операции с SD-картой. Но прежде чем мы начнем использовать файловую систему, мы добавим в наш проект и рассмотрим датчик влажности и температуры DHT 11, который применяется исключительно для бытовых целей в помещении. Как вошло уже в правило, ознакомимся с теорией.


Теперь немного о датчиках. Датчик влажности, тот же гигрометр. может иметь разные принципы работы: емкостные, резистивные, термисторные, оптические. Я же для бытовых целей взял самый дешевый – резистивный.

Что такое резистивный датчик?. Датчик такого типа представляет из себя два электрода нанесенных на подложку (бифилярная намотка), а сверху этих электродов наносится слой материала с достаточно низким сопротивлением (часто используют оксид алюминия), которое зависит от влажности, хорошо впитывает его и следовательно меняет свое удельное сопротивление. Т.е. сопротивление обратно пропорционально влажности. Время отклика для большинства датчиков от 10 до 30 секунд. Резистивные датчики не является полностью резистивные за счет емкостного эффекта в диапазоне более 10-100 МОм.

Перейдем непосредственно к нашему датчику. На рисунке ниже изображен датчик DHT11 в разобранном состоянии, вид спереди и вид сзади.

На некоторых ресурсах пишут что данный прибор имеет емкостный датчик, на некоторых – резистивный. В технической документации четко указано – резистивный тип. Этот датчик включает в себя резистивный компонент измерения влажности и компонент измерения температуры с отрицательным температурным коэффициентом (NTC), которые подключены к высокопроизводительному 8-битному микроконтроллеру. Каждый датчик DHT11 строго калибруется, коэффициенты калибровки хранятся в виде программ в однократно программируемой энергонезависимой памяти, и используются во внутренних процессах обработки сигнала.

Ниже представлена схема подключения датчика и таблица с его характеристиками. Протокол 1-Wire он не поддерживает (а жаль).

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

Теперь рассмотрим описание временных задержек для работы с датчиком.

Итак сперва запомним что датчик всегда находится в спящем режиме при высоком состоянии на линии. Чтобы общаться с ним нам необходимо его разбудить, получить подтверждение и принять 40 бит данных. В документации описаны временные задержки. Вот по ним мы и начнем писать код

Шаг №1. Инициализация.

Процесс инициализации начинается с подтягивания линии на 18 мс, далее отпускаем на 20-40 мкс и переводим ножку микроконтроллера в режим чтения. В принципе очень простые операции.

После того как перевели контроллер в режим чтения, ждем когда начнется 0, далее задержка и проверяем на высокое состояние. Все датчик откликнулся – живой.

Шаг №3. Прием данных.

В передаче данных, в принципе также все просто. Здесь различие в бите определяется задержкой высокого состояния. Первые 8 бит влажность, 2- тоже влажность, но десятые , которые он не измеряет. 3и 4-й температура соответственно. 5-й – бит контрольной суммы, который должен быть равен сумме всех 4-х байтов.

Ну и последнее, после последнего переданного бита датчик передает ноль 50 мкс. И дальше входит в режим ожидания.

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

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

Что же такое универсальность? Это возможность подключить, задействовать код к другому контроллеру и к другим ножкам. Для это мы в программе используем директиву препроцессора #define и переопределение типов typedef. Они являются почти аналогом друг-друга за исключением того что #define обрабатывается перед компиляцией путем простой замены всех вхождений, а с помощью typedef можно объявить имя функции или массива. Более подробно в следующей статье (№21).

Код я искал исключительно на Си. Но просторы интернета навязчиво выдают библиотеку под Arduino, который является электронным конструктором, а его среда –это использование диалога Processing/Wiring.(смесь языков СИ и Си++). Это не подходит….

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

Измерение температуры при помощи NTC термистора и микроконтроллера AVR

Автор: Погребняк Дмитрий

Click here to read this article in English.

Одним из вариантов для измерения температуры является использование термисторов. Среди преимуществ термистора можно выделить большое значение температурного коэффициента, то есть значительное изменение сопротивления в зависимости от температуры (порядка 2-10% на Кельвин). Термисторы бывают двух типов: с положительным температурным коэффициентом (PTC, Positive Temperature Coefficient), то есть увеличивающие своё сопротивление с увеличением температуры, и с отрицательным (NTC, Negative Temperature Coefficient) – уменьшающие сопротивление с возрастанием температуры. Речь в данной статье пойдёт про вторые, и про их использования для измерения температуры в сочетании с микроконтроллерами AVR

Характеристика NTC термистора

Термисторы характеризуются рядом параметров, такими, как максимальный допустимый ток, точность, сопротивление при определённой температуре (как правило, при 25°С). Одним из параметров, характеризующим степень изменения сопротивления в зависимости от температуры является коэффициент температурной чувствительности, обозначаемый B. Этот коэффициент рассчитывается на основе значений сопротивления при двух конкретных значениях температур. Во многих случаях этими температурами выбираются 25°С и 100°С. Обычно температуры, использованные при вычислении коэффициента указываются после буквы, например B25/100. Коэффициент B измеряется в Кельвинах и вычисляется по следующей формуле:

где R1 и R2 — значения сопротивлений при температурах соответственно T1 и T2, выраженных в Кельвинах.

Из этой формулы следуют и обратные:

Вычисление температуры

Термисторы обладают высокой степенью нелинейности параметров, и термисторы различных моделей, даже при одинаковых значениях параметра B25/100 могут по разному изменять сопротивление в зависимости от температуры. Поэтому формула [3] может лишь приблизительно оценить температуру. Кроме того, такая формула подразумевает сложные вычисления, которые требуют много процессорного времени, что часто является неприемлемым. Более простым и эффективным подходом является хранение таблицы, в которую заносятся предварительно рассчитанные значения, возвращаемые АЦП при тех, или иных температурах. Для экономии памяти можно хранить значения только для некоторых точек, искать их в таблице двоичным поиском, а промежуточные значения получать линейной интерполяцией. Для измерений температуры окружающего воздуха с точностью до 0.3°C, достаточно хранить значения с шагом 5°C. Если значения лежат в пределах 16 бит (и занимают 2 байта), то для хранения такой таблицы для диапазона измеряемых температур от -30 до 70 градусов потребуется всего 40 байт. Точность измерений можно повысить, уменьшив шаг таблицы. Так при шаге 2°C можно добиться точности до 0.1°C на широком диапазоне измерений.

Производители термисторов, как правило, приводят таблицы показывающие изменение сопротивления в зависимости от температур. Значения в этих таблицах также привязаны к сетке температур с некоторым шагом (например, 5°C). Используя формулы [1] и [2] можно с достаточной точностью интерполировать табличные значения.

Схемы подключения


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

Схема A
Схема B
Схема C
Схема D

Наиболее простым вариантом подключения является схема A. При выборе номинала резистора RA примерно равным сопротивлению термистора в районе измеряемых температур, значения U будут изменяться ближе к линейным, что обеспечит большую точность при интерполяции табличных значений.

Выбирая номиналы RA и термистора, следует учесть, что протекающий через термистор ток вызывает его нагрев и, как следствие, искажение показаний. Желательно чтобы мощность на термисторе не превышала 1 мВт. А значит, при напряжении U = 5В, RA должен быть как минимум, 10 килоОм. Сопротивление термистора в измеряемом диапазоне должно иметь примерно тот же порядок.

Схема B призвана ограничить мощность, рассеиваемую на термисторе.

Схемы C и D являются обратными к A и B. Их имеет смысл использовать, если требуется измерять низкие температуры, когда референтное значение АЦП (Uref) ниже U.

Подключение к АЦП микроконтроллера ATmega

Подключение АЦП микроконтроллеров ATmega


У контроллеров ATmega для снижения шумов используется отдельная линия питания для модуля АЦП. Инструкция рекомендует подключать эти входы через фильтр: индуктивность L = 10мкГн, и конденсатор C2 = 0,1мкФ.

Микроконтроллер может использовать либо внешнее референтное напряжение для АЦП, либо внутреннее (2,56В или 1,1В), либо, в качестве такового, использовать напряжение питания АЦП: AVCC. При использовании внешнего напряжения, оно должно быть подано на вход AREF. При использовании AVCC, или внутреннего напряжения 2,56В, между этим входом и землёй должен быть размещён конденсатор (на схеме C1). Инструкция не даёт чёткого указания для выбора ёмкости конденсатора, рекомендую использовать керамический конденсатор 0,1мкФ и более.

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

Дополнительно, для подавления шумов возникающих на линиях, можно установить конденсатор C3 в диапазоне 1-100нФ.

Следует учесть, что помимо модуля АЦП, вход AVCC запитывает также некоторые из портов ввода/вывода (как правило, на тех же выводах, что используются для АЦП). Использование этих портов на вывод и подключение к ним нагрузки может создать дополнительные шумы в работе АЦП.

Чтобы нивелировать шумы, возникающие на АЦП, рекомендую провести замеры несколько раз подряд и просуммировать полученные значения. В микроконтроллерах ATmega АЦП – 10-разрядный. Просуммировав результаты 64 подряд идущих измерений, результат остаётся в пределах 16-битного беззнакового целого, что не потребует дополнительной памяти для сохранения таблицы значений. При большем числе измерений также можно оставаться в пределах 16 бит, соответствующим образом сдвигая или деля результат.

Расчёт таблицы значений

Вашему вниманию предлагаю скрипт для онлайн расчёта таблицы значений АЦП.

Расчёт значений ведётся либо по двум значениям температур и сопротивлений, либо вводится списком, либо используется одна из предзагруженных R/T характеристик. В настоящее время загружены R/T характеристики термисторов фирмы Siemens/EPCOS. Выберите подходящую из списка.

Загруженные характеристики даны с шагом 5°С, при выборе меньшего шага сетки, значения получаются путём интерполяции по формулам [1] и [2] двух ближайших значений из таблицы.

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

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

Чтобы узнать подходящий тип R/T характеристики для вашего термистора, скачайте документацию, данную заводом изготовителем.

Сводная таблица для некоторых моделей термисторов Siemens/Epcos приведена ниже. Нажмите на код R/T характеристики, чтобы подгрузить параметры в форму ниже:

Код Сопротивление при 25°С, кОм R/T характеристика B25/100, К
B57891S , выводной 4,5мм (datasheet, pdf)
B57891S0222+008 2,2 1008 3560
B57891S0502+008 5 2003 3980
B57891S0103+008 10 4901 3950
B57891S0203+008 20 2904 4300
B57891S0104+008 100 4003 4450
B57891M , выводной 3,5мм (datasheet, pdf)
B57891M0102+000 1 1009 3930
B57891M0152+000 1,5 1008 3560
B57891M0222+000 2,2 1013 3900
B57891M0332+000 3,3 2003 3980
B57891M0472+000 4,7 2003 3980
B57891M0682+000 6,8 2003 3980
B57891M0103+000 10 4901 3950
B57891M0153+000 15 2004 4100
B57891M0223+000 22 2904 4300
B57891M0333+000 33 2904 4300
B57891M0473+000 47 4012 4355
B57891M0683+000 68 4012 4355
B57891M0104+000 100 4003 4450
B57891M0154+000 150 2005 4600
B57891M0224+000 220 2005 4600
B57891M0334+000 330 2007 4830
B57891M0474+000 470 2006 5000
B57164K , выводной 5,5мм (datasheet, pdf)
B57164K0471+000 0,47 1306 3450
B57164K0681+000 0,68 1307 3560
B57164K0102+000 1 1011 3730
B57164K0152+000 1,5 1013 3900
B57164K0222+000 2,2 1013 3900
B57164K0332+000 3,3 4001 3950
B57164K0472+000 4,7 4001 3950
B57164K0682+000 6,8 2903 4200
B57164K0103+000 10 2904 4300
B57164K0153+000 15 1014 4250
B57164K0223+000 22 1012 4300
B57164K0333+000 33 1012 4300
B57164K0473+000 47 4003 4450
B57164K0683+000 68 2005 4600
B57164K0104+000 100 2005 4600
B57164K0154+000 150 2005 4600
B57164K0224+000 220 2007 4830
B57164K0334+000 330 2006 5000
B57164K0474+000 470 2006 5000
B57540G , выводной, стеклянный «капля» 0,8мм (datasheet, pdf)
B57540G0502+000, +002 5 8402 3497
B57540G1103+000, +002 10 8307 3492
B57540G1103+005, +007 10 7003 3625
B57540G0203+000, +002 20 8415 4006
B57540G1303+005, +007 30 7002 3988
B57540G0503+000, +002 50 8403 4006
B57540G1104+000, +002 100 8304 4092
B57540G0234+000, +002 230 8405 4264
B57540G0145+000, +002 1400 8406 4581
B57551G , выводной, стеклянный «капля» 1,8мм (datasheet, pdf)
B57551G0202+000, +002 2 8401 3436
B57551G1103+000, +002 10 8307 3492
B57551G1103+005, +007 10 7003 3625
B57551G1303+005, +007 30 7002 3988
B57551G1104+000, +002 100 8304 4092
B57621С5 , SMD 3,2х1,6мм (datasheet, pdf)
B57621C5102+062 1,0 3206 3450
B57621C5472+062 4,7 1309 3520
B57621C5103+062 10 1010 3530
B57621C5153+062 15 1008 3560
B57621С0 , SMD 3,2х1,6мм (datasheet, pdf)
B57621C0222+062 2,2 1308 3060
B57621C0332+062 3,3 1309 3520
B57621C0472+062 4,7 1309 3520
B57621C0103+062 10 1010 3530
B57621C0153+062 15 1008 3560
B57621C0223+062 22 1008 3560
B57621C0333+062 33 2003 3980
B57621C0473+062 47 2001 3920
B57621C0683+062 68 2001 3920
B57621C0104+062 100 4901 3950
B57621C0154+162 150 2903 4200
B57621C0224+062 220 2903 4200
B57621C0334+062 330 1014 4250
B57621C0474+062 470 1014 4250
B57703M , выводной 10мм, с «ухом» 8,5×3,7мм (datasheet, pdf)
B57703M0502G040 5 8016 3988
B57703M0103G040 10 8016 3988
B57703M0303G040 30 8018 3964

Форма для он-лайн расчёта значений АЦП

Данные для таблицы
T1 °С
R1, cопротивление при T1 килоОм
T2 °С
R2, сопротивление при T2 килоОм
Данные для таблицы:R/R1
начиная с T2, с выбранным шагом сетки.
Разделитель значений — запятая.
BT1/T2 K
Схема включения термистора
Номинал резистора RA килоОм
Номинал резистора RB килоОм
Разрядность АЦП
Множитель результата АЦП
U, напряжение на входе В
Uref, референтное напряжение АЦП В
Рассчитать с °С по °С
Шаг сетки
Построить таблицу
T,°С R/R1 R,килоОм U,В I,мкА P,мВт U/Uref ADC E,°С

Пояснения к таблице:

жирным выделены значения R/R1 и R, полученные на основе табличных. Обычным шрифтом обозначены значения полученные интерполяцией или экстраполяцией по формулам.

ADC – округлённое значение на выходе АЦП, с учётом множителя. Значения, выходящие за предел измерений АЦП, не отображаются.

I,мкА — ток в цепи.

P,мВт — мощность, рассеиваемая на термисторе.

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

Код, соответствующий таблице

Пример использования

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

Описание работы с индикатором смотрите в другой моей статье.

AVR Lab устройства на микроконтроллерах AVR

Форум по AVR

Шина 1-wire, пример термометра на DS18B20 и микроконтроллере AVR, WH1602, ЖКИ

Шина 1-Wire была запатентована компанией Dallas Semiconductor, и была призвана наладить полудуплексную связь всего по одному сигнальному проводу. Также возможны варианты использования паразитного питания по линии данных (потому что во все микросхемы 1-Wire встроен конденсатор номиналом 800пФ).

Т.е. для связи с устройством 1-Wire требуется всего 2 провода, один сигнальный, второй – заземление. Компания Dallas (и позже купившая ее Maxim) выпускают много всякий устройств с шиной 1-Wire. Это всякие термометры, календари, датчики, память, отдельно хочу отметить электронные таблетки iButton успешно используемые в устройствах идентификации. В свое время у меня долго не слаживалось поработать по шине 1-Wire, то не было с кем связываться, то не хотелось и казалось сложным, а то и просто не заработало.

В конце концов, погоняв код в VMLab понял, что эта шина очень чувствительна к таймингам и к номиналу резистора, подтягивающего линию данных. Первым результатом успешной работы с 1-Wire у меня стал цифровой термометр на базе датчика DS18B20 и микроконтроллера ATmega8, данные о температуре выводились на символьный ЖКИ WH1602A. О чем я хочу написать заметку.
Рассмотрим шину 1-Wire поподробнее.

Каждое устройство 1-Wire имеет уникальный ROM код, так называемый адрес. На шине должно быть одно ведущее устройство (master) и одно или несколько ведомых (slave). Количество ведомых ограничено адресным пространством и емкостью шины. При начале обмена данных, ведущий должен проверить наличие на шине хоть кого-то. Для этого мастер на протяжении 480мкс должен удержать логический ноль на шине (так называемый Reset pulse), «отпустить» шину минимум на 60мкс и посмотреть какой уровень присутствует на линии данных. Если это низкий уровень – на шине есть устройство 1-wire. Если высокий – шина пуста. Это так называемый Presence pulse.

Далее следует передать байт-команду устройствам. Для этого ознакомимся с принципом передачи данных по 1-Wire. Передача байта разбита на так называемые временные слоты (60-120мкс), один временной слот служит для передачи одного бита. Данные передаются последовательно, начиная с младшего бита. Для передачи битов от ведущего к ведомому используется верхняя (на картинке) схема:

Для передачи логического 0, ведущий должен удержать на шине нулевой потенциал на протяжении всего временного слота (60-120мкс), а после отпустить шину, для сигнализации окончания временного слота. Для передачи логической 1, ведущий должен удержать шину в нулевом положении чуть более 1мкс (но не больше 15мкс), а после отпустить шину на весь оставшийся временной слот.

Для передачи данных в обратном направлении, от ведомого в ведущему используется нижняя (на картинке) схема. Микроконтроллер удерживает низкий уровень на протяжении чуть более 1мкс, после чего отпускает шину и ждет примерно 30мкс и проверяет состояние на шине, если там высокий уровень – то передана логическая единица, если низкий – то передан логический ноль.
В принципе все просто, но вот с этими задержками и возникают трудности. Теперь рассмотрим схему, по которой можно выжать данные о температуре из DS18B20. Сначала проверим наличие DS18B20 на шине с помощью Presence pulse. После дадим команду 0хсс (игнорировать ROM код, т.е. все следующая команда предназначена всем ведомым на шине) и 0х44 (начать преобразование), после чего выжидаем пока датчик преобразует температуру в код и после команда 0хсс, 0хbe (выдать температуру) принимаем 2 байта кода температуры. Вообще такой подход не универсален, если на шине присутствует несколько устройств, то получиться каша. Для того, чтобы не было каши, используют ROM код, и устройство откликается только на свой ROM. В случае с iButton, ROM код написан прямо на корпусе устройства. С DS18B20 такого не наблюдается и приходиться считывать ROM с помощью команды 0х33. Но возникает проблема, как считать ROM код, если на шине 2 устройства и не один из их ROM неизвестен. Для этого существует специальный алгоритм, про который можно почитать в даташите DS18B20. Здесь его описывать не буду, потому что у меня только одно устройство 1-wire на шине, а сам алгоритм громоздкий и писать его без цели не хочется. Как разживусь на 2-й датчик DS18B20 – так и напишу про алгоритм нахождения ROM кодов 
Для работы с 1-wire предлагают частично использовать аппаратный UART, но так не спортивно, тратить ценный UART на какой-то 1-Wire, который можно реализовать на любой ножке микроконтроллера?? Поэтому напишем функции работы с 1-Wire, привязанные к заданной ножке порта, например к PB0. Только сперва рассмотрим схему подключения DS18B20 к микроконтроллеру ATmega8.

Микроконтроллера тактируется от внутреннего RC генератора на 4МГц. Резистор R1 – подтягивающий на 6,8кОм, R2 – ограничительный на 1кОм, R3 – 17 Ом, потенциометр VR1 – 10кОм. Конденсаторы С5,С7 – электролиты, по 100 и 200мкф соответственно. С4,С6 – керамика на 0.1мкф.
Теперь рассмотри функции работы с DS18B20:

delays правильно выставлены?


Есть вопрос (а может и замечание) по delays при чтении из датчика. Если верить читать родной даташит, то в нем написано: «Output data from the DS18B20 is valid for 15µs after the falling edge that initiated the read time slot. Therefore, the master must release the bus and then sample the bus state within 15µs from the start of the slot.»
Т.о., если мой ангицкий меня не подводит, то мы должны успеть прочитать бит в течении 15мс, а не по истечении. И как написано в том же даташите, то надо как можно сильнее сократить время на пуллдаун и на пуллап.
Поправьте, если я не прав.

Avr — Как подключить датчик температуры к AVR?

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

У себя для освоения работы с датчиком использовал микроконтроллер 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

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

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

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

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

1wwrite &H CC ‘ Выдаем команду чтения ПЗУ
1wwrite &H 44 ‘ Запуск измерения

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

1wreset
1wwrite &H CC
1wwrite &H BE ‘ Команда чтения ОЗУ датчика

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

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

If Byte1 > 248 Then ‘ Проверка на отрицательность температуры
Byte0 = &H FF — Byte0
Byte1 = &H FF — 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

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

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

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

Lcd Chr ( 223 ) ; «C» ‘ Сhr(223) — символ «градус»

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

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

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

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

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

Avr — Как подключить датчик температуры к AVR?

Контроллер температуры в погребе на ATmega

Автор: kitekat
Опубликовано 21.09.2015
Создано при помощи КотоРед.

Каналов температуры – 3
Каналов влажности – 1
Каналов управления вентилятором – 1
Отображение – 1 канал, последовательно.
Применяемый МК – ATmega8 или ATmega48/88
Температурные датчики – DS18B20 (2 шт)
Датчик влажности – DHT11 или DHT21

Так получилось, что я поселился в частном доме. Человек я сугубо «квартирный», поэтому многие вещи для меня теперь являются проблемными. Например, погреб в доме оказался слишком теплым. Поэтому было решено сделать термометр, отображающий температуру в погребе. Дальнейшее исследование выявило наличие вентиляции, поэтому в задачу добавилось управление вентиляторами. В итоге первоначальная идея переродилась в полноценный контроллер управления температурой в погребе.
Итак, окончательная концепция – три датчика температуры (на полу, под потолком и наружный), датчик влажности, индикация температуры на 7-ми сегментном цифровом индикаторе, и вентиляторы на приточной и вытяжной трубах. Вывод различных значений производится последовательно, в течение нескольких секунд, с дополнительной индикацией, какой именно датчик сейчас используется.


Поскольку всяческих «исполнительных устройств» планировалось достаточно много, контроллер был выбран многоногий — чтобы избежать дополнительных регистров и усложнения схемы. Популярная ATmega8 вполне нам подходит.

Устройство представляет собой МК, окруженный «исполнительными устройствами». Схема выполнена в виде отдельных блоков, все соединения между блоками не нарисованы явно, а обозначены соответствующими метками на выводах. Это сделано для упрощении разводки платы. Здесь применяется известный прием – сначала приблизительно разводим плату, смотрим, где и как удобно соединить ножки МК с другими элементами, и затем правим схему – переставляем метки на выводах. А далее, уже глядя на готовую схему, пишем программу. Этот прием хорошо работает в «сквозных» системах проектирования, с контролем списка связей (нетлист), однако совсем не годится для любителей SprintLayout.

Транзисторный буфер из Q1 и Q2 требует отдельного пояснения.

Датчики температуры – цифровые устройства DS18B20, работающие по протоколу 1-wire. Эти датчики способны работать на общей шине, каждый имеет уникальный адрес. К сожалению, в МК AVR отсутствуют аппаратные средства поддержки 1-wire. Однако есть промежуточные решения, основанные на использовании интерфейса UART – об этом идет речь в Application Note от ATMEL AVR318 [3] . Вместо управления одним пином МК и переключением его то на вход, то на выход (как это требуется по стандарту 1-wire) используется выход TX и вход RX, объединенные с помощью буферных транзисторов в некое подобие одного двунаправленного вывода. Временные диаграммы интерфейса 1-wire очень похожи на прием-передачу байтов по интерфейсу UART. Поэтому программная обработка протокола 1-wire заключается в приеме-передаче определенных символов.

На одну шину можно «повесить» несколько датчиков, а затем их опрашивать программно. Первоначально планировалось использовать три датчика DS18B20, однако появилась мысль измерять также влажность. Влажность можно измерить также цифровым датчиком DHT11 или DHT21, в котором присутствует также и датчик температуры. Однако DHT, хоть и также работают по «одному проводу», но не совместимы с 1-wire и не могут работать несколько на одной шине. Поэтому было решено оставить два датчика DS18B20 на одной шине и один DHT11 на другой. Решение ограничиться всего двумя изделиями от Dallas/Maxim позволило также упростить схему и упростить программу в части автоопределения датчиков.

Блоки R14-D6-D7 и R26-D8-D9 призваны защитить входы МК от помех, наводимых на длинных линиях проводов, ведущих к датчикам.

Все остальные выводы МК используются только как обычные порты ввода-вывода (general purpose input-output), без специальных функций. Десять пинов отведены под 3-х разрядный 7-ми сегментный индикатор на светодиодах. 4 пина – под индикацию режимов отображения датчиков. Остальные выводы распределены под управление вентиляторами, включение аварийной «пищалки» и перемычку нумерации датчиков.

Транзистор Q3 управляет вентиляторами. Транзистор Q4 включает «пищалку».
Резисторы R27, R28, R29 — виртуальные, нужны только для моделирования схемы в Proteus, на плате не устанавливаются.

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

Программа представляет собой простое подобие флагового автомата. TIMER0 считает «тики», выставляет флажки таймаутов, которые обрабатываются в главном цикле. Функции работы с 1-wire напрямую списаны с того же Application Note AVR318 [4] – вариант работы с портами UART по опросу (polled). Вариант с прерываниями достаточно сложен и в данном изделии было решено не применять.

Программа на Си написана в среде AtmelStudio 4.6 и WinAVR.

Большой блок текста в первой части программы – строки, начинающиеся с #define – предопределение различных опций, таймаутов, условий включения вентиляторов, макросы работы с пинами, макросы вывода цифр на 7-ми сегментник.
Основное внимание при изменении программы следует обращать на определения макросов работы с портами. Все они сгруппированы по назначению. Каждый пин участвует в трех макросах – включение/выключение «исполнительного устройства», и инициализация пина.
Блок определений и функций, начинающийся с OWI_ (One Wire Interface) – списан напрямую из AVR318 (polled) [4] .

Вывод в выходные порты МК делаются побитовыми операциями SBI и CBI – это сделано для универсальности назначения выводов. Поэтому для формирования цифр на дисплее используются не массив значений, выводимых в порты, а массив указателей на функции вывода различных цифр.

Алгоритм достаточно простой. Вначале опрашивается шина 1-wire, и определяются адреса (идентификаторы) датчиков. Адреса заносятся в массив. Далее запускается основной цикл, где по определенным таймаутам опрашиваются датчики и выводятся цифры на дисплей. Датчикам DS сначала выдается команда на преобразование температуры в функции poll_termo(), а затем через определенный таймаут (не менее 94мс для 9-битного режима) выдается команда на прием значения температуры функцией get_termo(). Датчик DHT11 [6] работает проще – после специального сигнала от МК датчик сразу начинает слать данные, и их остается только принять. Пока было решено отказаться от чтения/вычисления CRC от датчиков DS, и ограничиться 9-битным режимом для отображения целых чисел градусов.

При определенных условиях включается или выключается вентилятор. Главное условие – если наружная температура больше 4 и меньше 15 и внутренняя температура (внизу) выше на два градуса наружной.
При падении внутренней температуры внизу до 1 градуса дополнительно включается прерывистый звуковой сигнал, а также мигают цифры индикатора – для привлечения внимания.
Кроме всего, при старте устройство исполняет функцию prestart(), в которой на несколько секунд зажигаются все светодиоды.

Детали и конструкция.

Устройство собрано на односторонней печатной плате размерами 100х83мм. При разработке использовались детали как выводные, так и SMD. DIP-корпус МК в данном устройстве был выбран только по наличию его у автора. На плате располагаются МК, дисплей, индикаторы режимов и стабилизатор питания. Внешние устройства подключаются кабелем «витая пара» из 4 пар, посредством разъема RJ45.

Защитные диоды в этой первоначальной ревизии платы ошибочно были забыты.

Все устройство собрано внутри металлического корпуса от компьютерного привода CD-ROM. На верхней крышке вырезаны отверстия под цифровой дисплей и индикаторы режимов. В качестве боковин можно также использовать пластиковые заглушки от 5-дюймовых отсеков компьютерных корпусов.

В качестве блока питания использовался внешний блок 9в/2А от какого-то устройства, вы можете использовать любой, который способен выдавать 9-12в и ток не ниже 0.3-0.5А.

Питание МК осуществляется стандартно через стабилизатор 7805, уложенный прямо на плату, что будет давать подобие радиатора.
Конденсаторы C1. C2 нужно располагать в непосредственной близости от стабилизатора, C3 рядом с выводами питания МК, С4 рядом с выходным разъемом.
На плате также присутствует разъем IDC10 для внутрисхемного программирования.

Светодиоды для индикации режимов измерения – разных цветов. Автор применил такие:
Температура вверху, под потолком – красный
Температура внизу, на полу – зеленый
Температура снаружи – белый,
Влажность – синий
Индикатор работы вентиляторов – желтый
В связи с разной субъективной яркостью светодиодов разных цветов токоограничивающие резисторы в их цепях разных номиналов.

«Пищалка» — с генератором, на 9-12в.

Примененный 7-ми сегментный индикатор – 3-хразрядный, с общим катодом. Автор использовал индикатор с цифрами 0.56” (13мм) высотой.
При необходимости легко заменяется на «общий анод» без переделки платы, требуется только использовать другую прошивку, или перекомпилировать программу, предварительно определив константу COMMON_ANODE. Для управления катодами/анодами транзисторы не применялись, поэтому токоограничивающие резисторы в цепях сегментов не должны быть менее 600 Ом, чтобы обеспечить ток сегмента не более 5мА. Расчет простой – максимальный ток через один пин МК – 40мА, сегментов 7, значит, ток светодиода сегмента не должен превышать 5,7мА.

МК – Atmega8 или ATmega48/88/168/328, которые полностью совместимы по ножкам, но слегка различаются по именам регистров. В программе есть анализ предопределенной переменной имени микроконтроллера, которая задается в свойствах проекта AtmelStudio.

Датчик влажности – DHT11 или DHT21, они также используются как верхний термометр Следует помнить, что DHT11 измеряет только положительную температуру, в отличие от DHT21. Показания данного датчика только выводятся на дисплей, в программе управления вентиляторами не участвуют.

Вентиляторы – от компьютерных блоков питания, на 12в, две штуки, в схеме не участвуют. Полевой транзистор Q3 в корпусе TO252 или TO263 – также был снят с материнской платы компьютера, его точное наименование не важно. Это любой N-канальный мощный MOSFET с логическим управлением.

Остальные транзисторы — npn общего назначения, например, BC547 или BC847.

Монтаж и наладка.

После установки всех деталей на плате необходимо «залить» прошивку в МК, и прошить фьюзы.
Основное отличие от фабричных установок:
ATmega8 – тактирование от внутреннего генератора 8МГц (CKSEL3:0 = 0100).
ATmega48/88 – убрать деление тактовой на 8 (CKDIV8 = 1).

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

Внешние датчики и вентиляторы подключаются 8-ми проводным кабелем «витая пара» для монтажа компьютерных локальных сетей Ethernet.
Автором был назначен такой порядок проводов,аналогично стандарту EIA/TIA-568B. 1-я пара (оранжевая, контакты 1-2) – на датчики DS, 2-я пара (зеленая, контакты 3-6) – на датчик DHT, 3-я пара (синяя, контакты 4-5) – на вентиляторы, 4-я пара (коричневая, контакты 7-8) – на питание +5в. Для монтажа «вилки» на кабель требуется специальный обжимной инструмент, можно попросить обжать кабель в компьютерных магазинах; либо отрезать от фирменного «патч-кабеля». Разводка и присоединение датчиков непосредственно в погребе была произведена по стенам и потолку, с применением монтажных коробок для монтажа электропроводки.

Вентиляторы подключаются своим плюсом (красный провод вентилятора) на провод +12в (контакт 5 разъема X3), а своим минусом (черный провод) — на провод FAN (контакт 4 разъема X3).

Ответственная операция – монтаж датчиков на проводах. Автор использовал кабель неэкранированной витой пары, что используется для монтажа компьютерных локальных сетей. Однако сами выводы датчиков рекомендуется сначала припаять к мягкому монтажному проводу, а уже потом этот провод припаивать непосредственно к достаточно жесткому проводу витой пары. Промежуточный датчик DS18B20 требуется монтировать «петлей» хотя бы по линии данных (DQ), хотя вполне возможна работа и при монтаже «звездой». Очень желательно разместить дополнительные керамические конденсаторы емкостью 0.1-0.3 мкФ прямо на выводах датчиков между питанием и «землей» (на схеме не показаны). Перед пайкой датчиков воспользуйтесь даташитом [5,6] на конкретный датчик для определения выводов. Выводы и места пайки изолируются термоусадкой. Датчик DHT герметизировать не нужно – он должен мерить влажность. А датчики DS18B20 и место присоединения кабеля требуется герметизировать, не забывая также места пайки. Например, упаковать в несколько слоев термоусадочной трубки, замазать «холодной сваркой». Наилучшим вариантом будет отрезок медной или стальной трубки, в которую плотно входит корпус датчика. Трубка с датчиком и кабелем заливается эпоксидной смолой.

При первом запуске после присоединения датчиков требуется определить соответствие датчиков DS и их очередности. Для наглядности требуется явная разница в температуре датчиков – нужно один из них нагреть или охладить. Если показания индикатора соответствуют порядку датчиков – то нам повезло, мы угадали. Если показания наоборот – то требуется поставить перемычку JP1 на плату, и перезапустить контроллер выключением питания. Программа будет опрашивать датчики в обратном порядке.

При отсутствии датчиков, или их неисправности, на индикатор выводится сообщение об ошибке, например Er1. Номера ошибок определены в программе: Er1 = отсутствие первого датчика DS; Er2 – отсутствие второго датчика DS; Er3 – общая ошибка датчиков DS при опросе; Er7, Er9 – отсутствие и ошибка датчика DHT.

Возможные пути модернизации.

Применение более мощных вентиляторов – возможно при минимальной переделке схемы. Можно применить реле или симистор, но обязательно с опторазвязкой.

Больше термодатчиков? Да, их можно навесить на общую шину и поболее. В программе при минимальных изменениях возможен опрос большого кол-ва, однако встает вопрос о соответствии их адресов и реальном местоположении. Например, для трех термодатчиков DS18B20 есть уже 6 вариантов расположения, и понадобится уже 3 перемычки. Тут уже нужно или переделывать схему и программу, или определять адреса датчиков и физически располагать их в порядке возрастания адресов.


В приложениях схема в формате ISIS Proteus; плата в формате ARES Proteus, также схема и плата в графических форматах.
Прошивки различных вариантов МК и индикаторов, и исходник программы на Си для AtmelStudio (WinAVR).

Термометр на ATTINY2313+DS18B20 доработанный

Недавно занимался сборкой компьютера с полностью пассивным охлаждением. Чтобы было удобно контролировать температуру процессора, нужно было по быстрому собрать термометр. Всяческие программы типа «Everest», «Aida», и прочие мне не подходили по одной простой причине: хотелось контролировать температуру даже при выключенном мониторе. Или даже при полностью отключенном мониторе. Было решено собрать термометр на основе цифрового датчика DS18B20, дешёвого микроконтроллера AVR, и семисегментного индикатора. Сначала я хотел повторить схему термометра по одному из вариантов, предложенных в интернете. Но после анализа схем, размещённых в интернете, я пришёл к выводу, что придётся изобретать свой «велосипед».

Конструкции, представленные в интернете, имели ряд недостатков, а именно:
* низкая скорость динамической индикации (50. 100 герц), изза которой становится некомфортно смотреть на индикатор, если быстро бросить на него взгляд, кажется что цифры «шевелятся»;
* не все конструкции адекватно измеряли весь диапазон температур (от -55 до +125), попадались например конструкции, не измеряющие температуру ниже нуля градусов, или некорректно измеряющие температуру выше 100 градусов;
* отсутствовала проверка контрольной суммы (CRC);
* общие выводы сегментов подключались к одной ножке микроконтроллера без ключевых транзисторов, ПЕРЕГРУЖАЯ ПОРТЫ МИКРОКОНТРОЛЛЕРА.

При перегрузке портов МК, яркость свечения индикатора может снизиться, а также можно пожечь ножки микроконтроллера. Несколько лет назад я собирал термометр на ATtiny2313+DS18B20 по схеме с интернета. Схема была без ключевых транзисторов. При температуре 18 градусов, цифра «1» светилась ярко, а цифра «8» светилась заметно тусклее, надеюсь всем понятно почему всё происходит именно так. Поэтому я пообещал себе в будущем не перегружать ножки МК. Вот кстати фотка того термометра, собранного по схеме из инета, думаю что в комментариях не нуждается:

Также хотелось сделать несколько доработок:
* вывести на индикатор символ градуса (десятые доли градуса мне были не так критичны);
* затактировать микроконтроллер от внешнего кварца, так как протокол «1-Wire», который использует датчик, критичен к формированию временнЫх интервалов (тайм-слотов), поэтому молиться о стабильности встроенного тактового генератора мне не хотелось;
* ввести в программу проверку контрольной суммы, при несовпадении контрольной суммы выводить на индикатор: «Crc»;
* добавить в схему диод (для защиты схемы от переполюсовки питания);
* при подаче питания в течении 1 секунды засветить все сегменты (так называемый тест сегментов).

Проект я написал в среде AVR Studio 5, функции работы с датчиком нашёл где-то в инете, а остальное переписал на свой лад, обильно снабдив комментраиями исходный код. В конце статьи есть ссылка на скачивание прошивки и исходника.

Семисегментный индикатор я использовал на 3 знакоместа, сегменты с общим анодом. Также в архиве (в конце статьи) есть прошивки под индикатор с общим катодом. Общие выводы сегментов я подключил сразу к двум выводам МК, соединённым параллельно. Таким образом, каждый общий вывод сегментного индикатора использует 2 ножки МК для повышения нагрузочной способности выводов.

Микроконтроллер я использовал ATtiny2313A (также можно использовать ATtiny2313 или ATtiny2313L), задействовал практически все свободные ножки (за исключением ножки сброса). Если собирать термометр на ATmega8, то можно соединять параллельно по 3 или по 4 ножки для повышения нагрузочной способности портов.

Прилагаю фотографии собранного термометра. Корпуса покачто нет, так как термометр будет встраиваться в корпус ПК.

Индикация.
Не подключен датчик температуры, либо короткое замыкание на линии данных:

Ошибка контрольной суммы (CRC):

Подключен датчик температуры, температура от -55 до -10 градусов:

Подключен датчик температуры, температура от -9 до -1 градуса:

Подключен датчик температуры, температура от 0 до 9 градусов:

Подключен датчик температуры, температура от 10 до 99 градусов:

Подключен датчик температуры, температура от 100 до 125 градусов:

Частота динамической индикации — несколько килогерц, благодаря чему мерцание на глаз не заметно даже при броском взгляде на индикатор.
Для желающих повторить конструкцию я скомпилировал несколько прошивок под разные кварцы: 4 МГц, 8 МГц, 10 МГц, 12 МГц, 16 МГц.
Также сделал прошивки под индикаторы с общим анодом (ОА), и с общим катодом (ОК). Все прошивки в архиве (см. ниже).

г.Вельск, Апрель 2014г.
P.S. Первоначально материал разместил тут.

UPD. Обновил прошивку. Мелкие исправления, мелкие плюшечки. Из основного — stdint типы данных, гибкая настройка ног под сегменты. Все изменения описаны в шапке исходника.
В связи с большим наплывом желающих выкинуть кварц из схемы, и не читающих зачем он в схеме нужен, отключил комментарии.

Грызем микроконтроллеры. Урок 4.

В связи с усложнением задачи, будет неплохо иметь под рукой более “навороченный” микроконтроллер. Можно конечно этого не делать, но у tiny2313 маловато памяти и нет Аналого-Цифрового преобразователя. Поэтому мы переезжаем на МК серии Mega!
В виду того, что конструкции дальше будут только усложняться, выбор пал на ATmega16.

А теперь задачи: нам нужно измерить напряжение, подаваемое с движка переменного резистора, измерить температуру в 4 точках и как-нибудь это показать.

Измерить напряжение довольно просто. Наш микроконтроллер имеет 8 входов аналого-цифрового преобразователя (АЦП). Сам АЦП имеет разрядность 10 бит, что дает 1024 ступени измерения.

Например, если измерения проводить в интервале 0-10 Вольт , то результат можно получить с точностью примерно до 0,01 вольта (а если быть абсолютно точным, то до 0,009765625)!

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

Есть чудесная мелкосхемка под названием DS18S20. Заключена она в корпус TO-92 (как маломощный транзистор) и имеет всего три вывода.

Зато внутри этого скромного корпуса содержится цифровой датчик температуры с точностью до 0,1С и диапазоном от -55 до +125 С.

С микроконтроллером всё это сопрягается по протоколу 1wire. О его принципе рассказывать не буду. Кому интересно – может поискать в интернете.
А вот о его прелестях не сказать не смогу.

1wire – однопроводной интерфейс, позволяющий подключить к одной линии данных практически неограниченное количество периферии. Каждое устройство имеет уникальный 64-х битный идентификационный номер. Т.е., максимальное число устройств на одной шине – 2 в степени 64. Единственный недостаток – если использовать максимальное число датчиков, опрос всех может занять лет 10

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

Таким образом, для всех датчиков будем использовать только 1 вывод МК. По-моему, очень даже красивое схемное решение

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

И, в нагрузку, научимся использовать Watchdog (дословно — сторожевой пес), или, так называемый, сторожевой таймер. Предназначен он для того, чтобы сбрасывать МК при зависании программы.

Он имеет свой собственный тактовый генератор на 1 МГц и предделитель, который позволяет выставить интервал времени от 0,016 до 2,048 секунды. При переполнении этого таймера происходит принудительный сброс МК. Этот таймер нужно периодически сбрасывать в каком-либо месте программы, не допуская его переполнения при нормальном исполнении программы.

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

Avr — Как подключить датчик температуры к AVR?

В этой статье я хочу рассказать о двух небольших разработках, выполненных недавно в лаборатории проблем материаловедения Института химии и химической технологии СО РАН в Красноярске (www.icct.ru). Буду рад, если статья поможет сэкономить время и деньги кому-нибудь из моих коллег, решающих аналогичные проблемы.

Обе конструкции связаны с измерением и регулированием температурных режимов для лабораторных установок. В их основе лежит плата AVR-USB-MEGA16, которая выполняет следующие функции:

1. Программная реализация низкоскоростного USB для связи с ПК.
2. Аппаратная генерация сигналов ШИМ (Широтно-Импульсная Модуляция) для регулирования мощности нагревателей.
3. Программная реализация шины 1-Wire для обслуживания температурных датчиков DS18B20.
4. Аналого-цифровое преобразование сигналов с термопар.


Firmware в плате AVR-USB-MEGA16 спроектировано таким образом, что управление всеми необходимыми ресурсами микроконтроллера (инициализация портов, таймеров, ШИМ и т. п.) происходит со стороны хоста через класс-обертку ATMega16. Поэтому единственное firmware подходит для всех проектов ПО хоста, опубликованных в статье.

Все проекты ПО хоста разработаны с использованием свободно доступной на сайте Microsoft среды разработки — Visual Studio 2008 Express Edition (подойдет также любая среда Visual Studio более свежей версии). Для работы с USB используется библиотека libusb-win32 [7]. Для построения графиков используется бесплатная библиотека zedGraph [9]. Все необходимые комментарии находятся в исходных файлах. Проекты и firmware, описываемые в статье, можно скачать по ссылке [8].

Устройства (или их фрагменты), представленные в данной статье, могут использоваться не только в физико-химической лаборатории, но и в быту. Например, системы типа «умный дом» — регулирование температуры в помещениях, недорогая реализация «хитрых» температурных режимов кухонной печи или духовки, водонагреватели и т.п. Другие примеры – моделирование естественных температурных режимов для обитателей аквариумов или растений в теплицах.

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

[Блок-схема устройств]

Первая разработка – программируемая водяная баня. Водяная баня – это просто водяной термостат, но в данной задаче температура термостата должна изменяться по некой задаваемой программе и иногда — весьма сложным образом. Мощность – до 1 кВт. Вторая разработка — печь для исследования реакций в сверхкритических флюидах. Температура – от 200 o C до 400 o C, но выходы на режимы и дальнейшее поведение температуры должно было регулироваться по определенным законам, зависящим от процесса. Мощность – до 3 кВт.

По сути, проблема несложная – обычный температурный регулятор с компьютерным управлением. Различаются только датчики. В первом случае (водяная баня) решение очевидно – недорогие датчики DS18B20. В этом случае аппаратная реализации регулятора становится тривиальной задачей. Во втором случае (печь) я решил использовать термопары для измерения температуры в печи и те же датчики DS18B20 для измерения температуры окружающей среды (и холодного спая термопары). Пара медь-константан вполне подходит для этого диапазона температур. Силовые блоки для регулирования мощности нагревателя различаются только маркой симисторов и размерами радиаторов для них.

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

Рис. 1. Блок-схема регулятора

На долю персонального компьютера приходятся интерфейсные, сервисные функции и высокоуровневые функции управления температурой. На долю микроконтроллера платы AVR-USB-MEGA16 – низкоуровневые функции, перечисленные во введении: ШИМ, 1-Wire, АЦП и USB.

Начнем с силового блока.

[Силовой модуль]

Нагреватели питаются от сети переменного тока. Поэтому естественное решение для управления нагревом – фазовая регулировка мощности. Несложных схем тиристорных регуляторов в Сети много. Однако, можно еще упростить решение, если учесть инерционность нагревателя как нагрузки. В этом случае можно перейти к режиму регулирования мощности по количеству целых полупериодов, пропущенных в нагрузку. Для управления яркостью лампочек освещения (диммеров) это не пойдет, т.к. они будут сильно мигать, но для печек или водонагревателей – в самый раз. Единственная задача, возникающая при конструировании таких регуляторов, – синхронизация моментов отпирания симисторов или тиристоров с нулем сетевого напряжения. Можно было бы нагрузить на эту задачу микроконтроллер платы AVR-USB-MEGA16, но более изящное решение — использовать оптосимисторы с детекторами перехода через ноль (Zero Crossing). Например, MOC3061-MOC3063. Этот вариант и был положен в основу силового модуля.

Схема и конструкция

Схема силового модуля, взята непосредственно из datasheet на опторазвязки MOC3061-MOC3063 без изменений. Она приведена на рис. 2.

Рис. 2. Схема силового модуля

Токоограничивающий резистор Rin = 330 Ом для выбранной мною микросхемы MOC3061. Симистор – BT137-600 для бани, BT139-800 – для печки. Максимальный ток этого первого симистора в открытом состоянии — 8А, второго – 16А, так что моих этих задачи хватит с запасом. При подаче “0” на вход Vin, симистор откроется в ближайший момент прохождения нуля и нагрузка (нагреватель) будет подключена к сети. При подаче “1” – закроется и нагрузка от сети отключится.

На рис. 3 представлена конструкция силового модуля для водяной бани. Без радиатора симистор может работать на нагрузку 100-150 Вт.

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

Рис. 3. Конструкция силового модуля

Проверим работоспособность силового модуля самым простым способом. Подадим на Vcc (рис. 2) сигнал от генератора прямоугольных импульсов напряжением около 5 В, Vin – землю. В данной конструкции резистор Rin будет размещен на плате AVR-USB-MEGA16, поэтому на плате силового модуля разъем подключении непосредственно к ножке 1 микросхемы MOC3061. Следовательно, сигнал от генератора нужно подать на разъем через резистор 300-330 ом. В качестве нагрузки подключим лампочку 220 В мощностью до 100 Вт. Мне подвернулась под руку лампочка на 75 Вт. Частоту следования импульсов установим равную 1 Гц. Изменяя длительность импульсов (от 0 до 1 сек) мы можем менять длительность вспышек лампочки от нуля до постоянного свечения. На рис. 4 показан процесс такого испытания. В качестве генератора импульсов я использовал генератор, имеющийся в USB-осциллографе PV6501 (светлая коробочка в правом верхнем углу снимка).

Рис. 4. Проверяем силовой модуль

Силовой блок успешно прошел испытания – идем дальше. Для подключения силового модуля к плате AVR-USB-MEGA16 нужно выполнить маленькую модификацию платы.

Модификация платы AVR-USB-MEGA16
Первая модификация платы AVR-USB-MEGA16 заключается во впаивании небольшого разъема (розетка на 2 гнезда) и резистора на 330 Ом. Вид модифицированной платы представлен на рис. 5.

Рис. 5. Модернизированная плата. Фрагмент для управления силовым модулем выделен красным

Схема подключения разъема показана на рис. 6. Эта и следующие модификации отмечены красным цветом. Данная модификация – правая на схеме сверху.

Рис. 6. Схема изменений и дополнений платы AVR-USB-MEGA16 (отмечено красным)

Разъем лучше сразу подключить к контакту P20 платы AVR-USB-MEGA16 (PD5 микроконтроллера ATMega16), т.к. именно с этого выхода мы впоследствии сможем взять сигнал аппаратного ШИМ.

Помигаем лампочкой через USB
Для проверки работы силового модуля от платы AVR-USB-MEGA16 напишем простейшее приложение, позволяющее включать или выключать лампочку. Программа называется Bulb. Проект приложения хоста для Visual Studio 2008 Express Edition находится в архиве «01 Управляем лампочкой по USB.zip» (см. ссылку [8]). Firmware для всех проектов этой статьи одно и то же и находится в архиве «00 Firmware.zip» (см. ссылку [8]). Hex-файл в этом архиве – прошивка для микроконтроллера платы AVR-USB-MEGA16. Прошиваем микроконтроллер. Подключаем к плате силовой модуль (с той же лампочкой на 75 Вт, что и в предыдущем эксперименте). Запускаем приложение хоста. Нажимая кнопку «Вкл/Выкл» в этом приложении мы можем включать и выключать лампочку через USB (см. рис. 7). Параллельно на плате AVR-USB-MEGA16 загорается и гаснет светодиод.

Рис. 7. Управление лампочкой через USB

Все работает. Силовая часть готова для построения простейшего позиционного (релейного) терморегулятора. Но перед этим нам нужно научиться измерять температуру. К этому и приступим.

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

Следующий этап разработки – очередная (вторая) модификация платы, необходимая для реализации шины 1-Wire. Она позволит нам измерять температуру при помощи недорогих датчиков фирмы Dallas Semiconductor — DS18B20. DS18B20 – это, по сути, готовый цифровой термометр с разрешением до 12 разрядов и способный обмениваться данными по шине 1-Wire. Рабочий диапазон температур от -55 o C до +125 o C. Время оцифровки температуры для 12 разрядов около 750 мс.

Программная реализация шины 1-Wire

В шине 1-Wire всего один сигнальный провод. Его нужно «подтянуть» к +5В через резистор 4.7 кОм. Еще один провод – земля. В принципе, устройства, работающие на шине 1-Wire, могут использовать паразитное питание от сигнального провода, но в данной разработке мы используем отдельный провод для питания датчиков. Таким образом, модификация платы заключается в установке 6-гнездовой розетки (мы планируем использовать два датчика – по три гнезда на датчик) и подтягивающего резистора. На схеме (рис. 6) эта модификация отображена в центре сверху. Сигнальная линия шины 1-Wire подключен к разряду 1 порта B (PB1). На рис. 8 представлен вид платы. Красным выделен фрагмент для работы с 1-Wire.

Рис. 8. Реализация 1-Wire для двух датчиков

Интерфейс 1-Wire достаточно хорошо описан в Сети (в том числе и программная реализация на микроконтроллерах AVR). Соответствующие фрагменты кода подробно прокомментированы в исходных файлах программного обеспечения firmware (см. файл «main.c» в архиве «00 Firmware.zip», ссылка [8]). Поэтому перейдем к работе с конкретными устройствами 1-Wire — температурными датчиками DS18B20.

Измеряем температуру при помощи датчиков DS18B20

Если низкоуровневая программная реализация шины 1-Wire выполнена на микроконтроллере платы AVR-USB-MEGA16, то работа с датчиками (DS18B20) реализована в приложении хоста. Во втором архиве (файл «02 Работаем с датчиками температуры.zip», см. ссылку [8]) находится пример программного обеспечения хоста (программа TempTest), обслуживающего несколько датчиков (до 16 в данном примере, но может быть и другое — просто константу DMAX в firmware я установил равную 16). Все термодатчики подключаются параллельно (у нас их будет максимум два), см. рис. 6.

Логика работы приложения следующая (см. файл Form1.cs). После запуска приложения и инициализации USB, запускается таймер timer1sec (в конце метода Form1_Load()). Каждую секунду этот таймер генерирует событие, которое обрабатывается в методе timer1sec_Tick(). В этом методе сначала определяется количество датчиков, подключенных к шине 1-Wire. Если на шине есть датчики, то всем им посылается команда начать оцифровать температуру. Время преобразования не превышает 750 мс. Поэтому после команды «начать преобразование» запускается второй таймер timer750ms. Через 750 мс этот таймер генерирует событие, при котором вызывается метод timer750ms_Tick(). В этом методе таймер timer750ms выключается и далее в цикле опрашиваются все датчики, подключенные к шине. Полученный двухбайтовый код температуры преобразуется в десятичное число со знаком и выводится на экран. Программа отслеживает наличие датчиков в каждом цикле. Поэтому датчики можно подключать и отключать в любой момент. Скриншот работающей программы показан на рис. 9. Первый датчик я положил на настольную лампу сверху, а второй показывает температуру в комнате.


Рис. 9. Пример работы с несколькими датчиками

[Водяная баня]

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

Собираем экспериментальный стенд – модель водяной бани

Общий вид стенда представлен на рис. 10.

Рис. 10. Стенд для отработки алгоритмов температурного регулятора

Мощность нагревателя составляет около 400 Вт, поэтому симистор силового блока нужно прикрепить к радиатору. Термометр термостата, представляет собой датчик DS18B20, помещенный в узкую пробирку с тонкими стенками, заполненную трансформаторным маслом для улучшения контакта с водой термостата. Второй датчик, измеряющий температуру окружающей среды, воткнут непосредственно в разъем шины 1-Wire на плате AVR-USB-MEGA16. Правильнее было бы поместить его где-нибудь вблизи наружной стенки термостата, но для данных тестов это не так существенно.

Реализуем простейший регулятор

Рассмотрим простейший алгоритм регулирования температуры, который называется позиционным или релейным. Суть этого алгоритма проста. Если текущая температура термостата меньше заданной величины (она называется «уставка»), то нагреватель включается (естественно, на полную мощность). Если температура сравнялась или превысила уставку – нагреватель сразу же выключается. В архиве «03 Простейший регулятор.zip» (см. ссылку [8]) представлен проект приложения, реализующего этот алгоритм.

Пример работы приложения показан на рис. 11. Температурный режим водяной бани запрограммирован следующим образом. Температура бани должна быть поднята до 80 o C с шагом 20 o C. На каждом шаге – прогрев в течении 20 мин. После прогрева на максимальной температуре – естественное охлаждение до 50 o C и поддержание температуры на этом уровне до конца эксперимента. На графике по горизонтали отложено время с начала процесса в минутах, по вертикали – температура термостата в o C.

Рис. 11. Работа бани с позиционным регулятором

Видно, что результат работы простейшего регулятора трудно назвать удовлетворительным. Видны заметные колебания температуры около точек равновесия, есть серьезные выбросы температуры (почти на 5 o C) после фронтов нагрева.

Причина плохой работы релейных регуляторов известна и довольно очевидна — тепловая инерция нагревателя. Действительно, как только температура термостата станет равна уставке, нагреватель выключится. Но, нагревателя имеет ненулевую теплоемкость, а его температура несколько выше температуры воды (иначе он просто не будет греть воду). Поэтому нагреватель какое-то время продолжает отдавать тепло в воду, несмотря на то, что он уже отключен от сети. И наоборот. Если температура воды станет меньше заданной — реле включает нагреватель. Но его температура уже сравнялась с температурой окружающей воды. Поэтому должно пройти некоторое время, пока температура нагревателя станет выше температуры воды и он начнет отдавать ей тепло.
Есть различные варианты исправления ситуации. Можно уменьшать инерцию нагревателя, вводить более сложные критерии включения/выключения регуляторов. Но все равно, радикально улучшить работу регулятора таким способом не удается. Можно уменьшить мощность нагревателя, но тогда увеличится время выхода термостата на заданный режим и тоже полностью удалить колебания не удается.

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

Делаем ШИМ

ШИМ означает широтно-импульсную модуляцию (по-английски PWMPulse-Width Modulation). ШИМ сигнал – это прямоугольные импульсы, следующие с некоторой частотой, но длительность (т. е. ширину) этих импульсов мы можем изменять по нужному нам закону.

Силовой модуль в нашей системе управляется дискретно. Симистор закрыт, когда на вход модуля подается «1» (+5В) и открыт, когда «0», причем момент открытия симистора «привязан» к моменту прохождения питающего напряжения через 0. Поэтому, если мы возьмем достаточно длительный период повторения открывающих импульсов (например, 1 сек) и будем изменять их длительность, то мы будем регулировать количество пропущенных к нагрузке полуволн питающего напряжения, т. е. регулировать среднюю мощность, поступающую в нагрузку.

Например, при периоде 1 сек, мы сможем регулировать мощность с точностью 1% (в секунде как раз 100 полупериодов сети переменного тока 50 Гц). Как только длительность открывающего импульса станет больше 0.01 сек, каждую секунду в нагрузку будет подаваться 1 полупериод питающего напряжения и нагреватель будет работать с 1% мощностью от номинала. Как только ширина импульса превысит 0.02 сек, то к нагрузке будут проходить два полупериода каждую секунду и мощность возрастет до 2% от номинала и т.д. Когда длительность импульсов сравняется с периодом их следования, все 100 полупериодов будут поступать в нагрузку каждую секунду, и, следовательно, нагреватель будет работать с полной мощностью. Вот так все просто.

Реализовать ШИМ можно несколькими способами. Можно реализовать программно на микроконтроллере или на ПК. Но в этом случае мы можем столкнуться со сбоями в работе ШИМ, особенно при малых или больших скважностях импульсов. Это связано с тем, что и микроконтроллер и ПК должен выполнять еще некоторые функции (обмениваться данными по USB, осуществлять их преобразование, вывод на экран и т.д.) и они могут не успевать обработать все прерывания при коротких интервалах.

К счастью, в микроконтроллере ATMega16 есть возможность реализовать аппаратный ШИМ с регулируемой частотой следования импульсов и скважностью. Для исследования этой возможности разработаем небольшое приложение, которое представлено в архиве «04 Помигаем лампочкой при помощи ШИМ и USB.zip» (см. ссылку [8]). Для генерирования сигналов ШИМ используется таймер TIMER1 микроконтроллера. Его инициализация и настройка подробно прокомментирована в исходных файлах проекта ПО хоста (файл «Form1.cs») – это происходит с помощью класса-обертки Atmega16.

Испытаем наш ШИМ-генератор. К выходу платы AVR-USB-MEGA16, который служит для подключения силового блока, подключим силовой модуль с лампочкой 75 Вт (как мы делали в самом начале статьи). А можно и просто воткнуть в этот разъем светодиод или подключить осциллограф. Запустим приложение PWM.exe из указанного архива. Устанавливая различную величину мощности нагревателя, мы увидим, что лампочка или светодиод мигают с различной длительностью в зависимости от установленного значения. На рис. 12 представлена осциллограмма ШИМ-сигнала, полученного с выхода платы AVR-USB-MEGA16 (порт PD5 микроконтроллера).

Рис. 12. Тестирование аппаратного ШИМ

Теперь мы можем приступить к созданию и изучению пропорционального регулятора.

Исследуем пропорциональный регулятор

Никаких аппаратных изменений по сравнению с позиционным регулятором не потребуется. Вся разработка сводится к написанию программы. В архиве «05 Пропорциональный регулятор.zip» (см. ссылку [8]) приведен проект приложения хоста для Visual Studio 2008 Express Edition. Все необходимые комментарии находятся в файле «Form1.cs».

Логика работы приложения следующая. При загрузке формы (метод Form1_Load()) создается объект dev класса ATMega16. В конструкторе этого класса происходит инициализация USB. Если с USB все в порядке, происходит инициализация рабочих переменных и запускается основной таймер программы timer1sec. Этот таймер генерирует события раз в секунду. В обработчике это события и происходит основная работа программы. Вернем к методу Form1_Load(). После запуска таймера timer1sec происходит настройка портов B и D и инициализация таймера Timer1 микроконтроллера ATMega16 для генерирования ШИМ-сигнала с регулируемой частотой и скважностью (управление настраиваемыми ресурсами микроконтроллера поддерживается firmware и классом-оберткой Atmega16). В оставшейся части метода Form1_Load() происходит инициализация библиотеки для построения графиков zedGraph. По событию Tick таймера timer1 вызывается метод timer1sec_Tick() в котором происходит измерение температуры и установка мощности нагревателя в зависимости от ситуации.

Измерение температур происходит следующим образом. Вначале определяется количество датчиков на шине 1-Wire. Если это количество не менее двух, то считается что первые два датчика участвуют в процессе (первый датчик измеряет температуру термостата, а второй – окружающей среды). Всем датчикам подается команда «начать преобразование» и включается таймер на 750 мс. По тику этого таймера произойдет считывание значений с датчиков и установка значений соответствующих переменных (см. метод timer750ms_Tick()). Параллельно продолжается работа метода timer1sec_Tick() – регулирование температуры (по их предыдущим значениям, полученным на секунду раньше).

Регулирование мощности нагревателя происходит просто. Определяется неувязка err, равная разности текущей температуры термостата и установленной (уставка). В зависимости от значения err устанавливается мощность нагревателя. Если невязка меньше 0, то греть не нужно, мощность устанавливается в 0. Если до желаемого значения далеко (т. е. невязка больше зоны пропорциональности), то мощность устанавливается в 100% от номинала. Если же мы находимся в зоне пропорциональности (т. е. недалеко от уставки), то мощность устанавливается пропорциональной невязке.

Вот, собственно, и вся логика. Пример работы водяной бани с той же программой прогрева, как и в случае позиционного регулятора показана на рис. 13. Мы видим, что никаких колебаний температуры уже нет.

Рис. 13. Работа бани с пропорциональным регулятором

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

Но так ли уж все безоблачно для пропорционального регулятора? Если посмотреть внимательно вторую и третью «полочки» (60 o C и 80 o C на рис. 13), то мы видим, что равновесный уровень заметно ниже уставки (соответственно, 60 o C и 80 o C). На рис. 14 представлен увеличенный фрагмент. Видно, что систематическая ошибка на уровне 80 o C составляет почти полтора градуса.

Рис. 14. Иллюстрация систематической ошибки регулятора

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

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

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

Пропорциональный регулятор с компенсатором тепловых потерь

Этот алгоритм был реализован и опробован на этой же модели водяной бани. Изменения по сравнению с предыдущим кодом минимальные. Модифицированный проект находится в архиве «06 Пропорциональный регулятор с компенсатором потерь.zip» (см. ссылку [8]). Результат работы на той же программе тепловых режимов показан на рис. 15. Видно, что систематическая ошибка пропорционального регулятора скомпенсирована при значении коэффициенте компенсатора 0.2. Уменьшая этот коэффициент до 0 мы получим чисто пропорциональный регулятор. Поэтому его значение также нужно подбирать экспериментально в зависимости от конструкции термостата и мощности нагревателя.

Рис. 15. Работа пропорционального регулятора с компенсатором тепловых потерь


Для данной задачи полученного результата вполне достаточно. На этом и остановимся и перейдем ко второй задаче – программированной печи.

[Печь]

Для измерения температуры в печи датчики DS18B20 уже не подойдут (они работают только до 125 o C). Температура печи не должна превышать 400 o C. Поэтому можно использовать низкотемпературные термопары. Поскольку термопара выдает аналоговый сигнал – необходимо использовать АЦП (аналого-цифровой преобразователь). В микроконтроллере ATMega16 есть 10 разрядный АЦП. Он достаточно быстрый (около 100 мкс на 10 разрядов) и снабжен аналоговым мультиплексором на 8 каналов. Для данной задачи вполне подойдет. Единственная проблема – малая термо-ЭДС термопары. Например, для пары медь-константан это порядка 40-60 мкВ/градус. Т. е. при разнице температуры между горячим и холодным спаем 400 градусов, мы имеем ЭДС всего 16-20 мВ. Поэтому перед АЦП необходимо поставить усилитель.

Термопара

Итак, для измерения температуры в печи мы собираемся использовать термопару медь-константан, которая как раз работает до 400 o C. Константан – это сплав меди с никелем. Поскольку один провод термопары медный мы можем обойтись всего двумя спаями, а измерительную цепь включить в разрыв медного провода. Холодный спай будет расположен на датчике DS18B20, который у нас измерял температуру окружающей среды, а горячий спай – непосредственно в печке. По измеренной ЭДС термопары мы можем определить разность температур горячего и холодного спая. Поскольку температуру холодного спая мы знаем (датчик DS18B20, рядом с которым находится холодный спай), то, следовательно, мы будем знать и абсолютную температуру в печке. Естественно, что термопару мы предварительно должны откалибровать.

Способов изготовления термопар много. Описания легко найти в Сети. Используемые материалы достаточно легкоплавкие и поэтому я просто сходил в институтскую стеклодувную мастерскую и попросил стеклодува спаять мне две проволочки при помощи горелки на очень узеньком кончике пламени. Проволочки я предварительно пропустил в стеклянные капилляры для электрической изоляции в высокотемпературной зоне. В холодной зоне достаточно лаковой изоляции, которая была на проводниках. У стеклодува получились два маленьких аккуратных шарика-спая. В разрез медного провода я впаял небольшую вилку. Что вышло в конечном итоге — показано на рис. 16.

Рис. 16. Готовая термопара для отладочных экспериментов

Теперь займемся предварительным усилителем.

Усилитель

В целом, изготовление усилителя для термопары для лабораторных условий не представляет серьезной проблемы. Коэффициент усиления порядка 100-200, желательно минимальный дрейф и смещение. Сигналы медленные, поэтому сетевая наводка легко отфильтровывается. Существуют усилители специально для термопар с компенсатором холодного спая. Но целью данной работы было использование только недорогих и достаточно доступных компонентов.

Немного поэкспериментировав с однополярным 5-вольтовым питанием операционных усилителей, я разочаровался в своих способностях справиться с нулем при помощи подручных средств и имеющихся у меня корпусов, поэтому решил вернуться к двухполярному питанию. Положительные 5 вольт возьмем с платы AVR-USB-MEGA16, а отрицательные (почти 5 вольт) получим при помощи преобразователей напряжения на коммутируемых конденсаторах. У меня под рукой оказались микросхемы LMC7660. Они рассчитаны на выходной ток до 20 мА, т. е. вполне подойдут для питания одного маломощного усилителя.

В качестве операционного усилителя была взята микросхема OP07 (отечественный аналог – 140УД17). Схема усилителя представлена на рис. 17.

Рис. 17. Схема усилителя для термопары

Работоспособность усилителя, запас по коэффициенту усиления и балансировку при питании от платы AVR-USB-MEGA16 я проверил на макетной плате (рис. 18). Но перед этим нужно опять слегка модернизировать плату AVR-USB-MEGA16. Схема этой третьей, и последней модернизации изображена на рис. 6 (красным слева). На плате появился еще один разъем, к которому необходимо подпаять +5В, землю и порт P1 (PA0) от АЦП.

Мы будем использовать внутренний источник опорного напряжения для работы АЦП. Поэтому необходима еще одна маленькая модификация. Выпаиваем аккуратно резистор R3 с платы AVR-USB-MEGA16, а ножку AREF выводим на этот же разъем для аналоговых модулей. Это опорное напряжение нам потребуется в другом проекте (измеритель pH) для смещения двухполярного сигнала в положительную область. Термопара, если горячий спай всегда теплее, чем холодный, будет выдавать однополярный сигнал (медь – плюс, константан – минус для нашей термопары). Поэтому в этом проекте напряжение AREF на внешней плате не потребуется, но резистор R3 отпаять все-таки нужно.

Рис. 18. Предварительный усилитель на макетной плате

Усилитель на OP07 мне понравился. Запас усиления достаточный, сбалансированный нуль стоит как вкопанный. Заметных шумов и наводок также не наблюдается. Так что можно переносить на печатную плату.

Плата усилителя разрабатывалась в Sprint Layout 5.0. Наконец-то появился повод попробовать метод «лазерного утюга» (точнее — «лазерно-утюжный») для изготовления платы. Получилось с первого же раза. Действительно, вполне работоспособная и удобная технология. Особенно если не нужны слишком узкие зазоры и тонкие отверстия и плата небольшая. Для тонкой работы нужно очень хорошо сбалансировать давление и температуру на подошве утюга, т.к. тонер может расплавляться неравномерно и расплываться (в местах где давление или температура избыточны). Итог работы представлен на рис. 19 и рис. 20.

Рис. 19. Готовый усилитель термопары

Плату усилителя можно соединить с платой AVR-USB-MEGA16 непосредственно, как показано на рис. 20.

Рис. 20. Вся электроника печи в сборе

Теперь осталось разобраться с АЦП.

Работаем с АЦП

Работа с АЦП очень проста. Пример простого приложения, работающего с одним каналом АЦП, находится в архиве «07 Проверяем работу АЦП.zip» (см. ссылку [8]). Firmware и класс-обертка ATMega16 разработаны так, что можно работать с портами и регистрами микропроцессора непосредственно из хоста через USB. Это делает работу с АЦП почти тривиальной. Логика работы программы такова (см. файл Form1.cs в проекте из архива «07 Проверяем работу АЦП.zip», ссылка [8]).

При создании объекта dev класса ATMega16 происходит инициализация USB. Если все прошло успешно (см. метод Form1_Load()), мы инициализируем АЦП. Собственно говоря работа идет с регистрам ADMUX и статусным регистром ADCSRA.

Сначала указываем, что мы будем работать с внутренним источником опорного напряжения (устанавливаем биты REFS0 и REFS1 регистра ADMUX в 1), разрешаем работу АЦП (бит ADEN регистра ADCSRA – в 1) и задаем коэффициент деления тактовой частоты процессора для работы АЦП (см. комментарий в тексте программы). В конце инициализации запускаем таймер, по событиям которого (каждые 0.1 сек) будем запускать АЦП, считывать и выводить результат. Это происходит в методе timer1_Tick().

Биты с 0 по 4 регистра ADMUX определяют режимы работы аналоговых входов. Установка их в 0 – означает работу с одиночным каналом AD0, который мы и собирались использовать. Запуск процесса преобразования происходит путем установки бита ADSC регистра ADCSRA в 1. По концу преобразования бит ADIF этого же регистра устанавливается в 1. Т.к. время преобразования весьма мало, ждем этого радостного события просто в цикле. После этого берем результат преобразования в регистрах ADCL и ADCH и выводим их в TextBox. Вот и все. Пример работы программы показан на рис. 21. Сигнал на вход АЦП удобно взять с того самого AREF, который мы вывели на разъем при последней модификации платы AVR-USB-MEGA16 (естественно, поделив его переменным резистором). Вот и пригодился AREF и в этом проекте.

Рис. 21. Тестирование АЦП

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

Сборка стенда и калибровка

Фотография собранного стенда представлена на рис. 22. Приступим к калибровке термопары.

Рис. 22. Все готово для калибровки термопары

Сам процесс калибровки несложен. Нагреем печь до максимальной рабочей температуры (в нашем случае 400 o C). Регулируя коэффициент усиления усилителя (подстроечный резистор «Усиление», рис. 17) добьемся того, чтобы код АЦП был в конце диапазона с небольшим запасом (в случае 10 разрядного АЦП, пусть будет около 900). После этого оставляем печь остывать, фиксируя периодически код АЦП термопары, показания термометра, который считаем образцовым, и температуру холодного спая. Хотя это и не очень принципиально, но лучше производить калибровку именно при остывании печи, чем при нагреве (меньше градиенты температуры в печи).

Для облегчения этого процесса напишем небольшое приложение, которое представлено в архиве «08 Калибруем термопару.zip» (см. ссылку [8]). Вид работающего приложения показан на рис. 23.

Рис. 23. Процесс калибровки термопары

При нажатии на кнопку «Зафиксировать значения», текущие значения температур T0, T1 и код АЦП сигнала термопары заносятся в список справа панели. Потом по этим данным можно построить градуировочный график или использовать их непосредственно в табличном виде в программе регулятора температуры печи.

Построенный градуировочный график термопары показан на рис. 24. Видно, что в диапазоне от 100 o C до 400 o C градуировочная кривая хорошо описывается линейной функцией. Уравнение тренда – на графике слева вверху. Поэтому в программе регулятора можно использовать это уравнение для пересчета кода АЦП в градусы (естественно, не забывая прибавить температуру холодного спая, которая измеряется датчиком DS18B20).

Рис. 24. Градуировочный график

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


Байты перемычек (fuse bits) ATmega16 должны быть 0xFF (low) и 0x09 (high).

@ S.V.Kukhtetskiy, 2009
Кухтецкий Сергей Владимирович,
лаборатория проблем материаловедения,
Институт химии и химической технологии СО РАН, Красноярск
E-mail: ku@icct.ru

[Решение возможных проблем]

Здесь описаны некоторые типичные проблемы, которые возникают при использовании прошивки Сергея Кухтецкого. Решение других проблем см. в статье AVR-USB-MEGA16, V-USB, FAQ: переписка по вопросам программирования.

1. Записал в платку прошивку Сергея Кухтецкого с помощью загрузчика USB и программы Khazama, но платка не определяется как устройство USB. Если снова установить перемычку для активации загрузчика USB, то платка определяется, и загорается светодиод. В чем проблема? Ответ: платка у Вас исправна, но Вы записали в неё не ту прошивку. Например, прошивка соответствует другой частоте кварца, не той что используется на Вашей макетной плате AVR-USB-MEGA16. Прошейте HEX-файл прошивки Сергея Кухтецкого, рассчитанный на нужную частоту кварца, который стоит у Вас. Частоту кварца можно прочитать на его корпусе, например если на корпусе написано 12.000, то кварц на 12 МГц.

2. При подключении платки к компьютеру (в платку записана прошивка Сергея Кухтецкого) система Windows запрашивает драйвер. Что это за драйвер, где его брать? Ответ: это драйвер библиотеки LibUSB, скачайте его по ссылке [10].

Удаленный оповещатель о критических температуре и влажности на основе МК AVR и датчика DHT22

После подряд 2х поломок кондиционера в серверной и последующего перегрева помещения в течение нескольких суток, встал вопрос о слежении за температурой в ней. Можно было бы ежедневно(ежечасно/ежеминутно) смотреть температуру со встроенных в сервера датчиков температуры используя интерфейс управления IPMI. Но в этом случае присутствует человеческий фактор на который, в данном случае, оказывает свое негативное осознание того, что можно было бы автоматизировать все гораздо лучше. Так случилось, что я как раз не так давно увлекся такой крайне интересной штукой как микроконтроллеры, поэтому задача автоматизации с использованием МК была новой и интересной возможностью реализовать накопленные знания в полезном для мира проекте.

Общая схема работы устройства и использованные инструменты.

За основу было решено взять одну из плат Arduino. Цены на китайские аналоги невысоки и вся необходимая обвязка МК компактно уже размещена на модуле. Изначально предполагалось использовать Arduino Pro + DHT22. Arduino Pro – так как самая дешевая, маленькая, но вполне функциональная плата. DHT22 — потому что этот датчик умеет, в отличие от более дешевого DS18B20, определять еще и влажность. А нам это тоже пригодится. Серверная по забавному стечению обстоятельств находится рядом с туалетом, который может затопить все вокруг себя совершенно без поднятия температуры, например.

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

70м) до кабинета ИТ отдела сигнал. Ну, а здесь пиликать зуммером и мигать разноцветными светодиодами всячески оповещая нас о приближающемся апокалипсисе. К сожалению, это простое решение оказалось не годно по причине отсутствия прямой линии (без промежуточных хабов) между серверной и нашим кабинетом.

Фото 1-й версии устройства:

Тогда было решено подключить ардуинку к компьютеру по USB и передавать данные о температуре и влажности по UART. А значит нужна уже более навороченная Arduino Nano (у меня с МК ATMega328 на 16МГц). Нужно было заставить ее общаться компом, который работает под ОС Windows 7. На этом компе должна быть установлена серверная часть программы, которая должна получать по UART данные и оповещать все подключенные к ней клиентские модули, работающие где-то в локальной сети, о критических значениях температуры и влажности. На тот момент инструментами для написания программ под эту ОС я не располагал, поэтому пришлось в срочном порядке познакомиться с каким-либо популярным языком программирования, обладающим удобной средой написания ПО для Windows. Я остановился на C#. Прошивка для МК, собственно, писалась в AVR Studio 6 на С.

Итак, поскольку при реализации проекта я не нашел информации с примерами кода на C для датчика DHT22, то в этой статье решил заострить внимание на работе именно с ним. Так же в конце статьи вы найдете все ссылки на исходники и используемый инструментарий, для решения своей схожей задачи.

Кратко о работе датчика DHT22.

Его основные параметры:
Напряжение притания 3,3-6 В
Возможности измерения Влажность 0-100%; температура от -40 до 80C
Точность измерения Влажность +-2%(макс.+-5%); температура +-0,5C
Длительность перида измерения Около 2 секунд

Здесь отмечу, что в программе для МК я опрашиваю датчик примерно каждую секунду. У меня так работает. Если у вас с опросом начнутся проблемы, то начните с увеличения этого периода до 2х секунд.

Распиновка и схема подключения из даташита младшего собрата:

Линия данных датчика подключена через 4,7кОм резистор к питанию, значит, в случае если датчик молчит или сломан/отсутствует, то на линии будет логическая единица. Для получения от датчика ответа нужно прижать линию данных к земле на 18 мС.

После того как датчик ответил, он начинает передавать данные. Передача каждого бита начинается с низкого уровня длительностью 50 мкс.

Всего данных передается 40 бит или 5 байт. Данные передаются начиная со старшего бита старшего байта.

Байт 5 — Старший байт значения влажности.
Байт 4 — Младший байт значения влажности.
Байт 3 — Старший байт значения температуры.
Байт 2 — Младший байт значения температуры.
Байт 1 — Контрольная сумма.

Ну и схема устройства:

К ноге D2 ардуины подключена шина данных датчика. К ноге D4 подключен светодиод питания. Кстати, если он мигает, значит датчик не прошел проверку при инициализации, проще говоря — не найден.

Переходим к коду прошивки.

Сначала краткое описание модулей.

UART_ATMEGA328.h

Это модуль с функциями для приема и передачи сообщений по UART. Кстати, в его составе есть функция void send_int_Uart(int i) . Она получает целое 2х байтовое знаковое число, преобразует в строку и передает его по UART. Не ищите где используется эта функция — в данном проекте она не пригодилась.

DHT11-22_def.h

Содержит макросы настроек подключения датчика. Здесь указывается модель используемого датчика: _DHT22 или его упрощенного варианта _DHT11 . PORT, DDR и PIN к которым подключен датчик. И номер пина к которому подключена линия данных. Эти макросы используются в следующем модуле:

DHT11-22.h

Содержит функции для работы с датчиком DHT22 или DHT11.

Код модуля DHT11-22_def.h:

Код модуля DHT11-22.h:

Комментарии по коду.

1. Анализ контрольной суммы добавлять не стал, хотя и сохраняю ее в переменной checkSum .

2. При подсчете длительности периода высокого уровня на шине данных для определения значения получаемого бита решил обойтись без использования таймера МК поскольку посчитал это допустимым упрощением для данного проекта. Но добавил функцию unsigned char calibrateDHT() , в которой подсчитывается переменная dhtSplitLevel содержащая среднеарифметическое значение между самым коротким периодом высокого уровня (при передаче бита 0) и самым длинным периодом высокого уровня (при передаче бита 1). Далее эта переменная используется для определения значений битов данных при последующих обращениях к датчику.

3. Для использования в проекте более дешевого датчика DHT11, нужно указать его в модуле DHT11-22_def.h вместо DHT22. Правда, работу с ним протестировать не удалось по причине его отсутствия.

Ну и напоследок фото и видео работы получившегося устройства:

Цукерберг рекомендует:  Код пульсирует в мозгу и течет по венам
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих