В настоящее время схем различных конструкций радио управления моделями достаточно большое количество. Встречаются варианты только с дискретными каналами, с пропорциональным управлением и универсальные (присутствует как дискретное, так и пропорциональное управление). Но у большинства любительских конструкций, а так же у всех коммерческих изделий, есть существенный недостаток - нет исходных кодов программы. В лучшем случае авторы выкладывают demo-версию, которая имеет ограниченную функциональность или время работы.
Это первый фактор, который сподвигнул меня на "отчаянный шаг" - разработку собственной схемы радиоуправления. Второй фактор заключается в том, что подавляющее большинство конструкций не имеет обратной связи. А так как в моем случае необходимо управлять моделью подводной лодки, то необходимо контролировать как минимум два параметра на стороне модели: уровень заряда аккумулятора и наличие воды внутри корпуса модели. Третий же фактор - знакомство с беспроводными модулями NRF24L01+, а так же с их усиленной версией (дальность "стандартной" - около 10 метров) NRF24L01+PA+LNA, которая позволяет "пробить" на целых 1.1 км, в условиях прямой видимости и при скорости передачи 250 кб/с. Ну и конечно, при разработке схемы "с нуля" гораздо проще изначально ее ориентировать на свои нужды.
Что в итоге получилось вы узнаете из данного "цикла" статей. Он состоит из двух публикаций - текущей, в которой описан передатчик а так же следующей, в которой будет описан приемник.
Итак, немного общих сведений о данной системе радиоуправления.
Она имеет 4 цифровых (дискретных) и 4 аналоговых каналов, что позволяет ее использовать для управления моделью любого типа: воздушной, наземной или водной. Кроме того, имеется обратная связь, что особенно удобно при управлении воздушной или водной моделью (на дисплей пульта выводится информация о состоянии заряда батарей, уровне сигнала, наличии воды в корпусе и температуре двигателя). Для отображения информации используется дисплей от телефонов Siemens LPH8731-3C. При разрешении 101х80 пикселей, его вполне хватает для решения поставленных задач.
Решено было использовать NRF24L01+PA+LNA (на AliExpress), дальность связи которых составляет 1,1 км, как упоминалось ранее (против NRF24L01+ , у которых всего 10-15 метров). Цоколевки обоих модулей абсолютно идентичны.
После небольшой вводной, можно приступить непосредственно к теме этой статьи - пульту управления.
"Сердцем" устройства является микроконтроллер ATmega8. Вообще-то на этапе проектирования предполагалось использование микроконтроллера ATmega48, но как выяснилось, написанный код для него был слишком объемным, и впоследствии он был заменен на ATmega8.
Принципиальная схема устройства представлена ниже:
Немного о схеме.
Внимание! На схеме не обозначен интегральный стабилизатор напряжения LM1117-3.3! Он монтируется либо на внешней плате, либо непосредственно на плате пульта. К примеру, я его расположил на свободном от деталей участке платы, и залил термоклеем.
Разъем J1 используется для подключения радио-модуля NRF24L01+. Разъемы J4 и J5 предназначены для упрощения подачи питающего напряжения на какие-либо внешние устройства. J4 подключен к плюсу питания (3.3V), а J5 - к минусу (общему). Кроме того, к этим разъемам так же подключается и стабилизатор LM1117-3.3.
J2 предназначен для измерения уровня заряда аккумуляторов. Для этого, необходимо соединить его контакт №1 с плюсом аккумуляторной батареи. По-умолчанию в прошивке идет расчет уровня заряда для двух последовательно соединенных Li-Ion аккумуляторов (максимальный уровень напряжения 8.4В). Если у вас используется другой тип аккумуляторов, то необходимо внести изменения в прошивку, а так же возможно придется пересчитать делитель напряжения на резисторах R7 и R8, но об это несколько позже. Как вы видите, в схеме имеется еще один неиспользуемый делитель - его предполагалось использовать для контроля напряжения каждой банки в аккумуляторной батарее. В данной версии прошивки он не используется, но может пригодиться, если вы планируете применить в своей конструкции аккумуляторы другого типа. Например, Ni-Mh, Ni-Cd и т.д. , с меньшим напряжением банки и как правило, большим количеством банок в батарее. Правда, для этого придется опять-таки немного модифицировать прошивку.
К разъему J2 подсоединен ЖК дисплей. На принципиальной схеме контактам разъема соответствуют одноименные контакты дисплея (контакт №1 на разъеме совпадает с контактом №1 на дисплее). На практике выглядит так:
Переменные резисторы RV1 - RV4 служат для установки положения исполнительных механизмов, подключенных к приемнику (сервомашинки, регуляторы оборотов двигателя и т.д.).
Кнопки предназначены для дискретного управления нагрузкой, подключенной к отдельному разъему приемника. Они настроены на работу без фиксации.
Программа для микроконтроллера написана на C под AVR-GCC (WinAVR). Кроме стандартных библиотек использовались модифицированные варианты библиотек для дисплея от телефона Siemens A65 (LPH8731-3C.h), и для работы с радиомодулем NRF24L01+. Они присутствуют в прикрепленном файле.
Весь код в статье приводить не буду, он доступен в приложении. Но на некоторых моментах считаю нужным остановиться более подробно.
Кратко о переменных:
const unsigned char mux[][3] = { //Применяется для переключения входа АЦП {0,0,0},{0,0,1},{0,1,0}, {0,1,1},{1,0,0},{1,0,1}, {1,1,0},{1,1,1} }; unsigned char control[4]; //Массив, содержащий значения, соответствующие положению ручек переменных резисторов unsigned char rx_array[8]; //Массив, в который записываются данные для передачи unsigned char tx_array[8]; //Аналогично предыдущему, но для приема unsigned char rx_address[5] = {0xD7,0xD7,0xD7,0xD7,0xD7}; //Адрес устройства, прием unsigned char tx_address[5] = {0xE7,0xE7,0xE7,0xE7,0xE7}; //Аналогично предыдущему, передача unsigned int button_push[16] = {1021, 339, 509, 256, 696, 294, 413, 229, 837, 317, 460, 242, 606, 276, 380, 217}; //Численное значение АЦП для различных комбинаций кнопок volatile unsigned char counter_rx, action; //Отвечают за обновление данных на ЖК volatile unsigned char water, water_old, water_set; //"Водные" переменные. В первую записывается текущее состояние (0 - 1), вторая отвечает за определение изменения. Третья - счетчик. volatile unsigned char button; //Используется для хранения текущего состояния кнопок volatile unsigned int battery_mod, battery_ctrl, signal_level; //Ответственные за отображение уровня батарей и сигнала volatile int ds18temp; //Температура char string[6]; //Нужна для вывода температуры на ЖК
Следующий пункт - реализация контроля двух банок аккумуляторов (либо двух аккумуляторных батарей).
В программе за контроль напряжения батареи пульта отвечает следующая функция:
unsigned char get_battery_control(void) { volatile unsigned char a; battery_ctrl = adc_read(7, 0); // if (battery_ctrl < 204) a = 0; else if (battery_ctrl < 223) a = 1; else if (battery_ctrl < 235) a = 2; else a = 3; // return a; }
Для мониторинга двух банок ее необходимо изменить следующим образом:
unsigned char get_battery_control(void) { unsigned char data[][3] = {{204, 223, 235},{102, 111, 117}}; volatile unsigned char d, e; volatile unsigned int a, b, c; a = adc_read(6, 0); //Задаем канал и разрешение (0 - 10бит, 1 - 8бит). b = adc_read(7, 0); if (b < a) { d = 1; c = a; } else { d = 0; c = b; } // if (c < data[d][0]) e = 0; else if (c < data[d][1]) e = 1; else if (c < data[d][2]) e = 2; else e = 3; // return e; }
Суть сводится к тому, что бы измерить АЦП напряжения на двух банках, а потом выводить на ЖК дисплей наиболее низкое, во избежании критического разряда аккумулятора.
И еще одна остановочка, последняя. Это касается кнопок.
Нажатие кнопки определяется следующим образом. Первым делом с помощью АЦП получаем значение напряжения на выводе, к которому подключены кнопки. Далее, происходит сравнение с переменной, в которой хранятся "эталонные" данные. Сравнение происходит в цикле, и если произошло совпадение, то легко узнать, какие кнопки нажаты. Для этого достаточно перевести число "проходов" цикла в двоичный код. Биты установленные в "1" и есть нажатые кнопки.
unsigned int button_push[16] = {1021, 339, 509, 256, 696, 294, 413, 229, 837, 317, 460, 242, 606, 276, 380, 217}; //Численное значение АЦП для различных комбинаций кнопок ..... void get_button(void) { volatile unsigned char a, i; volatile unsigned int c, e[3]; for (i = 0;i < 3;i++) { e[i] = adc_read(4, 0); } c = (e[0] + e[1] + e[2])/3; //Считаем среднее значение за 3 измерения for (a = 0;a < 16;a++) //Необходимо прокрутить цикл 16 (так как у нас 4 кнопки) { if (c > 1000) button = 0; else if ((c > (button_push[a] - 10))&&(c < (button_push[a] + 10))) button = a; //Проверяем на совпадение. Если в районе +/- 10 ед. , то считаем верным. } }
Для прошивки микроконтроллера в моем случае использовался программатор USBasp в паре с программой Khazama AVR Programmer. Fuse-биты микроконтроллера необходимо выставить следующим образом:
Если вы используете другую программу для прошивки микроконтроллера, то оставляйте все fuse-биты как они были в "чистом" МК, только выберите тактирование от встроенного генератора на 8МГц.
Теперь немного о печатной плате и сборке устройства. Печатная плата выполнена на одностороннем фольгированном материале (текстолит, гетинакс), и имеет размеры 45х55 мм. Топология печатной платы представлена ниже:
Проводники, обозначенные синим цветом - это перемычки. Их можно выполнить, например, из телефонного одножильного кабеля.
Переменные резисторы можно применить любого типа, с сопротивлением 6,8 - 33 кОм. Микроконтроллер в теории можно заменить на ATmega168 или 328, так как они отличаются только объемом памяти программ. ЖК дисплей заменить нельзя, для этого придется использовать другую библиотеку для работы с ним. В качестве интегрального стабилизатора напряжения можно использовать любой линейный или импульсный, рассчитанный на выходное напряжение 3.3 вольта. Это может быть, например, LM1117-3.3. Резисторы R7 - R10 желательно брать презиционные, в противном случае возможно нечеткое определение нажатых кнопок.
Ну и напоследок немного фотографий готового устройства, а так же видео его работы.
Вид платы.
НА этом фото показано как был "установлен" стабилизатор LM1117-3.3. Джампер стоит для подачи 5 вольт на МК, минуя стабилизатор (для программирования).
Это фото сделано не просто так. Внимание! Если у вас есть желание не возиться с модулями NRF24L01+, вопрошая "Почему не передает .... ?", то установите непосредственно на платку параллельно питанию два конденсатора: на 47мкФ и 100нФ. Почему и как, вопрос, но без них стабильная работа практически не возможна.
Вид устройства в сборе.
Отображение данных на ЖК дисплее (приемник отключен).
Спасибо за внимание к этой статье! Удачной вам сборки ваших устройств!
Следующая статья: Радиоуправление на ATmega8 и радиомодулях NRF24L01+PA+LNA. Приемник
Список радиоэлементов
Обозначение | Тип | Номинал | Количество | Примечание | Магазин | Мой блокнот |
---|---|---|---|---|---|---|
U1 | МК AVR 8-бит | ATmega8 | 1 | Поиск в магазине Отрон | ||
U2 | Линейный стабилизатор | LM1117-3.3 | 1 | За пределами платы | Поиск в магазине Отрон | |
U3 | Радиомодуль | NRF24L01+ | 1 | Или его модификация NRF24L01+LNA+PA | Поиск в магазине Отрон | |
LCD1 | LCD-дисплей | LPH8731-3C | 1 | Поиск в магазине Отрон | ||
C1 | Конденсатор | 1000 мкФ | 1 | 6.3В | Поиск в магазине Отрон | |
C2 | Конденсатор | 100 нФ | 1 | 0805 | Поиск в магазине Отрон | |
R1, R4 | Резистор | 2.2 кОм | 2 | 0805 | Поиск в магазине Отрон | |
R2, R8, R10 | Резистор | 10 кОм | 3 | 0805 | Поиск в магазине Отрон | |
R3 | Резистор | 4.7 кОм | 1 | 0805 | Поиск в магазине Отрон | |
R5, R6 | Резистор | 240 Ом | 2 | 0805 | Поиск в магазине Отрон | |
R7, R9, R11 | Резистор | 1.1 кОм | 3 | 0805 | Поиск в магазине Отрон | |
RV1 - RV4 | Переменный резистор | 10к | 4 | СП-1 | Поиск в магазине Отрон | |
J1 - J5 | Разъем | PLS-40 | 1 | Поиск в магазине Отрон | ||
SA1 - SA4 | Переключатели | МП-1 | 4 | Любые | Поиск в магазине Отрон | |
Скачать список элементов (PDF)
Комментарии (4) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация
[Автор]