Обзор беспроводных модулей HC-12
Иногда возникает необходимость иметь связь между оборудованием, приборами, какими-то своими схемами на расстоянии и при этом нет возможности или не целесообразно использовать провода. В этом случае приходится строить беспроводную связь. Реализовать это можно большим количеством способов, но совсем недавно на глаза мне попались беспроводные модули HC-12 на GearBest (ссылка HC-12 на AliExpress), о которых речь пойдет дальше. Стоимость модулей составляет около 4-5$ за штуку.
Для начала технические характеристики беспроводных модулей HC-12:
- Рабочая частота – 433,4 – 473,0 МГц
- Используется только внешняя антенна, PCB антенна на модуле отсутствует
- Дальность передачи информации – до 1000 — 1800 м на открытом пространстве в зависимости от режима работы
- Мощность передатчика – до 100 мВт (доступны настройки для 8 уровней мощности)
- Количество каналов передачи данных – 100
- Четыре рабочих режима
- Встроенный микроконтроллер (присутствует на модуле) STM8S003F3
- Интерфейс для коммуникации с внешними устройствами – UART
- Потребляемый ток – от 3,6 мА до 16 мА в зависимости от режима работы
- Пиковое потребление тока – до 100 мА (передача данных)
- Потребление тока в ждущем режиме – 80 мкА
- Напряжение питания – от 3,2 В до 5,5 В
- Настройка модуля AT командами
Параметры модуля по умолчанию:
- UART: 9600, 8N1
- Канал 001 (433,4 МГц)
- Мощность передачи 100 мВт
Разработчики этого устройства предлагают следующие сферы применения продукта:
- Беспроводные датчики
- Устройства для охраны и безопасности
- Беспроводное управление роботами
- Телеметрия и дистанционное управление в промышленности
- Автоматическое получение данных
- Системы POS
- Системы входа без ключа
- Беспроводные сети для ПК и т.д.
Однако, предлагаемые производителем сферы применения не исчерпывают все области, где можно применить беспроводную связь. Ограничением в данном случае будет только фантазия радиолюбителей и инженеров.
Модули HC-12 работают как беспроводной удлинитель UART и не вносят каких-либо изменений в передачу информации — что отправил на одном конце, то получил на другом.
Данные модули позиционируются в продаже как заменяющие Bluetooth модули:
В некоторой степени это на самом деле более выгодно: намного больший радиус передачи, более компактное исполнение модуля (справа на фото Bluetooth модуль HC-05, о которых подробно рассказывалось в данной статье), возможность использования внешней антенны, однако отсутствие штатной PCB антенны можно поставить в минус, а кроме этого при соединении с ПК или планшетом понадобится еще один модуль для связи, в то время как Bluetooth есть практически во всех устройствах. Таким образом, модули HC-12 расширяют линейку беспроводных модулей и дают большее поле для конструирования собственных устройств.
Модуль представляет собой печатную плату с необходимыми элементами размером 27,8 х 14,4 мм. Беспроводной модуль имеет возможность подключения антенны двумя способами: подключение антенны через разъем IPEX20279-001E-03 (ANT1) или просто припаять кусочек провода (к контакту 6) (ANT2) или другой разъем (контакты 7,8 — земля). Для подключения к другим устройства модуль имеет пятиконтактный разъем (PLS/PBS), где 1 – плюс питания, 2 – земля, 3 – RxD, 4 – TxD, 5 – SET. Вывод 5 SET подтянут 10 кОм резистором к плюсу питания. Этот вывод необходим для активации настроек при помощи AT команд. Активация происходит при подключении вывода к низкому уровню, то есть к земле.
Модули построены на базе микросхемы SI4463 (микросхема в корпусе QFN-20), к этой же микросхеме подключен кварцевый резонатор на 30 МГц, необходимый для работы. Сама по себе эта микросхема (микроконтроллер) имеет интерфейс SPI, но модуль подключается по UART. Дело в том, что на модуле присутствует еще один микроконтроллер — STM8S003F3, он выступает в роли преобразователя интерфейсов. Кроме этого микроконтроллер STM упрощает взаимодействие с SI4463. Дело в том, что по UART нам необходимо всего лишь отправить байты данных как они уже отправляются в «воздух», но напрямую по SPI так сделать не получится, так как необходимо выполнять дополнительные команды. Микроконтроллер STM реализует все необходимые команды для этого и упрощает настройку и управление модулем HC-12 посредством собственных AT команд.
Диапазон питания модуля HC-12 определяет LDO (Low Dropout) регулятор напряжения (регулятор напряжения с низким падение напряжения на регулирующем элементе) XC6206 (элемент в корпусе SOT-23 с маркировкой 662K). Диод и транзистор на модуле под микроконтроллером STM относятся к схеме согласования UART. Элемент в шестиногом корпусе SC-70 – это переключатель AS179-92LF. Функционал наглядно показан на электрической схеме выше – переключение антенного выхода на приемный и передающий выводы микросхемы SI4463.
Контакты модуля HC-12 выполнены таким образом, что их можно использовать для пайки к разъемам PLS/PBS, либо припаивать напрямую к контактным площадкам другой печатной платы. При этом антенну может заменить печатный проводник (PCB антенна).
В продаже кроме модулей HC-12 (на базе микроконтроллера SI4463) есть так же практически идентичный модуль на базе микроконтроллера СС1101, обладающего практически теми же параметрами. Справа СС1101, слева SI4463:
Однако отличия между ними существуют как в плане элементной базы, так и в программной составляющей. Между собой в стоковом состоянии модули не соединяются. Для работы в паре одному из модулей необходимо модифицировать прошивку, если это возможно. А именно Зеленый модуль является модулем HC-11, что часто не указывают при продаже. HC-11 имеет несколько другую структуру работы и, хотя и схожие, но с различиями, AT команды.
Для подключения к компьютеру используем стандартный USB-UART переходник:
После подключения питания модуль начинает сразу работать со стандартными параметрами, заложенными производителем и ждет поступления данных по UART. Для изменения параметров модуля необходимо замкнуть вывод SET на землю, что активирует управление AT командами. Для HC-12 применимы 12 AT команд.
AT команда | Описание |
---|---|
AT | Тестовая команда. |
AT+Bxxxx | Команда изменения скорости передачи данных (может быть 1,200bps, 2,400bps, 4,800bps, 9,600bps, 19,200bps, 38,400bps, 57,600bps, и 115,200bps) |
AT+Cxxxx | Команда изменения канала связи (от 1 до 127). Шаг частоты канала 400 кГц, при больших расстояниях и скоростях больше 9,600bps рекомендуется не использовать частоты 5 соседних каналов выбранного канала, что бы сохранить полноценную работоспособность |
AT+FUx | Команда выбора режима работы (FU1, FU2, FU3, FU4). FU1 — режим сохранения энергии, потребляемый ток 3,6 мА. FU2 — экстремальный режим сохранения энергии, потребляемый ток 80 мкА. FU3 — режим полной скорости, потребляемый ток 16 мА. FU4 — режим максимальной дальности, потребляемый ток 16 мА, только скорость 1,200bps, количество информации не более 60 байт, интервал передачи пакетов рекомендуется использовать около 2 секунд для предотвращения потери данных |
AT+Px | Команда выбора передающей мощности (от 1 до 8) |
AT+Ry | Запрос установленных параметров модуля (AT+RB — baud rate, AT+RC — канал передачи данных, AT+RF — режим работы, AT+RP — мощность передачи) |
AT+Rx | Получение всех параметров: режим работы, baud rate, канал передачи данных, мощность передачи |
AT+Uxxx | Команда выбора data bits, check bit и stop bit |
AT+V | Запрос версии программного обеспечения модуля |
AT+SLEEP | Команда перехода в спящий режим, ток потребления в спящем режиме 22 мкА. Для выхода из спящего режима необходимо послать AT команду |
AT+DEFAULT | Сброс параметров настроек модуля до заводских |
AT+UPDATE | Вход в режим ожидания обновления программного обеспечения модуля. После ввода команда необходимо закрыть COM порт и запустить софт для обновления (HC-1X updater) |
При построении схем с применением модулей HC-12 необходимо учитывать несколько факторов:
Приемопередатчик HC-12 и датчик температуры DS18b20 на AVR-ассемблере
По мотивам содержания моей книжки «Программирование микроконтроллеров AVR: от Arduino к ассемблеру» была опубликована статья о подключении дисплеев к AVR с применением только «чистого» ассемблера. Под «чистым» имеется в виду наличие только простейшего редактора кода и программатора, и отсутствие необходимости во всяких навороченных инструментах вроде Atmel Studio. В конце я пообещал, что изложенный там материал продолжится изложением примеров, затронутых в книжке лишь вскользь или не вошедших в нее вовсе.
Одним из таких моментов является беспроводная связь между устройствами, вторым — цифровые датчики (в книжке большей частью изложено обращение лишь с аналоговыми). По нижеизлагаемым причинам для связи я остановился на модуле HC-12, а в качестве цифрового датчика использовал одну из бессмертных разработок «всех времен и народов» — датчик DS18b20.
Для упрощения отладки проекта его составляющие сначала моделировались на Arduino, и затем воспроизводились на ассемблере на более адекватной элементной базе.
К той статье я получил некоторое количество ожидаемых критических замечаний от знатоков программирования. Одно из них считаю необходимым прокомментировать отдельно: почему у меня «кидание из крайности в крайность» (имеется в виду от Arduino к ассемблеру, пропуская нормальный С). А потому, что Arduino — это платформа для начинающих, для ознакомления с предметом и удобнейший инструмент для быстрого макетирования. А все остальное — для продолжающих. И ассемблер должен предшествовать «нормальному С», а не завершать изучение. Как когда-то верно заметил DI HALT, после С вникать в ассемблер уже не захочется, и ничегошеньки вы про работу контроллера так и не узнаете. Хороший пример — утверждение в одном из комментариев, что «любая программа обработки прерываний должна…» — нет, дорогие оппоненты, совсем не «любая» и уж точно не «должна», все зависит от контекста, в котором это происходит.
Уже столкнувшись пару-тройку раз лоб в лоб с «оптимизирующим компилятором», я полагаю, что необходимости углубленного изучения программирования вполне можно избежать, коли вы собрались простенький прибор построить, а не вникать в нюансы построения этих самых компиляторов. Оптимизировать код «по месту» вручную, согласно моему опыту, можно куда лучше и более предсказуемо, чем это сделает компилятор. Конечно, при условии, что вы привыкли изучать не «оптимизирующие компиляторы», а тщательно вникать в нюансы схемотехнических решений и функционирования программ. И научить этому, без сомнения, может только ассемблер.
Остальные соображения по этому поводу см. в книге.
Приемопередатчик HC-12
Сначала речь пойдет об организации беспроводной связи между двумя девайсами. Тема, можно сказать, топовая для наших дней, но при ближайшем рассмотрении приемлемое решение оказывается найти довольно сложно. Естественно, в простых устройствах целесообразно применение самых дешевых и компактных решений. Но дешевизна далеко не синоним простоты — малая цена и доступность описанного мной год назад RF-комплекта из приемника и передатчика ISM-диапазона 433 МГц вполне компенсируются сложностью библиотечного кода. Еще более усложнять задачу, переписывая его на ассемблере, просто глупо. И, кстати, за это время я выяснил, что качество модулей в продаже почему-то резко упало: даже из проверенных источников получить RF-комплект, не желающий работать в паре — совсем не исключение. Для проверки заказал десяток комплектов по дешевке у вроде бы солидного продавца на Ali, посмотрим на качество, когда доберутся.
Для ассемблерного подхода здесь бы идеально подошел какой-нибудь из приемопередатчиков, работающих через стандартные порты обмена (обычно это UART, иногда SPI). К сожалению, почти все они довольно дороги — в книге я ориентировал читателей на MBee-868, но самый дешевый из них находится поиском за цену порядка 1200 рублей, а для радиообмена ведь нужна их пара (и не ищите их на Ali — говорят, это чисто отечественная разработка). За такой порядок цен можно уже построить целую метеостанцию даже по ценам «Чипа-Дипа».
Остальные решения, такие, как LoRa, в основном еще дороже (если не рассматривать сомнительные и плохо документированные предложения с Ali). Потому я остановился на HC-12 на 433 МГц — пару таких модулей можно купить в более-менее надежном интернет-магазине рублей за 800 (или раза в полтора-два дешевле прямо на Ali). Смоделировав прием и передачу на Arduino, я убедился, что отзывы на форумах не врут: из коробки, без всяких настроек, модули работают просто отлично.
Обмен по умолчанию идет на скорости 9600. В качестве антенны использовался просто отрезок изолированной проволоки диаметром 0,5 мм и длиной 17 см (к модулям прилагается и спиральная антеннка, но, опять же по отзывам, она работает хуже). На дальность не проверял, но в пределах квартиры, включая передачу на лоджию через капитальную кирпичную стену под косым углом, никаких проблем не возникло.
Приятная особенность всех применяемых решений — отсутствие аналоговых компонентов, что позволяет не очень заботиться о качестве питания (напомню, что существенным фактором при работе RF-приемника является необходимость отдельного от цифровой части аналогового стабилизатора).
Энергосбережение при передаче
Все хорошо, и меня устраивает — процедуры обмена простейшие и в полпинка переводятся на ассемблер. Есть только одно довольно большое «НО»: потребление. Модуль в умолчательном режиме на холостом ходу потребляет 15 мА, которые возрастают до 100 и более мА в момент передачи. Исследования с помощью осциллографа показали, что передача длится дольше, чем это должно быть при формально выставленной скорости 9600. При такой скорости байт передается примерно за миллисекунду, измерения же показали, что при передаче четырехбайтового числа потребление возрастает до 100 мА примерно на 15 мс. С этим может справиться обычный 100-миллиамперный стабилизатор (LM2931, LP2950 и пр.) с хорошим танталовым конденсатором на выходе, но для батарейного питания все это совершенно не годится.
Конечно, я сначала рассчитывал на штатные способы энергосбережения, из которых выбрал периодическое погружение в сон и пробуждение с помощью AT-команд. Но первое же испытание управления HC-12 с помощью AT-команд (попытка получения стандартного отклика «AT»-«OK») показала полный облом. Вход в режим управления (заземлением вывода S) занимает длительное время — официально не менее 40 мс, в реальности может и все 200, отклик приходит через раз и может ожидаться вообще неопределенно долго. Плюс штатный выход из режима управления — формально не менее 80 мс, и черт его знает, сработало там все или зависло.
Почитав стенания по этому поводу на различных форумах, я решил, что такой хоккей нам не нужен! Пусть разбираются въедливые перфекционисты, а мы поступим проще: раз в умолчательном режиме модуль нормально работает, просто будем отключать питание, а при необходимости передачи — включать. Экспериментально удалось установить, что после включения модулю достаточно 30-35 мс на успокоение, для гарантии будем выжидать 50 мс. Включать питание модуля будем маломощным MOSFET-ключом (транзистор BS-170), замыканием на общий провод. Не забудем выждать до выключения необходимое время для гарантированного окончания передачи. Эксперименты показали, что при снижении паузы до выключения модуля ниже 20-30 мс процесс обмена нарушается, потому будем с запасом выжидать также 50 мс. Это проще в осуществлении, чем подача AT-команд, страхует от странностей работы модуля и занимает не больше времени, чем управлением штатным способом в идеальном случае. Причем в перерывах модуль совсем ничего потреблять не будет и не надо экспериментировать с выбором из различных предлагаемых режимов.
Моделирование передачи-приема на Arduino
Скетч, моделирующий простую передачу двухбайтового числа (HC-12_proba_peredatchik) вы найдете в архиве по ссылке в конце статьи. Раз в 4 секунды передается число 273. Соответственно, в простейшем скетче для проверки приема (HC-12_proba_priemnik) при приеме этого числа светодиод по выводу 13 меняет состояние на противоположное. В текстовых скетчах намеренно использован не слишком удобный способ побайтной передачи двухбайтового числа и формированием его заново на приемном конце, примерно так ( value — двухбайтовая переменная типа word или uint_16 ):
Возможности класса Serial позволяют и передачу и прием сделать более компактным способом, но в дальнейшем мы будем переводить это на ассемблер, где никаких классов Serial не имеется, потому сразу делаем программы передачи и приема совместимыми с ассемблерным вариантами.
И для приемника и для передатчика можно использовать любой Ardiuno на основе ATmega328 (Uno, Nano, Mini или их аналоги, в том числе и с 3-вольтовым питанием). Схемы подключения и передатчика и приемника в тестовом варианте тривиальны: подключить оба вывода питания GND и Vcc модуля к питанию Arduino GND и +5V, и перекрестно соединить выводы RxD и TxD. В скетчах для связи через модули HC-12 использован программный UART: вывод 8 (RxD) и 9 (TxD) Arduino в передатчике, 2 (RxD) и 3 (TxD) в приемнике (см. исходный текст скетчей). Можно, конечно, использовать и штатный UART, но тогда необходимо каждый раз перед подключением USB отключать модуль и при проверке запитывать контроллер от автономного адаптера. Забывчивость мне уже стоила одного необратимо сожженного Uno и одного контроллера, лишившегося загрузчика, потому рисковать не советую (что интересно, в случае Xbee-модулей, которые также подключаются к UART, никаких таких катастроф не наблюдалось — просто Arduino IDE при подключении Xbee переставала получать отклик от порта). В ассемблерном варианте, который мы будем обсуждать далее, подключенный к порту UART адаптер, разумеется, не имеет значения, так как программирование через него не ведется. И мы там будем всегда использовать штатный порт, а на приемной стороне выводить полученные данные на дисплей.
Теперь соберем схему для испытаний модуля HC-12 на отключение и включение с помощью транзисторного ключа, согласно описанному ранее:
В соответствующем скетче (HC-12_proba_power_peredatchik) контроллер каждые 4 секунды отсылает в эфир возрастающее число. В перерывах питание модуля отключается. Управление включением и отключением питания модуля через ключ, соединяющий с модуль с «землей», осуществляется через вывод D5 Arduino (совпадает с выводом 5 порта D). Именно на такой схеме проводились измерения потребления модуля и проверялись необходимые величины задержек на установление питания.
Теперь отвлечемся от потребления и смоделируем расширенную передачу данных с выводом на дисплей. Усложненный скетч передатчика HC-12_peredatchik_array также имеется в архиве по ссылке в конце статьи. Контроллер передает в эфир целый массив, начинающийся с идентификатора передатчика (в данном случае трех символов «DAT»), после следуют два байта числа и затем символ «;» качестве конца данных. Опять же оформить подобную передачу можно средствами высокоуровневого языка более красиво и компактно, но мы остановимся на побайтной передаче массива, так как именно такой способ будем использовать в ассемблерном варианте. Текст скетча HC-12_peredatchik_array невелик и я привожу его здесь полностью:
Может показаться, что накладные расходы такого способа слишком велики — четыре служебных байта на два байта передаваемого числа. Но во-первых, это тестовый макет (в реальности мы можем передавать сколько угодно чисел любой разрядности), во-вторых, таким способом мы можем повесить на один приемник любое количество датчиков, меняя их идентификатор (к примеру «DA1», «DA2» и так далее). А оконечный символ «;» служит здесь для проверки того факта, что массив передан и принят полностью (в Arduino без этого символа вполне можно обойтись, а в ассемблерном варианте он нам пригодится, чтобы не связываться со всякими таймаутами).
Для проверки можно просто принимать массив побайтно через программный порт, и потом отправлять принятое через обычный Serial на монитор порта для проверки. Для такого способа можно использовать слегка модифицированный скетч простейшего приемника (HC-12_proba_priemnik). Подробнее я останавливаться на этом не буду, так как мы тут сразу попробуем смоделировать отвязанный от USB приемник с дисплеем.
Приставим к Arduino обычный ЖК или OLED-дисплей 16х02, так как уже знаем (см. предыдущую статью), что потом перенести это в ассемблерный проект будет совсем несложно. Схема подключения дисплея и модуля HC-12 к Arduino показана на рисунке:
Соответствующий скетч носит название HC-12_priemnik_OLED16x02_Arduino, и также может быть найден в архиве по ссылке в конце статьи. Пятисекундная задержка в начале (в функции setup() ) с тестовым выводом на дисплей необходима для проверки правильности подключения и инициализации дисплея. После этого программа начинает отслеживать прием массива через программный UART (штатный Serial при этом используется для отладки). Прием устроен довольно нестандартным способом:
После того, как мы убедились, что пришел первый байт передаваемого массива ( Serialpr.available()>0 ), производится отслеживание по условию while ( Serialpr.available() ). Выход из этого цикла происходит автоматически по истечению таймаута на прием. По умолчанию в Arduino Serial.timeout равен 1 мс, что примерно равно времени передачи байта со скоростью 9600. Поэтому через пару-тройку принятых байт мы из цикла вылетаем, не закончив прием массива. Чтобы этого избежать, после приема очередного байта ставится небольшой delay, тогда выход из цикла будет только после приема последнего байта массива. Задержка необязательна, если раскомментировать отладочные строки посылки через обычный Serial – время их выполнения как раз обеспечит необходимую задержку. Повторю, что средствами Arduino можно обеспечить куда более компактный прием (применив всякие там readString и parseInt ), но мы моделируем будущий ассемблерный вариант. Вы увидите, что там проблема приема целостного массива будет решаться другим способом, где как раз посылка разделителя «;» будет играть решающую роль.
Убедившись, что массив принят полностью (последний принятый байт содержит символ двоеточия «;»), а первые три байта полученного массива содержат необходимый идентификатор (строка «DAT»), мы, как и ранее, формируем двухбайтовое число из отдельных байт и посылаем результат на дисплей.
Передача и прием на ассемблере
Испытание ассемблерной версии передатчика проводилось по схеме, показанной на рисунке выше (сразу с возможностью отключения питания модуля HC-12). Контроллер ATtiny2313 может быть заменен в данном случае на почти любой другой AVR (о том, что именно надо менять в исходном коде при такой замене — см. упомянутую книгу). Кварц (в данном случае на 4 МГц) — обязательная для этого случая деталь, при работе от встроенного генератора UART на скорости 9600 будет сбоить. Потребление в сравнении с ардуиновскими 16 МГц падает примерно вдвое, а кварц шустрее 4 МГц нужен лишь в отдельных задачах, связанных с измерением времени.
Управление ключом питания модуля HC-12 производится через вывод 5 порта D (вывод 9 микросхемы). Стандартный для Arduino вывод сигнального светодиода D13 (это вывод 19 ATmega328) здесь заменен на вывод 6 порта D (выв. 11 ATtiny2313, крайний в корпусе). Заметьте, что на схеме указан стандартный светодиод, который при резисторе 620 Ом будет потреблять около 5 мА. Если хотите немного сэкономить дополнительно, поставьте суперяркий (1000 мкд и более) и к нему резистор порядка 20-33 кОм, в зависимости от яркости свечения выбранного типа.
Предварительно необходимо установить fuse-биты. Да-да, а что вы думали? Это в Arduino вам их менять не только нельзя, но и невозможно. А все контроллеры выпускаются с фабрики с установками на работу от встроенного генератора (причем с конкретной частотой 1 МГц, за редким исключением). Потому их нужно поменять, как минимум, на работу от внешнего кварца. Для облегчения программирования чипа 2313 привожу наглядную картинку настроек фьюзов для данного случая. Как там и написано, нажатая кнопка соответствует нулевому (programmed) значению фьюза:
Систему BOD мы здесь держим выключенной (все биты BODELEVEL в единичном состоянии), потому что это 20-30 мкА дополнительного потребления. При выключенной системе отслеживания питания контроллер при истощении батарейки может совершать непредсказуемые операции, но в общем случае это опасно только для содержимого EEPROM. В данной схеме долговременная память не употребляется и BOD можно выключить.
Соответствующая тестовая ассемблерная программа передатчика сразу с использованием энергосбережения (H-12_peredatchik.asm) приведена полностью далее:
В главном цикле программы, как видите, совершается единственное действие — уход в энергосберегающее состояние. Все действия здесь реализованы в обработчике прерывания сторожевого таймера (WDT), настроенного на выход из сна каждые 4 секунды (максимальное значение 8 секунд). После выхода из сна через МОП-ключ BS-170 подключается передачик, дается пауза 50 мс для того, чтобы модуль «пришел в себя», и затем производится передача. Измерения показали, что в паузах вся схема потребляет не более 150 мкА. Активный период длится около 0,1 с, в это время потребление в среднем составляет около 50 мА. Напомним, что в ассемблерной программе подключение программатора ни на что не влияет, потому при отладке передатчика его можно не отключать (но не забывайте, что программатор питается от схемы и при измерении потребления отключать его все-таки необходимо!). Напомним, что в качестве светодиода Led1 можно поставить суперяркий с токоограничивающим резистором R2 величиной 20-30 кОм. Текст программы и скомпилированный hex-файл вы найдете в том же архиве в конце статьи.
Следует учесть, что WDT в контроллере ATtiny2313 расширенного типа, аналогичного встроенному в Arduino-контроллеры ATmega328. Сторожевой таймер в старых контроллерах, вроде ATmega8/16, не поддерживает режим выхода из сна в прерывание, только полный перезапуск. Это критично для программ, хранящих промежуточные результаты в памяти или регистрах, но в данном случае приведет лишь к необходимости в минимальной коррекции процедур инициализации сторожевого таймера и переноса всей функциональности в главный цикл (подробности см. книгу). Кроме того, старый WDT не поддерживает длинные выдержки в состоянии сна (более 2 с). Это следует помнить и проверять тип встроенного WDT, если вы захотите перенести программу на другой контроллер (кстати, популярный у ардуинщиков ATtiny13 также имеет расширенный WDT, но в нем отсутствует полноценный аппаратный UART, потому для наших целей его придется приспосабливать дополнительно).
Расширенную программу передатчика с посылкой массива, аналогично тому, как мы это делали на Arduino, вы также можете найти в архиве (H-12_peredatchik_2313_WDT.asm). Она отличается от приведенной выше только содержимым обработчика прерывания WDT:
Программа каждые 4 секунды передает в эфир такой же массив, предваряемый идентификатором датчика, как и Arduino-скетч выше, потому, чтобы убедиться, что передатчик работает верно, проверить прием можно тем же скетчем приемника с дисплеем (HC-12_priemnik_OLED16x02_Arduino). Обратите внимание, что передаваемое число здесь 2-байтовое, но ограничено 3 десятичными знаками (0-999). Так в дальнейшем (при выводе на дисплей) удастся сократить процедуру BCD-преобразования — в задаче дистанционного термометра далее передаваемые величины температуры не будут выходить из этого диапазона.
Приемник на ассемблере
Для дальнейших действий нам потребуется приемник с дисплеем на основе ассемблера, потому давайте составим макет подобного устройства. За основу возьмем ATmega8, тогда схема может быть, например, такой:
Установка fuse-бит для Mega8 показана на рисунке (здесь питание от сетевого адаптера, экономия не требуется, потому систему BOD можно не отключать):
Программа, соответствующая этому рисунку (HC-12_priemnik_OLED16x02_proba.asm), получается довольно громоздкой, потому полностью здесь не приводится, и вы ее сможете посмотреть в архиве по адресу в конце статьи. Здесь мы остановимся на ключевых моментах. В начале программы, после всех необходимых установок, дисплей для проверки верности подключения и для образца заполняется тестовыми символами точно так же, как это делалось в программе OLED1602_proba.asm из предыдущей статьи. Затем программа переходит к замкнутому циклу, в котором принимает последовательно все элементы нашего массива, с проверкой трех символов идентификатора в начале и концевого символа «;» в конце:
Если эти служебные символы не совпадают с ожидаемыми, то происходит возврат в начало цикла ожидания. Если все совпало, то выполняем конвертацию полученного hex-числа в три отдельных десятичных цифры и выводим их дисплей в виде символов, для чего достаточно к каждой цифре прибавить число 0x30 = 48, соответствующее позиции нуля в таблице ASCII (во избежание недоумений: чтобы прибавить к регистру общего назначения константу, в AVR-ассемблере применяется команда вычитания отрицательного числа, команда сложения с константой имеется только для 16-битовых чисел).
Обратите внимание на способ выполнения приема через UART. В данном случае мы не используем никаких прерываний, а банально зацикливаем программу в ожидании установления бита RXC в регистре UCSRA, что означает приход очередного байта:
То есть программа у нас львиную часть времени висит в ожидании прихода очередного байта. «Большим» программистам такой способ, несомненно, покажется диким и архаичным — они привыкли автоматически избегать ситуаций, потенциально могущих ничем не закончиться. На самом деле этот способ приема как раз удобнее и безопаснее других, так как будучи применен в главном цикле программы, совершенно не мешает вклинить сколько угодно параллельных процессов через прерывания. А если логика программы такая хитрая, что этот простой способ по какой-либо причине не «катит», то в книге у меня рассмотрены еще три способа, уже с использованием прерываний UART, причем этими тремя перечень возможностей не исчерпывается.
Датчик температуры DS18b20
В книге описана работа в основном с известным аналоговым полупроводниковым датчиком температуры TMP36 (под другими названиями его выпускает множество фирм). Вообще аналоговые датчики температуры не представляют никакой проблемы — у меня много лет отлично работал заоконный термометр с медным датчиком на основе 800-омной обмотки герметизированного реле РЭС-60. Сложнее с аналоговыми датчиками влажности, но и их приобрести отдельно не проблема, вопрос только в цене — дешевые наверняка будут вам показывать «погоду на Марсе», особенно вне комнатных условий. Впрочем, с цифровыми Arduino-датчиками ровно та же история, так что не будем отвлекаться.
Рассмотрим здесь один из самых приличных представителей цифровых датчиков температуры — DS18b20. Первые его аналоги появились на рынке более двух десятилетий назад, когда обо всем этом китайском ширпотребе, задающем сегодня тон на массовом рынке, еще речи не шло. Возможно, поэтому изделие по качеству получилось вполне на уровне: по моему опыту, точность 0,5 градуса «из коробки» датчик вполне выдерживает. Высокие метрологические качества подтверждаются фактом, что датчик DS18b20 внесен в Госреестр средств измерений (сертификат 44046-10 от 2010 года), и при соблюдении соответствующих условий может использоваться для официальных измерений. Цена на этот датчик зависит от диапазона, в котором гарантируется погрешность в 0,5 градуса, и совсем не кусается, причем оригинальный MAXIM даже в «Чип-дипе» можно приобрести менее, чем за сотню деревянных. Интерфейс OneWire позволяет длину линии в десятки метров, и потому китайские и отечественные магазины смогли предложить DS18b20 заделанным в герметичный кабель разной длины. Потребляет датчик копейки и вполне годится для энергосберегающих автономных устройств. В общем, удобная штуковина во всех отношениях, кроме, пожалуй, довольно навороченного протокола (что, очевидно, неизбежное следствие его высоких качеств).
А для нашей ассемблерной задачи DS18b20 удобен еще и потому, что, в отличие от всех этих Arduino-датчиков, выдает сразу калиброванные цифровые значения, соответствующие градусам Цельсия. То есть для вывода показаний не придется возиться с калибровкой и проводить громоздкие расчеты. Необходима только небольшая коррекция выходного кода, которую на ассемблере провести ненамного сложнее, чем на С.
Датчик подключим к выводу 0 порта С. На всякий случай приведем полную схему передатчика с датчиком DS18b20 на основе ATtiny2313:
Касательно экономичности: в сравнении с тестовой схемой изменения потребления после подключения датчика обнаружить не удалось, потому я не стал возиться с его отключением-подключением к питанию. Информационный вывод DQ датчика подключен в выводу PB0 порта B. Питание здесь отдельное, не «parasite mode», когда датчик питается от линии данных — возможно и такое, но сложнее в реализации. Датчик на линии единственный, потому вариант чтения наипростейший, без долгих запросов с извлечением длиннющих 64-битных индивидуальных номеров.
Можно составить Arduino-модель, конечно, но это мало что даст: использование библиотеки DallasTemperature чрезвычайно простое, достаточно сделать по образцу прилагаемого к ней примера. Это ничуть нас не продвинет в изучении протокола, а составлять его самостоятельно сразу на ассемблере даже проще, чем на С. Процедуры чтения DS18b20, в том числе и на AVR-ассемблере, обсуждаются в Сети уже не первое десятилетие, потому останавливаться на этом я не буду. Толковое описание алгоритма можно найти, например, в серии статей вот тут, советую с ним ознакомиться (правда, в некоторых нюансах реализации моя программа отличается от приведенных в этих статьях примеров).
Уже 20 лет как несуществующая, фирма Dallas Semiconductor надолго задержалась в народной памяти целым рядом неустаревающих придумок. Например, она изобрела когда-то шину OneWire (1-Wire). Одним из самых массовых OneWire-устройств в России стали подъездные ключи-таблетки (iButton). На мой вкус, куда более удобное устройство, чем RFID-карточки, прижившиеся в качестве ключей в гостиницах. Кроме OneWire, самая, наверное, известная из ее придумок — ряд встраиваемых часов реального времени с различными интерфейсами (DS1307 и его потомки).
Всемирную известность Dallas когда-то принесла идея встраивать литиевые батарейки прямо в чип обычной статической памяти SRAM. Таким образом вы получали некую имитацию в то время еще очень дорогой и сложной в обращении EEPROM, причем имитацию гораздо более скоростную, чем даже современные флешки. Сохранность данных гарантировалась в течение 10 лет, и такое решение широко применялось даже в ранних ПК и лэптопах для хранения установок BIOS. По мере удешевления EEPROM это относительно дорогое и ненадежное (через 10 лет микросхему неизбежно нужно менять на новую) решение отмерло естественным путем и к началу тысячелетия фирма Dallas разорилась. Но ее остроумным придумкам умереть не дала издавна с ней сотрудничающая фирма Maxim, в 2001 году поглотившая Dallas со всеми патентами и товарными знаками, чему мы и обязаны сохранением торговой марки DS.
Добавим, что совсем недавно, в июле 2020 года, Maxim сама была поглощена своим главным конкурентом Analog Devices. Sic transit gloria mundi. Но стоит надеяться, что узнаваемая торговая марка DS все равно никуда не денется.
На простую шину 1-Wire можно сажать до десятков устройств на расстоянии до 30 м, или до 200-300 шт на расстояниях до 100-300 метров с применением специальных интерфейсных модулей и витой пары (подробности для интересующихся см. тут). Цифра 30 м относится к режиму «паразитного» питания, с отдельным питанием длина линии может быть больше даже без специальных мер. Но такие задачи возникают относительно редко — например, в публикациях упоминается распределенный контроль температуры в помещениях типа овощехранилищ. В любительской практике датчики, если их больше одного, обычно принципиально разнесены в пространстве (внешний и внутренний у метеостанции, два датчика для двух разных парников в огороде), и проще организовать беспроводную связь, чем тащить провода. Потому мы вместо 64-битного индивидуального номера DS18b20 и применяем самодельный идентификатор для беспроводных датчиков.
При ознакомлении с описанием DS18b20 поражаешься количеству наворотов, реализованных в таком простом и дешевом устройстве. Конечно, мы будем применять датчик в самом простом режиме однократного считывания температуры, но иметь в виду эти возможности следует.
Текст программы передатчика (HC-12_peredatchik_DS18b02.asm) можно найти все в том же архиве по адресу в конце статьи. Программа основана на приведенной выше программе посылки двухбайтового числа с идентификатором передатчика (H-12_peredatchik_2313_WDT.asm), но вместо произвольного числа один раз посылает считанный с датчика двухбайтовый код. В целях энергосбережения время между посылками увеличено до 8 секунд (его можно увеличить еще больше, если осуществлять вывод не в каждом прерывании WDT, а отсчитывать, например, каждое четвертое или даже восьмое). Обработку данных целесообразно производить на приемном конце, и на этом вопросе мы остановимся подробнее: — во-первых, это хорошая иллюстрация к ассемблерным методам обработки чисел на 8-разрядном контроллере, во-вторых, потому что этот вопрос применительно к датчику DS18b20 уже двадцать лет не сходит со страниц форумов по электронике и нередко ответы на него оказываются довольно причудливыми.
Формат данных о температуре, выдаваемых датчиком, устроен довольно остроумно. Содержимое двух байтов при умолчательном 12-битовом разрешении (остальные, очевидно, нужны для сокращения времени измерения при непрерывном преобразовании) представлено на стр. 6 фирменного руководства. На самом деле там не 12 значащих бит, а 11, 12-й (старший) представляет знак (1- минус, 0 — плюс), а максимальная температура равна 125 градусам и целая часть укладывается в 7 бит. Эти биты целой части распределены между двумя байтами по тетраде в каждом, так, что младшая тетрада старшего байта содержит старшие четыре бита температуры в градусах Цельсия (самый старший бит тетрады, напомню, несет только знак), а старшая тетрада младшего байта – младшие четыре бита. Оставшаяся младшая тетрада младшего байта несет десятичную дробную часть значения температуры, но выраженную в виде шестнадцатеричной дроби. Для тех, кто не понял, воспроизведу здесь картинку с указанной страницы руководства:
Пусть вас не путают авторы некоторых сомнительных примеров: при отрицательных температурах все происходит по правилам представления отрицательных чисел в двоичном исчислении. Для получения отрицательного значения в датчике вычисляется дополнительный код (дополнение до двух) для всего 12-битного числа, а не отдельно для целой и дробной части. Потому, если отвлечься от гениальных высокоуровневых функций языка C, позволяющих все преобразования выполнить за одно действие, то обычная разборка этого формата предусматривает следующие шаги:
а) Определение знака (сравнением какого-нибудь из старших пяти бит старшего байта с единицей). При положительном знаке — сразу переход к пункту «в».
б) При отрицательном знаке производится дополнительное преобразование в положительный код: знак запоминается (и потом выводится), а для самого двухбайтового числа вычисляется дополнение до двух, которое и будет положительным числом. Дополнение до двух можно вычислять миллионом разных способов: например, в C-нотации это выглядит просто, как
XXXX+1 (где XXXX — исходное отрицательное 2-байтовое число в дополнительном коде, а применяемый способ инвертирования битов определяет компилятор — можно, например, применить побитовое «исключающее ИЛИ» с числом 0xFFFF). Ту же самую операцию можно выполнить и простым вычитанием из максимального числа диапазона с прибавлением единицы: 0xFFFF – XXXX + 1. Обратите внимание, что разработчики из Dallas мудро заполнили все неиспользуемые старшие биты старшего разряда значением знака, потому мы можем совершать манипуляции с полным 16-разрядным числом, не заботясь о специальном выделении 12-разрядного результата.
В AVR-ассемблере все это делается побайтно и с помощью специальных команд com и neg ( com — просто инвертирование битов, что равносильно операции вычитания из $FF, а neg — нахождение дополнительного кода, то есть инвертирования с прибавлением единицы, или вычитания из $(1)00):
com valueH ;инвертируем старший байт
neg valueL ;младший -> доп. код
sbci valueH,0xFF ;UPD — спасибо GarryC за указание на ошибку
в) Усечение результата до одного десятичного знака после запятой. В принципе мы можем получить аж четыре знака после запятой (цена младшего разряда 0,0625 °С), и некоторые Arduino-библиотеки так и поступают. Что, конечно, полная фикция, так как при разрешении 1/16 °С даже два знака после запятой (т.е. 0,01 градус) в шесть с лишним раз перекрывают это разрешение, и в 50 раз — реальную погрешность датчика, равную 0,5 градуса. (Скажу по секрету, что погрешность в сотую градуса достигается только с платиновым термометром на лабораторном оборудовании). Так что не будем занимать лишнее место на фейковые разряды, ничего реального не отражающие, и обойдемся десятыми градуса.
Мы не будем даже городить строгое округление, так как десятая градуса все равно в пять раз меньше погрешности датчика, а алгоритм простого усечения получается куда менее громоздкий. Для поразрядного вывода на дисплей нам удобнее сразу иметь целое число, выраженное в десятых градуса, и потом установить точку на нужное место вручную. Иными словами, нам надо умножить полученное число на 10 и поделить на 16, или, что то же самое, умножить на 5 и поделить на 8.
В Tiny нет аппаратного умножения, потому в целях универсальности кода (чтобы он одинаково годился и для Tiny и для Mega) умножение на 5 составляем из нескольких действий согласно формуле X*4+X. Умножение на 4 на ассемблере естественно выполнять двойным сдвигом влево, но если разобраться поглубже, то окажется, что инструкция сложения регистра с самим собой не только делает то же самое, что и сдвиг влево на один разряд, но даже совпадает с ним по коду команды. Иными словами, это одна и та же команда, потому для единообразия употребим сложение, а вот деление на 8 будем делать тройным сдвигом вправо (здесь valueH:valueL – старший и младший байты полученного числа):
После этого полученное число осталось конвертировать в три отдельных десятичных разряда и вывести на дисплей. Заметим, что максимальная величина температуры у нас будет состоять из трех десятичных разрядов (по образцу «99,9»), но выше 99 градусов мы температуру все равно не меряем. Принцип устройства процедур bin2BCD10 и unpack_bcd8 описан в книге:
В этом выводе предусмотрено игнорирование ведущего нуля в разряде десятков градусов. Но если мы просто пропустим вывод в эту лишнюю позицию на экране, то вся строка градусов окажется короче на один символ, и при переходе от двухразрядного значения целых градусов («+10.0 ºС») к одноразрядному («+9,9 ºС») у вас, очевидно, два раза пропечатается конечный символ «С». Очистка всего экрана перед выводом строки, конечно, самый простой метод, но не самый лучший: процедура довольно долгая и экран будет заметно мигать, а если выводится еще что-то (во вторую строку, например), то придется без нужды обновлять и эти данные. Есть и много других способов, но мы применяем самый простой и кратчайший по времени, к тому же не затрагивающий остальные данные на экране: выдерживаем одну и ту же длину строки, независимо от величины градусов (она окажется равной 8 символов). Поэтому мы усложняем программу и выводим пробел вместо нуля в разряде десятков градусов.
Полностью программу HC-12_priemnik_OLED16x02_DS18b20.asm можно скачать из архива по адресу ниже. Результат совместной работы обеих ассемблерных программ с датчиком DS18b20 и модулем HC-12 показан на рисунке:
При отладке обеих программ следует учесть, что первое измерение после включения питания передатчика будет содержать ошибочные данные. Возможно, это связано с какими-то особенностями начальных установок программы, возможно свойство самого датчика, но копаться в этом, на мой взгляд, не имеет смысла — уже второе измерение будет правильным.
Одно из восхитительных свойств DS18b20 — то, что он совершенно не дребезжит и, соответственно, не требует осреднения показаний по времени из нескольких значений. Аналоговые датчики с измерением через АЦП таким качеством похвастаться не могут, да и значительная часть цифровых тоже.
Как вы думаете, чего в этой приемной программе не хватает до полноценного термометра? Разумеется, таймаута на прием данных. Если все оставить, как есть, то после прекращения поступления данных на вход приемника (что может случиться по множеству причин) на дисплее зависнет последнее принятое значение, и вы еще долго не узнаете о том, что передача у вас прекратилась. Потому воспримем эту версию программы, как полуфабрикат для дальнейшего совершенствования, и соорудим для примера вариант с периодической проверкой поступления данных (HC-12_priemnik_OLED16x02_DS18b20_timer.asm).
Для этого добавим к системе таймер, вызывающий прерывания каждую секунду, и будем наращивать в этих прерываниях некий глобальный счетчик. Счетчик будет обнуляться один раз в 8 секунд после каждого приема данных. Посчитаем, что пара пропусков передачи — допустимая ситуация (мало ли, вдруг недалеко молния ударила и навела помехи), и поставим граничным значением, например, 20 секунд. При превышении этого значения выводим прямо в прерывании таймера вместо строки градусов 8 прочерков-пробелов в те же позиции. При первом же корректном приеме данных прочерки заменятся на обычную строку градусов, счетчик сбросится и прочерки выводиться перестанут.
Радио модуль 433.4МГц HC-12 (Trema-модуль V2.0)
Trema-модуль HC-12 — это беспроводной полудуплексный модуль UART позволяющий передавать и принимать данные в диапазоне частот от 433,4 МГц до 473МГц на скорости от 1200 до 115200 бод.
Видео:
Спецификация:
- Напряжение питания: 3,3 . 5 В
- Потребляемый ток при передаче данных: 100 мА
- Диапазон частот: 433,4 . 473 МГц
- Мощность передатчика: до +20 дБм
- Чувствительность приёмника: до -117 дБм
- Дальность связи: до 1 КМ на открытой местности (на скорости 1200 бод)
- Интерфейс: UART
- Поддерживаемые скорости UART: 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 бит/сек
- Установки по умолчанию: FU3, 9600 бод, 8-N-1, CH001
- Рабочая температура: -25 . +75°C
- Рабочая частота: 433 МГц
- Коэффициент стоячей волны: <=1.5 на 433МГц
- Импеданс: 50Ω
- Длина с коаксиальным шнуром: 10 . 15 см
- Разъём: IPEX
Все модули линейки «Trema» выполнены в одном формате
Подключение:
Trema-модуль HC-12 подключается к Arduino по шине UART (можно использовать как аппаратную так и программную шину).
- Вывод модуля TX подключается к аппаратному (фиксированному) или программному (назначенному) выводу RXArduino. Это линия шины UART для передачи данных от модуля к Arduino.
- Вывод модуля RX подключается к аппаратному (фиксированному) или программному (назначенному) выводу TXArduino. Это линия шины UART для передачи данных в модуль от Arduino.
- Вывод модуля S подключается к любому выводу Arduino номер которого указывается в скетче. Это линия перевода модуля в режим AT-команд. Модуль будет воспринимать AT-команды, только во время подачи на этот вывод низкого уровня.
Модуль удобно подключать 4 способами, в зависимости от ситуации:
Способ — 1 : Используя провода, Piranha UNO и программный UART
Используя провода «Папа — Мама», подключаем напрямую к контроллеру Piranha UNO.
Способ — 2 : Используя провода, Piranha ULTRA и аппаратный UART
Используя провода «Папа — Мама», подключаем напрямую к контроллеру Piranha ULTRA.
С данным подключением будет использоваться второй аппаратный UART на Piranha ULTRA. Стоит заметить, что программный порт на UNO безошибочно работает на скорости до 57600 бод, в то время как аппаратный без проблем может работать на скорости 115200, вдвое большей.
Способ — 3 : Используя Trema Set Shield
В примерах ниже мы будем использовать программный UART на 8 и 9 цифровых выводах, поэтому для удобства подключения можно установить модуль в 3-ю ячейку Trema Set Shield. Так же на этих выводах находиться аппаратный порт Piranha ULTRA, что ещё больше упрощает работу с модулем.
Способ — 4 : Используя проводной шлейф и Shield
Используя 2-х и 3-х проводные шлейфы, к Trema Shield, Trema-Power Shield, Motor Shield, Trema Shield NANO и тд.
Способ — 5 : Напрямую к ПК через USB-UART
Используя USB-UART преобразователь Piranha можно подключить напрямую к ПК. При этом можно получать данные и отправлять команды на Arduino по радиоканалу, как если бы Arduino была подключена по проводу. Пример скетча для данного подключения.
Питание:
Входное напряжение питания 3,3 или 5 В постоянного тока, подаётся на выводы V и G модуля. Для работы от 3,3 В джампер под пайку сзади модуля должен быть запаян.
Подробнее о модуле:
Модуль работает в диапазоне частот от 433,4 МГц до 473МГц, имеет возможность выбора каналов от 1 до 100, возможность выбора восьми вариантов мощности передатчика от -1 дБм до 20 дБм при этом расстояние передачи может достигать 1000 метров на открытой местности при скорости передачи данных в эфире 5000 бит/с.
Модуль является полудуплексным, это означает что он может принимать или отправлять данные.
Режимы работы модуля
Модуль имеет четыре режима работы: FU1, FU2, FU3, FU4 и режим приём AT команд. Для перехода в режим приёма AT команд вывод S модуля необходимо прижать к земле (режим логического «0»). Режимы FU отвечают за приём и передачу данных последовательного порта.
Режим FU1 — режим относительно низкого энергопотребления, с током покоя 3,6 мА. В этом режиме можно выбирать скорость передачи данных по проводу arduino-модуль, но скорость в эфире постоянна и равна 250`000 бит/сек.
Режим FU2 — режим очень низкого энергопотребления, с током покоя 80 мкА. В этом режиме скорости передачи данных могут быть 1200, 2400 и 4800 бит/сек. Скорость в эфире фиксирована и равна 250`000 бит/сек. В этом режиме интервал между пакетами данных должен быть больше 1 секунды, иначе данные будут потеряны.
Режим FU3 — режим по умолчанию, потребляемый ток покоя 16 мА, скорость передачи данных в эфире автоматически переключается в зависимости от скорости проводного последовательного порта по следующей таблице:
Скорость передачи по проводу, бит/сек | 1`200/2`400 | 4`800/9`600 | 19`200/38`400 | 57`600/115`200 |
Скорость передачи в эфире, бит/сек | 5`000 | 15`000 | 58`000 | 236`000 |
Чем ниже скорость передачи по проводу — тем больше расстояние передачи модуля.
Режим FU4 — режим максимальной дальности, ток покоя 16 мА, поддерживает только одну скорость передачи равную 1200 бит/сек при этом скорость передачи в эфире уменьшается до 500 бит/сек, для наибольшей дальности связи. В этом режиме можно передавать не больше 60 байтов за раз, при этом интервал между пакетами должен превышать 2 секунды во избежание потерь данных.
Таблица режимов
Режимы: | FU1 | FU2 | FU3 | FU4 | Комментарий |
---|---|---|---|---|---|
Ток покоя | 3,6 мА | 80 мкА | 16 мА | 16 мА | Среднее значение |
Задержка передачи | 15-25 мс | 500 мс | 4-80 мс | 1000 мс | Передача одного байта |
Дальность передачи, W = 20 дБм | до 100 м | до 100 м | до 600м на 9600 бит/сек; до 1000 метров на 2400 бит/сек | до 1800 метров на 1200 бит/сек | Прямая видимость и идеальные условия, зависит от антенны. |
Для того чтобы модули могли связаться друг с другом у них должен быть выставлен одинаковый режим работы и скорость.
Чувствительность приёмника
Чувствительность приёмника модуля зависит от скорости передачи данных по следующей таблице:
Скорость передачи в эфире | 5`000 бит/сек | 15`000 бит/сек | 58`000 бит/сек | 236`000 бит/сек |
Чувствительность приёмника | -117 дБм | -112 дБм | -107 дБм | -100 дБм |
AT команды модуля:
Для перехода в режим AT команд необходимо притянуть вывод S модуля к земле (логическому нулю). Для входа в режим AT команд модулю необходимо 40 миллисекунд. Для выхода из режима AT команд модулю необходимо 80 миллисекунд.
- AT
тестовая команда, при удачном выполнении модуль возвращает «OK»
- AT+Bxxxx
Команда установки скорости обмена данными с микроконтроллером, где «xxxx» это скорость. Может быть 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200. Пример:
AT+B4800, при удачном выполнении модуль вернёт «OK+B4800»
- AT+Cxxx
Команда смены канала, «xxx» — номер канала (001-100). Значение по умолчанию 001. Пример: «AT+C042» сменит канал на 42 и рабочая частота станет 449,8 МГц. Приёмник модуля очень чувствительный и при использовании на скорости больше 9600 бит в секунду или если модули находятся на небольшом расстоянии друг от друга каналы лучше использовать через один, так как возможны перекрёстные помехи на соседних каналах.
- AT+FUx
Команда смены режима работы модуля. По умолчанию FU3. Для передачи данных модули должны находится в одном режиме.
- AT+ Px
Команда установки уровня мощности передатчика, «x» — от 1 до 8 по следующей таблице:
X | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Мощность (дБм) | -1 | 2 | 5 | 8 | 11 | 14 | 17 | 20 |
Чем выше мощность, тем больше расстояние излучения модуля. При уменьшении мощности на 6 дБ рабочее расстояние уменьшается в 2 раза. Значение по умолчанию — 8.
- AT+Ry
Запрос одного параметра модуля, где «y»: B — запросить скорость передачи данных, C — запросить канал, F — запросить режим работы и P — запросить мощность передатчика. Например: при запросе»AT+RB» модуль ответит «OK+B9600».
- AT+RX
Запросить все параметры модуля.
- AT+Uxxx
Установка параметров передачи данных. Биты данных, бит чётности, стоп-бит. Например, чтобы установить 8 бит данных, бит чётности и 1 стоп-бит посылаем модулю «AT+U8E1», модуль ответит «OK».
- AT+V
Запросить версию прошивки. При запросе «AT+V» модуль ответит «www.hc01.com HC-12 v2.6»
- AT+SLEEP
Перевод в режим сна. Потребляемый ток в данном режиме 22 микроампера. Передача данных в данном режиме невозможна
- AT+DEFAULT
Сброс параметров модуля на значения по умолчанию
- AT+UPDATE
Установка модуля в режим ожидания обновления прошивки
Примеры:
Пример тестирования модуля и сброса настроек на заводские.
Данный скетч сбрасывает настройки модуля на заводские и включает встроенный светодиод Arduino если получен положительный ответ от модуля.
Перевод модуля в режим ручного ввода AT команд
Пример входа в режим ввода AT команд в мониторе порта Arduino. После каждой команды необходим символ новой линии или возврата каретки. Скорость передачи должна быть выставлена на 9600 бод.
Подключение модуля через USB-UART преобразователь
Пример дистанционной отправки команд Arduino, при этом один модуль подключён к ПК через USB-UART преобразователь, второй подключён к Arduino на которую загружен этот скетч. При отправке ключевого слова «toggle» из монитора последовательного порта встроенный светодиод платы будет менять своё состояние.
Соединение двух Arduino через беспроводной UART
Данный пример передаёт «как есть» всё что он получает от модуля в серийный порт Arduino. Пример можно использовать для проверки связи между модулями и для обмена данными между двумя Arduino через беспроводной UART. Для соединения двух Arduino необходимо загрузить данный скетч в обе.
Передача массива и включение светодиода на расстоянии
В примере используются два модуля и две платы Arduino. Модули должны быть установленны на один канал и режим работы (см. первый пример).
Пример передачи массива. Включаем светодиод значением первого байта. Arduino с передатчиком посылает заголовок и массив; Arduino с приёмником ждёт заголовок и принимает массив. Тип массива может быть только byte, char, int8_t или uint8_t,
Скетч принимает массив из скетча выше и включает встроенный светодиод по значению первого байта
Пример переключения каналов модуля.
Пример смены канала передатчика. Передаётся байт на 1-м канале, затем канал переключается и передаётся байт на 3-м канале.
Одинаковый скетч для двух приёмников. Приёмники должны быть установленны на 1-й и 3-й каналы.
Если в последовательный порт приходит байт 0xAA, встроенный светодиод включается. Если приходит любой другой байт, светодиод выключается. Канал модуля должен быть 001 или 003. Выставить канал можно при помощи скетча выше «Перевод модуля в режим ручного ввода AT команд». Для этого из монитора порта необходимо ввести AT+C001 и enter для одного модуля и AT+C003 и enter для другого. Так же это можно сделать автоматически, при помощи скетча «Пример тестирования модуля и сброса настроек на заводские» заменив при этом команду AT+DEFAULT на AT+C003 для одного из модулей.