0
\$\begingroup\$

I'm trying to communicate with a BNO055 using an STM32L552ZET6Q microcontroller via UART. The BNO055 is on a separate board, and connected to the STM32 via a 1.5M cable. Additionally, there are MAX3232CUE+T RS232 chips on either side of the cable, converting the UART data to RS232 and back again. This is to make sure communications aren't corrupted by EMI or simple distance while traveling through the cable.

When observing the data arriving from a logic analyzer, it looks different from what is displayed on the STM32 Debugger (seen below) Also keep in mind that these were both taken as UART (not RS232) in close proximity to the STM32. Logic analysis from STM32L5 to BNO055 UART bus

Debugger display from UART RX

Included below is the code used to write to and read from the BNO055 via UART:

void uartWrite(bno055_uart *chip, uint8_t reg, uint8_t len, uint8_t *buf)
{
    uint8_t status;
    uint8_t feedback[2];
    uint8_t transmit_buf[128] = {0xAA, 0x00, reg, len};
    for(uint8_t x = 0; x < len; x++)
    {
        transmit_buf[x + 4] = buf[x];
    }
    status = HAL_UART_Transmit(&chip->uart_bus, transmit_buf, (len + 4), 50);
    //bno055_delay(10);
    if(status == HAL_OK)
    {
        HAL_UART_Receive(&chip->uart_bus, feedback, 2, 50);

        switch(feedback[1])
        {
        case 0x01:
            return;
            break;
        case 0x03:
            printf("Write Failure in BNO055 UART");
            break;
        case 0x04:
            printf("Invalid Register map address");
            break;
        case 0x05:
            printf("Register Map Write Disabled");
            break;
        case 0x06:
            printf("Wrong Start Byte");
            break;
        case 0x07:
            printf("Bus Over Run Error");
            break;
        case 0x08:
            printf("Max Length Error");
            break;
        case 0x09:
            printf("Min Length Error");
            break;
        case 0x0A:
            printf("Receive Character Timeout");
            break;
        }
        return;
    }

    else
    {
        printf("Error Occurred/r/n");
        return;
    }
}

void uartRead(bno055_uart *chip, uint8_t reg, uint8_t len, uint8_t *data)
{
    uint8_t transmit_buf[128] = {0xAA, 0x01, reg, len};

    HAL_UART_Transmit(&chip->uart_bus, transmit_buf, 4, 50);
    //bno055_delay(10);
    HAL_UART_Receive(&chip->uart_bus, data, (len+2), 50);
    if(data[0] != 0xBB)
    {
        switch(data[1])
        {
            case 0x02:
                printf("Read Failure");
                break;
            case 0x04:
                printf("Register Map Invalid Address");
                break;
            case 0x05:
                printf("Register Map Write Disabled");
                break;
            case 0x06:
                printf("Wrong Start Byte");
                break;
            case 0x07:
                printf("Bus over run error");
                break;
            case 0x08:
                printf("Max length error");
                break;
            case 0x09:
                printf("Min length error");
                break;
            case 0x0A:
                printf("receive character timeout");
        }

    }
}

Edit 1: Below is a picture of the STM32 clock configuration in STM32CubeIDE. Both devices have external 32.768kHz clock sources attached to them.

STM32L5 Clock setup End of Edit 1

Edit 2: I finally had a chance to try running the device with HAL_MAX_DELAY and it looks like the STM32 doesn't realize that anything has arrived on the bus. broken down, it shows the following:

a request is sent for the BNO055's id (0xA0). This command is composed of a start byte (0xAA), Read or Write (0x01 for read), What is being read (0x00) and how many bytes of data the BNO055 should send back (1, 0x01).

The response back from the BNO055 is success (0xBB), length of the data (0x01) and the data (0xA0).

Logic analysis with HAL_MAX_DELAY

However, the HAL_UART_RECEIVE function just keeps waiting for something to show up.

End of Edit 2

Below are links to the BNO055 datasheet, and BNO055 UART application notes respectively, as well as the datasheet for the MAX3232CUE+T: Link to BNO055 Datasheet Link to BNO055 UART application notes Link to MAX3232CUE+T Datasheet

I'm still collecting additional information, so if you have any specific questions, please let me know. Thank you for your assistance!

\$\endgroup\$
16
  • 2
    \$\begingroup\$ Hard to say. What baud rate you are using, and do both devices support it within allowable tolerance? \$\endgroup\$
    – Justme
    Commented Feb 15, 2023 at 19:30
  • \$\begingroup\$ @Justme 115200 baud rate on the STM32 UART and BNO055. From what I could see in the BNO055 application notes I linked, that's the only supported rate. I could be wrong, but I didn't see any other possibilities. Strangely, I didn't see any mention of baud rate in the BNO055 datasheet. \$\endgroup\$
    – E.HP.S
    Commented Feb 15, 2023 at 19:45
  • 2
    \$\begingroup\$ The baud rate is described in the datasheet UART protocol section. But have you measured the baud rates if they match? What clock source and frequency you are using on STM32? What clock source and frequency are you using on sensor? \$\endgroup\$
    – Justme
    Commented Feb 15, 2023 at 19:59
  • \$\begingroup\$ @Justme The STM32's input clock frequency is 32.768kHz, coming from a VMK3-9005-32K7680000 . The BNO055 uses a ECS-.327-12.5-17X-TR as an external clock source (also 32.768kHz). \$\endgroup\$
    – E.HP.S
    Commented Feb 15, 2023 at 20:06
  • 1
    \$\begingroup\$ That STM32 can't run on an external 32768 Hz crystal. Even if it did, it could not reach 115200 with it. So while it may use the LSE crystal for trimming a higher clock, be sure about what exact frequency it runs with, and what tolerance the frequency has. \$\endgroup\$
    – Justme
    Commented Feb 15, 2023 at 20:13

1 Answer 1

1
\$\begingroup\$

Alright, I've got it working!

So, this one was weird, and I'm not 100% sure I understand what happened, but I'm reasonably close.

As I understand it, the BNO055's UART RX buffer was sort of hanging on to old data, preventing it from reading new data and causing it to time out. I added a HAL_UART_AbortReceive() before running HAL_UART_Receive() and it works like a charm! I'm collecting Acceleration, Orientation, Euler & Quaternion data, all over UART/RS232!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.