Плохая новость: мой ESC (см. « Kinetis Drone: Graupner ESC S3055 Failure «) для моего дрона Kinetis все еще не ремонтируется ? . В любом случае, у меня есть много других вещей, которые нужно сделать для моего проекта дрона. Один из них — работать над пульт дистанционного управления:
Испытательная установка
У меня есть Bluetooth и трансивер Nordic nRF24L01 +, подключенный к плате FRDM-22F, который обеспечивает хорошую связь на коротком расстоянии с Bluetooth около 10 м и nRF24L01 + в диапазоне 50-100 м. Для наружного использования мне нужно что-то для диапазона 200-300 м. Поэтому я организовал контроллер Graupner mx-16 : 8-канальный пульт дистанционного управления, идеально подходящий для полета на квадрокоптере:
В комплект поставки mx-16 входит приемник Graupner GR-16 :
Граупнер ГР-16
GR-16 имеет один порт телеметрии / программирования и может управлять до 8 сервоканалами. Так что было бы возможно напрямую подключить 4 ESC квадрокоптера к четырем первым каналам, но тогда у меня не было бы никакой гиростабилизации. Вместо этого я хочу, чтобы Freescale FRDM-K22F считывал сервосигналы и управлял ESC с помощью Kinetis K22F с помощью датчиков.
Поэтому я хотел бы использовать «стандартный» пульт дистанционного управления со «стандартным» приемником, но читать сигнал приемника с помощью микроконтроллера и управлять двигателями с помощью микроконтроллера.
Серво Сигналы
Выходными сигналами трансивера является обычный сервосигнал: 50 Гц с длительностью 1-2 мс:
Типичный сервосигнал
Но 50 Гц довольно медленно для динамической системы, такой как квадрокоптер. Кроме того, это означало бы, что мне нужно выбрать / прочитать по крайней мере четыре таких сигнала, которые были бы выполнимы, но болезненны.
SUMD протокол
Контроллеры полета нуждаются в лучшем способе получения входных сигналов, и для этого существуют несколько аналоговых и сигнальных шинных систем, например, Futaba SBUS или Graupner SUMD .
Вместо отправки значения ШИМ с частотой 50 Гц протокол SUMD представляет собой цифровой сигнал и отправляет несколько каналов с частотой 100 Гц (каждые 10 мс). Захват логического анализатора показывает два 8-канальных пакета данных:
SUMD Data Frames
С SUMD действительно здорово то, что это обычный протокол UART / Serial: 8N1, 115200 бод ?
Пакет данных SUMD
Данные имеют заголовок, за которым следуют данные и контрольная сумма. Для приведенного выше кадра вот что означают значения:
- 0xA8 : идентификация заголовка для Graupner
- 0x01 или 0x81 : Идентификация для кадра данных с передатчиком в отказоустойчивом (0x81) или нормальном (0x01) состоянии
- 0x08 : количество каналов с 16- битными данными каждый
- 0x2EE0… .0x2EE0 : пакеты данных
- 0xF90F : контрольная сумма CRC
: idea: Я бы ожидал, что 0x81 отправляется, когда получение находится в безопасном режиме (см. ниже ниже). Но в моих выводах 0x81 отправляется только в том случае, если приемопередатчик включен без сигнала приемника. В противном случае он отправляет 0x01, даже если он потерял радиосигнал. Это не имеет смысла для меня?
Пакеты данных находятся в диапазоне от 0x1c20 (-150%, 900 мкс, расширенная нижняя позиция) до 0x41a0 (+ 150%, 2100 мкс) для расширенной высокой позиции.
Уровень напряжения
Приемник питается от 5 В постоянного тока, но я не нашел документации об уровне напряжения выходных сигналов. К моему удивлению, сигнал SUMD имеет напряжение 3 В, поэтому нет необходимости использовать преобразователь уровня для использования его с микроконтроллером 3,3 В :-):
SUMD Уровень напряжения
Конфигурация сигнала SUMD
Приемник должен быть настроен на выдачу сигнала SUMD. Сигнал всегда подается на сервопорт номер 8. Настройка скрыта в настройках телеметрии:
Меню телеметрии на mx-16
Затем выберите меню настроек:
Меню настроек телеметрии
Настройка, которую я ищу, находится на странице «RX Servo», за « CH OUT TYPE », который по умолчанию «ONCE» для GR-16:
CH OUT TYPE (по умолчанию)
Следующие типы поддерживаются прошивкой моего ресивера (информация от
- ONCE : выходы приемника передаются в последовательности: рекомендуется для аналоговых сервоприводов. Этот параметр обеспечивает автоматическое управление сервоприводами с использованием цикла 20 мсек — 30 мсек для двенадцатиканального приемника (заказ № 33512) — независимо от значения, установленного и отображаемого на дисплее RX SERVO под пунктом меню ‘ СРОК.
- ЖЕ : выходы приемника передаются в параллельных блоках по четыре, то есть каналы с 1 по 4 и каналы с 5 по 8 принимают сигнал передатчика одновременно в каждом случае: рекомендуется для цифровых сервоприводов. Это особенно полезно, когда несколько сервоприводов используются для определенной функции (например, элеронов), так что все сервоприводы движутся абсолютно синхронно. Также возможно подключение аналоговых сервоприводов; в этом случае вы должны установить 20 мс в пункте меню «PERIOD» на дисплее RX SERVO. Примечание: если вы выберете параметр SAME, особенно важно установить систему питания приемника большой емкости, поскольку почти четыре сервопривода почти всегда работают одновременно, что увеличивает нагрузку на аккумулятор.
- SUMI : (входной сигнал суммы): вход для спутникового ресивера. В этом режиме для резервирования можно использовать «спутниковый» приемник, см. Http://fluggeil.de/articles.php?article_id=116 (на немецком языке).
- SUMD : (Sum digital out) Создает цифровой суммарный сигнал, который может быть считан, например, микроконтроллером. Сигнал суммы содержит все сервосигналы в одном пакете данных, поэтому мне нужно только прочитать этот сигнал. Сигнал SUMD всегда выдается на сервоканале 8 на GR-16, и этот канал может отличаться для каждого приемника.
В режиме SUMD я могу настроить тип отказоустойчивости и количество каналов . В отказоустойчивом режиме я могу указать, что произойдет, если приемник не получит сигнал.
- SUMD OF ( Failsafe OFF ): в случае потери связи сигнал не подается .
- SUMD FS ( Failsafe POSITION ): в случае потери связи отправляются предварительно сконфигурированные отказоустойчивые позиции сервопривода. Например, я могу настроить «безопасные» настройки сервопривода, и если приемник выходит за пределы диапазона, он по умолчанию будет использовать безопасные настройки.
- SUMD HD ( Failsafe HOLD ): в этом режиме приемник будет продолжать излучать последние полученные значения.
Я настроил его для SUMD-FS-08 (SUMD, Failsafe Position с 8 каналами):
Конфигурация SUMD
Сигнал SUMD всегда находится на разъеме сервопривода / канале 8 GR-16:
Сигнал SUMD на 8 канале
SUMD декодер
Используемый мной SUMD-декодер взят из проекта PX4 PixHawk Autopilot ( https://pixhawk.ethz.ch/docs/sumd_8c.html ).
: idea: Исходная реализация PX4 SUMD не обрабатывает отказоустойчивый байт 0x81. Я расширил реализацию, чтобы охватить этот случай.
SUMD Rx Input
Я настроил компонент UART ( AsynchroSerial ) для чтения данных SUMD. Поскольку это только Rx, мне не нужен контакт Tx. Я настроил его для использования UART2 с Rx на PTD2 и 115200 бод. Кроме того, я включил прерывания UART с внутренним буфером в 128 байтов (меньше будет делать это тоже):
Конфигурация SUMD Rx Pin
На рисунке ниже показано подключение с помощью SUMD к UART2 / PTD2:
SUMD проводка
При использовании модуля Bluetooth можно использовать UART0 с RxD на PTD6:
SUMD с Bluetooth в сочетании
Удаленный модуль
Чтобы читать сигналы SUMD, я создал «Удаленный» модуль. Он запускает задачу FreeRTOS для считывания данных из UART. У меня добавлен интерфейс оболочки, чтобы я мог проверить полученные данные канала:
Состояние удаленного канала
/*
* Remote.c
*
* Created on: 31.10.2015
* Author: Erich Styger
*/
#include "Platform.h"
#if PL_HAS_REMOTE
#include
#include "Remote.h"
#include "FRTOS1.h"
#include "SUMDRx.h"
#include "UTIL1.h"
#if PL_HAS_SUMD
#include "SUMD.h"
#endif
#if PL_HAS_SHELL
#include "Shell.h"
#endif
static uint16_t REMOTE_channels[SUMD_MAX_CHANNELS];
#if PL_HAS_SUMD
const uint8_t testSUMD[] = /* test message */
{
0xA8, /* Graupner ID, start */
0x01, /* SUMH/SUMD */
0x08, /* number of channels */
0x2E, 0xE8, /* data channel 1 */
0x2E, 0xD0, /* data channel 2 */
0x2E, 0xF0, /* data channel 3 */
0x2E, 0xe0, /* data channel 4 */
0x2E, 0xE0, /* data channel 5 */
0x2E, 0xE0, /* data channel 6 */
0x2E, 0xE0, /* data channel 6 */
0x2E, 0xE0, /* data channel 8 */
0x57, 0xB4, /* CRC */
};
static uint8_t ReadSUMD(void) {
int res;
int i;
uint8_t rssi=0; /* Received Signal Strength Indicator, not used as SUMD does not provide this */
uint8_t rx_count=0; /* counter of received packets, will be incremented for each received packet */
uint16_t channel_count; /* number of received channels in data packet */
uint16_t channels[SUMD_MAX_CHANNELS]; /* here the channel data get stored */
uint8_t ch;
res = 1; /* preset to accumulating */
while(res==1){
if (SUMDRx_RecvChar(&ch)==ERR_RXEMPTY) {
break;
}
res = sumd_decode(ch, &rssi, &rx_count, &channel_count, &channels[0], sizeof(channels)/sizeof(channels[0]));
/* @return 0 for success (a decoded packet), 1 for no packet yet (accumulating), 2 for unknown packet, 3 for out of sync, 4 for checksum error */
}
if (res!=0) {
return ERR_FAILED;
}
/* copy data */
FRTOS1_taskENTER_CRITICAL();
memcpy(REMOTE_channels, channels, sizeof(REMOTE_channels));
FRTOS1_taskEXIT_CRITICAL();
return ERR_OK;
}
#endif
static void Remote(void *pvParameters) {
(void)pvParameters; /* parameter not used */
uint8_t res;
for(;;) {
#if PL_HAS_SUMD
res = ReadSUMD();
#endif
FRTOS1_vTaskDelay(10/portTICK_RATE_MS);
}
}
#if PL_HAS_SHELL
static void REMOTE_PrintHelp(const CLS1_StdIOType *io) {
CLS1_SendHelpStr((unsigned char*)"remote", (unsigned char*)"Group of remote commands\r\n", io->stdOut);
CLS1_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Shows remote help or status\r\n", io->stdOut);
}
static void REMOTE_PrintStatus(const CLS1_StdIOType *io) {
int i;
uint8_t buf[32];
CLS1_SendStatusStr((unsigned char*)"remote", (unsigned char*)"\r\n", io->stdOut);
CLS1_SendStatusStr((unsigned char*)" channels", "", io->stdOut);
for(i=0;i<sizeof(remote_channels) sizeof(remote_channels[0]);i++)="" {="" cls1_sendnum16u(remote_channels[i],="" io-="">stdOut);
CLS1_SendStr(" ", io->stdOut);
}
CLS1_SendStr("\r\n", io->stdOut);
}
uint8_t REMOTE_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
uint8_t res = ERR_OK;
int32_t val;
const unsigned char *p;
if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, (char*)"remote help")==0) {
REMOTE_PrintHelp(io);
*handled = TRUE;
} else if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_STATUS)==0 || UTIL1_strcmp((char*)cmd, (char*)"remote status")==0) {
REMOTE_PrintStatus(io);
*handled = TRUE;
}
return res;
}
#endif /* PL_HAS_SHELL */
void REMOTE_Init(void) {
if (FRTOS1_xTaskCreate(
Remote, /* pointer to the task */
"Remote", /* task name for kernel awareness debugging */
configMINIMAL_STACK_SIZE, /* task stack size */
(void*)NULL, /* optional task startup argument */
tskIDLE_PRIORITY+2, /* initial priority */
(xTaskHandle*)NULL /* optional task handle to create */
) != pdPASS)
{
for(;;){} /* error! probably out of memory */
}
}
#endif /* PL_HAS_REMOTE */
Первые тестовые прогоны
И вот моя грубая тестовая установка: квадрокоптер (плата FRDM-K22F, двигатели и приемник) питается от батареи. Пульт дистанционного управления используется для воздействия на скорость двигателя (-ов).
Тестовая установка Kinetis Drone с Graupner MX-16
По соображениям безопасности только один мотор, а квадрокоптер привязан к земле :-):
- Включение питания для вертолета
- Включение пульта дистанционного управления и включение радио
- Перемещение палки, чтобы повлиять на двигатель
Резюме
Теперь у меня есть возможность использовать обычный пульт управления с приемником для отправки сигналов в микроконтроллер. Используя сигнал SUMD, я могу использовать UART для считывания сигнала суммы, а затем обработать его микроконтроллером. Таким образом, у меня есть удобный способ управлять моим квадрокоптером, любым роботом или чем-то еще, для чего я хочу иметь удаленный контроллер ? .
Одним из следующих шагов будет очистка аппаратной проводки и использование датчиков, чтобы помочь мне управлять этим зверем ? . И да, мне тоже нужно починить ESC…
Счастливого удаления ?
ССЫЛКИ:
- Проект Kinetis Drone на GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-K22F/FRDM-K22F_Drone
- Используемые компоненты Processor Expert: DDD
- Контроллер Graupner mx-16: http://www.graupner.de/en/products/1d80881f-8353-4c86-8a6d-2ebefc64e1c1/33116/product.aspx
- Приемник Graupner GR-16: http://www.graupner.de/en/products/d3601541-a7a0-4f5f-8f0a-a624d262d28f/33508/product.aspx
- Типы радиоуправления: http://blog.oscarliang.net/pwm-ppm-sbus-dsm2-dsmx-sumd-difference/
- Протокол данных Graupner SUMD: http://www.deviationtx.com/media/kunena/attachments/98/HoTT-SUMD-Spec-REV01-12062012-pdf.pdf
- Проект автопилота PX4 PixHawk: https://pixhawk.ethz.ch/ , https://pixhawk.org/start.
- Сборка рамы Quadrocopter : « Kinetis Drone: конструкция рамы с Graupner Race Copter Alpha 250 Q »
- Вождение ESC’s: Kinetis Drone: Вождение электронных регуляторов скорости
- Sensor Fusion: Kinetis Drone: Панель инструментов Sensor Fusion
- Точка отказа ESCs: Kinetis Drone: Graupner ESC S3055 Failure