Скачать их исходные коды можно по следующим ссылкам:
Передатчик
Приемник
Биндинг
В режиме биндинга пульт переключается в режим приема и устанавливает свой адрес в 254.254.254.254. В этом режиме он ожидает специального пакета с приемника. Формат пакета при этом должен быть следующим:
байт | значение |
0 | 0xfa |
1:4 | 4 байта адреса приемника |
При приеме такого пакета, пульт запоминает адрес и отправляет обратно пакет следующего формата:
Байт | значение |
0 | 0x5d |
1:4 | 4 байта адреса приемника (подтверждение) |
5 | Идентификатор привязки |
Пятый байт используется для обеспечения единственности передатчика для привязанного к нему приемника. Значение этого байта берется случайным образом каждый раз при включении режима привязки. Далее, при передаче данных управления моделью, приемник будет рассматривать их только при условии наличия этого идентификатора. Таким образом, обеспечивается защита от одновременной привязки двух пультов к одной модели.
Режим привязки на приемнике включается установкой перемычки на канал ch7 (по маркировке OrangeRx). Перемычку необходимо установить до включения питания. В этом случае приемник так же как и передатчик устанавливает свой адрес в 254.254.254.254. Потом при помощи генератора случайных чисел получаются 4 байта нового адреса для последующей работы в нормальном режиме. Далее он в цикле кратковременно переключается на передачу информации и отправляет свой свежесозданный адрес пульту. После каждой такой попытки следует пауза ожидания ответа.
При получении ответа с пульта приемник записывает в энергонезависимую память свой адрес и контрольный байт пульта. Далее эти же данные применяются в качестве текущих и приемник переходит в режим нормальной работы.
В прошивке пульта основной функцией режима привязки является void BindMode() в файле Model.ino. В прошивке приемника тем же целям служит void DoBind() из файла proto.ino.
Подключение кнопок
dState – байт текущего состояния кнопок;
dChanged – байт, указывающий на то, состояние каких кнопок изменилось.
Соответствие битов кнопкам следующее:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Не используется | Не используется | Кнопка «канал 4» |
Кнопка «bind» |
Кнопка «меню» |
Кнопка «отмена» |
Кнопка «+» |
Кнопка «-» |
Подключение резисторов управления пропорциональными каналами
Стоит заметить, что считывание происходит циклически не с двух, а с трех входов АЦП(4, 5, 6). Шестой вход в оранже не используется и фактически "висит в воздухе". Это не ошибка. Получаемое с него значение - "белый шум" - используется для целей генератора случайных чисел.
Калибровка
Калибровка органов пропорционального управления имеет достаточно простой алгоритм. Сначала предлагается установить ОУ в центральное положение и нажать кнопку "меню". По нажатию кнопки для каждого канала заполняется переменная Center. Далее предлагается переместить каждый ОУ в свои крайние положения. Во время перемещений будут вычеслены максимальное и минимальное значения для каждого канала. Следующее нажатие на кнопку "меню" приводит к записи калибровочных значений в энергонезависимую память микроконтроллера.
Реализация алгоритма калибровки находится в файле analog.ino в функции void ADC_Calibration().
Подключение дисплея
Наиболее подходящим для данного проекта оказался дисплей Arduino TFT. Он практически идеально вписался в имеющийся корпус. Главное же его достоинство – подключение по SPI. Это особенно актуально ввиду большого дефицита свободных пинов на микроконтроллере. Для работы с дисплеем использована библиотека TFT, входящая в Arduino IDE версии 1.0.5 и выше. SD-карта на дисплее пока не используется.
Подключение радиомодуля
За основу пульта был взят OrangeRx OpenLRS модуль приемника. Достаточно подробно я описал его тут. В двух словах - это микроконтроллер AVR atmega328 с трансивером HopeRF RFM22B. За что точно практически сразу захотелось применить хирургическое вмешательство к китайцам, так это за то, что rfm'ка распаяна на программный SPI. Ввиду этого имеет место быть серьезный дефицит свободных пинов. Неудобно, но не смертельно...
Функции для работы с rfm находятся в файлах SoftSPI.ino и rfm22.ino. Необходимые переменные и дефайнсы вынесены в файл config.h.
Настройки моделей (хранение их в EEPROM)
Пульт дает возможность управления моделью посредством двух пропорциональных и четырех дискретных каналов. Пропорциональные каналы описываются следующей структурой данных:
Наименование | Тип данных | Назначение | Область EEPROM |
Center | uint16_t | Нейтральное положение органа управления | Область калибровочных значений |
MaxVal | uint16_t | Крайнее правое положение органа управления | Область калибровочных значений |
MinVal | uint16_t | Крайнее левое положение органа управления | Область калибровочных значений |
chValue | uint16_t | Текущее положение органа управления | |
ExpLeft | uint16_t | Максимальное отклонение управляющего сигнала влево | Область настроек модели |
ExpRight | uint16_t | Максимальное отклонение управляющего сигнала вправо | Область настроек модели |
Trimm | uint8_t | Смещение нейтрального положения | Область настроек модели |
Revers | uint8_t | Реверс канала | Область настроек модели |
Все дискретные каналы описываются двумя переменными с размерностью в один байт:
Наименование | Тип данных | Назначение | Область EEPROM |
dChannels | uint8_t | Текущее состояние кнопок | |
dFix | uint8_t | Режим работы кнопок | Область настроек модели |
Для кнопок возможны два режима работы:
Так же для каждой модели сохраняется еще 4 байта адреса ее приемника и контрольный байт.
Прошивка пульта рассчитана на хранение в энергонезавиломой памяти микроконтроллера настроек для восьми моделей. Именно столько их уместилось в списке на одном экране меню. Памяти хватило бы и на 16, но ввиду природной лени изощеряться со скроллингом в меню я не захотел...
void SetModelDefaults() - сброс настроек модели в исходное состояние. Параметры привязки при этом не сбрасываются.
void LoadModelInfo() - загрузка настроек выбранной модели в оперативную память.
void SaveModelInfo() - сохранение настроек в энергонезависимую память.
Все функции располагаются в файле Storage.ino.
Алгоритм микширования
- Если ADC_Value больше Center, то считать ОУ отклоненным вправо. Выполнить приведение ADC_Value к диапазону значений 1500:2000
- Если ADC_Value меньше Center, то считать ОУ отклоненным влево. Выполнить приведение ADC_Value к диапазону значений 1000:1500
- Если 1 и 2 не выполняются, то считать ADC_Value равным 1500
- Если для канала включен реверс, то «перевернуть» его значение в рамках диапазона 1000:2000 и изменить принятое отклонение в 1/2 на противоположное.
- Если ОУ отклонен вправо, то привести его значение к диапазону 1500 : 1500 + ExpRight
- Если ОУ отклонен влево, то привести его значение к диапазону 1500 + ExpLeft : 1500
- Полученное значение сдвинуть на Trimm - 128
Таким образом имеется возможность задавать кривую изменения пропорционального сигнала по трем точкам.
Функционал реализован в файле Model.ino в void UpdateDigiChannels() и в файле analog.ino в void ADC_Update(uint8_t indx, uint16_t ADC_Value).
Меню
В случае, когда dChanged показывает наличие изменения состояния и текущий экран не является основным, вызывается функция void ButtonPress(). Она реализует основной обработчик меню.
Описание пунктов меню живет в структуреtypedef struct {
String menuname; //отображаемое на экране наименование пункта
byte ParentID; //указатель на экран меню, на котором оно прорисовывается
byte Children; //количество подпунктов
byte LineID; //строка на экране, на которой отображается пункт
} tMenuItem;
tMenuItem MenuItems[MENU_ITEMS_COUNT]; // массив всех элементов меню.
Последние 8 пунктов этого массива соответствуют восьми моделям в памяти пульта. Остальные инициализируются функцией void LoadMenu(). Функция void UpdateScreen(byte ss) отвечает за перерисовку экранов меню. Функция void CallMenuFunc() - вызов действия, связанного с выбранным пунктом. Функция void UpdateSelection() - перерисовка рамки текущего пункта меню без перерисовки всего экрана(чтоб исключить моргание экрана при навигации).В ближайших планах - реализация FHSS и передача телеметрии.
- сделан FHSS. 8 наименее зашумленных каналов подбираются при включении приемника.
- сделана передача телеметрии. пока передается только rssi, но в ближайших планах передача температуры движка и напряжения бортовой батареи
- сделан Failsafe. работает по всем каналам, программируется с пульта.
Исходники тут: http://rc-master.ucoz.ru/publ/19-1-0-103
К сожалению мое нетехническое образование не дает мне возможности в полной мере понять статью.
Но чувствую, что круто заморочено ))))))))))