Robomaster electrically controlled entry (2) DR16 & DT7 receiving and decoding

Introduction Kit

Means Robomaster the remote control robot is fixed, can only use DR16 & DT7 suite Dajiang provided by the sending and receiving of data manipulation. This manual can be downloaded to a suite in Robomaster's official website, which has detailed instructions, as well as to decode the official demo.

https://www.robomaster.com/zh-CN/products/components/detail/122

Control data may be sent directly by the remote DT7, also the remote controller may be connected to the computer through a data line, and then open the mouse and keyboard operations within the transmission Robomaster client interface, the remote client will be to the receiver.

Before using kit DT7 & DR16 it has been necessary to ensure successful pairing between the receiver and the remote controller.

LED on DR16 generally have three states: red light, green light flashes, the green light, the state corresponding to the following:

LED status Corresponding states
Red light Not detected to the remote controller
Flashing green Detector to the remote controller, but the pairing
Steady green Paired with the remote controller

Open pairing method requires the paired remote and the receiver, the frequency of the press button about 10s, and then release.

Kit following parameters, the communication distance can reach full 1km, actual use is indeed very stable, DJI or regressed. However, it notes that the remote control is very DT7 impact, the antenna is also easy to break, remember to protect.

DBUS protocol

Between the receiver and the receiver using DBUS protocol for communication, this DBUS protocol and common SBUS protocol should be the same thing, I do not know why the change of name.

Signal level to the TTL level, and it is the inverse of the UART, an inverter needs to enter through the serial port to the microcontroller receives. This can take their own inverters, two resistors plus a transistor on it.

Setting the parameters of the serial port when receiving shining parameter table.

Of course also be connected directly reserved for Robomaster development board DR16 receiver interface, serial port 1 is generally directly on the line drawn to connect the corresponding receiver, built-in interface to an inverter. Level between the UART and the DBUS standard inverted relationship, it can not be connected to any other port.

Data frame analysis

Here began highlight - the data frame transmitted to the remote receiver. In actual use, we need the received data stream is decoded, the value of the received data stream "translated" into the corresponding remote / keyboard / mouse. DBUS 18 data bytes a.

The receiver may be via an inverter, connected to TTL module to the USB, and connected to the PC, open into a hexadecimal serial assistant to look at the display.

A typical frame length of data follows

00 04 20 00 01 78 00 00 00 00 00 00 00 00 00 00 00 00

It corresponds to the official to the manual, it is easy to understand the meaning of the data frame.

In the numerical example channel 0, the first two bytes of the above data frame is written in binary form, to obtain

0000 0000 0000 0010

As a rule, after the second byte as the high eight 3, a first low-order byte integrally connected together, to obtain

010 0000 0000

This binary number is converted into the decimal value obtained is exactly the 10 th power of 2, i.e., 1024.

Can be separated in the same way - splicing out all the data values, we actually decoding the remote control function is what made this work.

Example decoding received DMA &&

Here official Open Source example to explain the process of decoding the remote control receiver +.

https://github.com/RoboMaster/RoboRTS-Firmware

In dbus.c below, we can see the official decoding function, which includes work done - separation of data and splice; zero drift in order to prevent the remote control data, a set of positive and negative dead zone 5; data overflow deal with

static void get_dr16_data(rc_device_t rc_dev, uint8_t *buff)
{

  memcpy(&(rc_dev->last_rc_info), &rc_dev->rc_info, sizeof(struct rc_info));

  rc_info_t rc = &rc_dev->rc_info;
  
  //satori:这里完成的是数据的分离和拼接,减去1024是为了让数据的中间值变为0
  rc->ch1 = (buff[0] | buff[1] << 8) & 0x07FF;
  rc->ch1 -= 1024;
  rc->ch2 = (buff[1] >> 3 | buff[2] << 5) & 0x07FF;
  rc->ch2 -= 1024;
  rc->ch3 = (buff[2] >> 6 | buff[3] << 2 | buff[4] << 10) & 0x07FF;
  rc->ch3 -= 1024;
  rc->ch4 = (buff[4] >> 1 | buff[5] << 7) & 0x07FF;
  rc->ch4 -= 1024;
  
  //satori:防止数据零漂,设置正负5的死区
  /* prevent remote control zero deviation */
  if(rc->ch1 <= 5 && rc->ch1 >= -5)
    rc->ch1 = 0;
  if(rc->ch2 <= 5 && rc->ch2 >= -5)
    rc->ch2 = 0;
  if(rc->ch3 <= 5 && rc->ch3 >= -5)
    rc->ch3 = 0;
  if(rc->ch4 <= 5 && rc->ch4 >= -5)
    rc->ch4 = 0;
  
  rc->sw1 = ((buff[5] >> 4) & 0x000C) >> 2;
  rc->sw2 = (buff[5] >> 4) & 0x0003;
  
  //satori:防止数据溢出
  if ((abs(rc->ch1) > 660) || \
      (abs(rc->ch2) > 660) || \
      (abs(rc->ch3) > 660) || \
      (abs(rc->ch4) > 660))
  {
    memset(rc, 0, sizeof(struct rc_info));
    return ;
  }

  rc->mouse.x = buff[6] | (buff[7] << 8); // x axis
  rc->mouse.y = buff[8] | (buff[9] << 8);
  rc->mouse.z = buff[10] | (buff[11] << 8);

  rc->mouse.l = buff[12];
  rc->mouse.r = buff[13];

  rc->kb.key_code = buff[14] | buff[15] << 8; // key borad code
  rc->wheel = (buff[16] | buff[17] << 8) - 1024;
}

Find the corresponding data structure rc_info, the contents of the manual and its contents completely correspondence, you can see the official follow-up to the code in order to facilitate the preparation of the code used in the Commonwealth of data at the keyboard.

struct rc_info
{
  /* rocker channel information */
  int16_t ch1;
  int16_t ch2;
  int16_t ch3;
  int16_t ch4;
  /* left and right lever information */
  uint8_t sw1;
  uint8_t sw2;
  /* mouse movement and button information */
  struct
  {
    int16_t x;
    int16_t y;
    int16_t z;

    uint8_t l;
    uint8_t r;
  } mouse;
  /* keyboard key information */
  union {
    uint16_t key_code;
    struct
    {
      uint16_t W : 1;
      uint16_t S : 1;
      uint16_t A : 1;
      uint16_t D : 1;
      uint16_t SHIFT : 1;
      uint16_t CTRL : 1;
      uint16_t Q : 1;
      uint16_t E : 1;
      uint16_t R : 1;
      uint16_t F : 1;
      uint16_t G : 1;
      uint16_t Z : 1;
      uint16_t X : 1;
      uint16_t C : 1;
      uint16_t V : 1;
      uint16_t B : 1;
    } bit;
  } kb;
  int16_t wheel;
};

About receiving remote control data, we can directly decode function is called to find where, in accordance with

get_dr16_data -> rc_device_date_update -> dr16_rx_data_by_uart -> dr16_rx_callback -> dr16_uart_rx_data_handle -> USART1_IRQHandler

May be found to be invoked in the serial receive an interrupt, DMA initialization function as follows

void dr16_uart_init(void)
{
  UART_Receive_DMA_No_IT(&huart1, dr16_uart_rx_buff, DR16_RX_BUFFER_SIZE);
  
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
}

Receiving handler as follows

In addition to throwing some registers operate some of the HAL library in order to drive the DMA, in fact, we can actually see the entire DMA receive logic is very simple, that is, through dr16_uart_rx_buff acquired the DMA data storage array, each time after the completion of reception of the received data length determination, if it is confirmed the 18 bytes of data is determined to be valid, the incoming dr16_rx_callback for further processing.

After although the official code for various purposes is encapsulated many layers, but actually judge the legitimacy of the data reception processing dma function has been decoded data directly into a function.

uint32_t dr16_uart_rx_data_handle(UART_HandleTypeDef *huart)
{
  if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
  {
    /* clear idle it flag avoid idle interrupt all the time */
    __HAL_UART_CLEAR_IDLEFLAG(huart);

    /* clear DMA transfer complete flag */
    __HAL_DMA_DISABLE(huart->hdmarx);

    /* handle dbus data dbus_buf from DMA */
    if ((DR16_RX_BUFFER_SIZE - huart->hdmarx->Instance->NDTR) == DR16_DATA_LEN)
    {
      if (dr16_rx_callback != NULL)
      {
        dr16_rx_callback(dr16_uart_rx_buff, DR16_DATA_LEN);
      }

      if (dr16_forword_callback != NULL)
      {
        dr16_forword_callback(dr16_uart_rx_buff, DR16_DATA_LEN);
      }
    }

    /* restart dma transmission */
    __HAL_DMA_SET_COUNTER(huart->hdmarx, DR16_RX_BUFFER_SIZE);
    __HAL_DMA_ENABLE(huart->hdmarx);
  }
  return 0;
}

Epilogue

So this will speak to this whom, in fact, DR16 & DT7 receives remote control kit is a very easy task, because the robot should be noted that the demand for real-time execution of the task, generally does not employ time-consuming, taking up more resources serial port interrupt way reception, but the use of DMA mode to receive.

Guess you like

Origin www.cnblogs.com/sasasatori/p/11655856.html