Опрос USB геймпада

nanotroll
Offline
Зарегистрирован: 24.07.2016

Добрый день!

Есть USB геймпад, подключенный к stm32f4discovery через OTG. Опрос кнопок происходит по такой схеме:

if (Appli_state == APPLICATION_READY)
{
	HID_LOGITECH_F710_Info_TypeDef *logitech_f710_info;
	logitech_f710_info = USBH_HID_GetLogitech_F710_Info(&hUsbHostFS);

	if (logitech_f710_info != NULL)
	{
		Обработка кнопок();
	}
}

С кнопками все работает как надо, проблема с обработкой стиков. Условие if (logitech_f710_info != NULL) означает, что когда ничего не нажато, ничего и не будет происходить. Мне нужно сделать так, чтобы когда я нажал стик вверх, начал выполняться код, а когда отпусил стик - код переставал выполняться. Код, который должен выполняться пока нажат стик представляет собой расчет данных (расчет зависит от переменной) и дальше отправка этих данных по УАРТ. Причем эта отправка должна происходить именно пока нажат и удерживается стик (грубо говоря код зациклен). Проблема состоит в том, что когда я НАЖАЛ стик, данные в стуктуре logitech_f710_info изменились, а когда я продолжаю УДЕРЖИВАТЬ стик, данные не изменяются, поэтому я не попадаю в условие if (logitech_f710_info != NULL). Значение стика остается таким, какое было при нажатии. Если зациклить нужный код с помощью while, то как отследить отпускание стика? Может быть есть способ как решить без использования while?

 

nanotroll
Offline
Зарегистрирован: 24.07.2016

Вот структура функции обработки стика:

если (стик нажат)
{
if (шаг1)
{
посчитать данные1
отправить данные1
}
else if(шаг2)
{
посчитать данные2
отправить данные2
}
шаг++
если шаг>2 шаг=0
}

Получается при нажатии на стик выполняется первый блок if, а дальше просто не попадает в условие  if (logitech_f710_info != NULL).

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nanotroll,

скажите пожалуйста, какую библиотеку Вы используёте? Можно полный скетч глянуть, сл ссылкой на библиотеку, где Вы её брали?

sadman41
Offline
Зарегистрирован: 19.10.2016

Я не нанотроль, но полагаю, что ее зовут "STM32 USB host library"

nanotroll
Offline
Зарегистрирован: 24.07.2016

Да, именно так, STM32 USB host library. Полный код могу выложить, но там много лишнего. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А на чём Вы её гоняете? 

Можно ссылку на библиотеку?

nanotroll
Offline
Зарегистрирован: 24.07.2016

Плата stm32f4discovery настроена как usb хост, там контроллер stm32f407vg. Библиотека http://www.st.com/en/embedded-software/stsw-stm32046.html

nanotroll
Offline
Зарегистрирован: 24.07.2016

Добрый день!

Пока нашел такое решение: в функции обработки стиков выставляю соответствующие переменные-флаги (нажат - отжат). Запускаю таймер, в обработчике прерывания по сравнению по флагам запускается функция отправки данных. Функция обработки стиков: 

void processingAnalogSticks(uint8_t stick_lx, uint8_t stick_ly, uint8_t stick_rx, uint8_t stick_ry)
{
	int tmpLX, tmpLY, tmpRX, tmpRY;

        if (mode == WALK)
	{
		if (stickPressedY(stick_ly))
		{
			tmpLX = map(stick_lx, 0, 255, -10, 10);
			tmpLY = map(stick_ly, 0, 255, -10, 10);
			tmpRY = map(stick_ry, 0, 255, -50, 50);
			solveIK(0, tmpLY, tmpRY, 0, 0, tmpLX);
			moveFlag = 1;
		}
		else
		{	
                        moveFlag = 0;
		}
	}
}

Обработчик прерывания таймера:

void TIM6_DAC_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim6);
  if (moveFlag)
  {
	  moveToGaitPositions();
  }
  else if (moveFlag == 0)
  {
	  if (prev_moveFlag)
	  {
		  moveToStandingPositions();
	  }
  }
  prev_moveFlag = moveFlag;
}

Функции  moveToGaitPositions() и moveToStandingPositions() считают и заполняют массивы данными, которые потом отправляются по uart. Функция формирования строки и отправки по uart:


void moveServos(unsigned int *values, unsigned int servoTime, unsigned int servoDelay)
{
	char data[146];

	strcpy(data, "");
	char temp[10];

	for (uint8_t i = 0; i < 18; i++)
	{
		strcat(data, "#");
		sprintf(temp, "%u", servoNumbers[i]);
		strcat(data, temp);

		strcat(data, "P");
		sprintf(temp, "%u", values[i]);
		strcat(data, temp);
	}

	strcat(data, "T");
	sprintf(temp, "%u", servoTime);
	strcat(data, temp);

	strcat(data, "D");
	sprintf(temp, "%u", servoDelay);
	strcat(data, temp);

	strcat(data, "\r\n");

	if (mode == WALK)
	{
		HAL_UART_Transmit(&huart6, (uint8_t *) data, strlen(data), 0xFFFF);
	}
	else
	{
		HAL_UART_Transmit_DMA(&huart6, (uint8_t *) data, strlen(data));
		while (hdma_usart6_tx.State != HAL_DMA_STATE_READY);
		delay_ms(servoTime + servoDelay);
	}

	for (uint8_t i = 0; i < 18; i++)
	{
		currentPositions[i] = values[i];
	}
}