Electronic – First two byte of Transmit Buffer sent by STM32 to Motor Controller is transferred wrong

brushed-dc-motormotor controllerserialstm32f4uart

I want to use STM32F407VET6 board to send commands to Roboteq Motor Controller MDC2230 and I'm very newbie in embedded systems.

Firstly, I created my project via STM32CubeMX and connected RX and TX to each other. The loop-back worked correctly.

Also I can create communication between my PC and controller via RS232 to USB Converter. If I send "get Left Motor Speed" command via CuteCom, (It's: "?$03 1") Motor controller responds to PC without distortion successfully.

And also STM32 communicates with PC via that converter cable, sends and receives data correctly: I can see outputs of STM32 on CuteCom and can send commands to STM32.

At last, I connected controller to micro-controller. Here is the connection:

+--------------+        +-------------------+      +-------------------+
| "STM32"   TX |------->| R1OUT        R1IN |<-----| DATA OUT (Pin 2)  |
| "USART2"  RX |<-------| T1IN        T1OUT |----->| DATA IN (Pin 3)   |
|          GND |--------| GND           GND |------| GND               |
|         3.3V |--------| 3V-5.5V "MAX3232" |      | "Roboteq MDC2230" |
+--------------+        +-------------------+      +-------------------+

But in the case of STM32 to Roboteq Controller; STM32 sends first two bytes of buffer, wrong. It must be:

( 3f 24 30 33 20 31 0d ) "?$03 1\r" , but CuteCom(*) shows:

( bf 27 30 33 20 31 0d ) "¿'03 1\r" and sometimes(**):

( bf 27 38 33 20 31 0d ) "¿'83 1\r"

Here is some parts of code which works in other cases but not in above connection:

#define MAX_COMMAND_STR_SIZE 32
uint8_t tx_buff[MAX_COMMAND_STR_SIZE]; 
uint8_t rx_buff[MAX_COMMAND_STR_SIZE];
memset(tx_buff, 0x00, MAX_COMMAND_STR_SIZE * sizeof(uint8_t));
memset(rx_buff, 0x5F, MAX_COMMAND_STR_SIZE * sizeof(uint8_t));

sprintf((char*)tx_buff, "?$03 1\r");
while ( 1 )
    {
        dummyInit(&huart2);
        HAL_DMA_Init(&hdma_usart2_tx); // FIXME: Is needed?
        HAL_DMA_Init(&hdma_usart2_rx); // FIXME: Is needed?
        HAL_UART_Transmit_DMA ( &huart2, tx_buff, strlen((char*)tx_buff) );
        HAL_Delay ( 10 );
        HAL_UART_Receive_DMA ( &huart2, rx_buff, MAX_COMMAND_STR_SIZE );

        if ( DEBUG ) printf("tx_buff: %s\n", tx_buff);
        if ( DEBUG ) printf("rx_buff: %s\n", rx_buff);
        if ( DEBUG ) printf ( "DR: %"PRIu32"\n", huart2.Instance->DR );
        if ( DEBUG ) printf ( "ERR: %"PRIu32"\n\n", huart2.ErrorCode );
        //printf("Returned --> %d \n\n", getSpeedL(FALSE));
}

void dummyInit(UART_HandleTypeDef *_huart) // FIXME: if any other way exists, replace with this
{
    __HAL_UART_DISABLE(_huart);

    CLEAR_BIT(_huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
    CLEAR_BIT(_huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));

    __HAL_UART_FLUSH_DRREGISTER(_huart);

    /* Enable the peripheral */
    __HAL_UART_ENABLE(_huart);

    /* Initialize the UART state */
    _huart->ErrorCode = HAL_UART_ERROR_NONE;
    __HAL_UART_RESET_HANDLE_STATE (_huart);
    _huart->gState = HAL_UART_STATE_READY;
    _huart->RxState = HAL_UART_STATE_READY;
    _huart->RxXferCount = 0;
    _huart->TxXferCount = 0;
} 

(*) I'm using some lazy way to read communication between max3232's T1OUT and Roboteq's DATA IN pin. My RS232 to USB converter connected to my pc, and there is M-F Jumper cable on RS232 side. I'm just touching to T1OUT of MAX232.

(**) And CuteCom shows output with noise.

What are the wrong parts of my approach? I know, my first fault is being a Software Engineer, not an Electrical Engineer.

Best Answer

It seems like you have some sort of 7/8 bit format mix-up in your STM32. The difference between the expected and unexpected data is that the MS bit is set. For example, 0x03 vs 0x83 in: ( bf 27 30 33 20 31 0d ) "¿'83 1\r"

Your message format seems to only require 7-bit ASCII values. Study the UART specifications for the STM32 to see if there is some distinction between 7 bit and 8 bit data operation or setup. Also, try ANDing all byte values with 0x7F just prior to loading them into the UART's xmit data register.