0
votes

I'm using Linux Ubuntu and try to get serial communication to work. Ok, what am I using...

I use a Raspberry Pi and connected it via USB/Serial-Adapter with an Inserial Measurement Unit (mulifunction sensor).

Just to clarify what i'm trying to do:

Establishing a connection betwenn Raspberry Pi and IMU.

To run IMU there are given steps i have to follow.

Power-on Sequence:

(a) power-on.
(b) Wait 800ms.
(c) Wait until NOT_READY bit goes to 0. NOT_READY is GLOB_CMD[3Eh]'s bit[10].
TXdata={0x3E,0x00,0x0d}. /* GLOB_CMD read command */
TXdata={0x3E,MSByte,LSByte,0x0d}. /* get response */
Confirm NOT_READY bit.
When NOT_READY becomes 0, it ends. Otherwise , please repeat (c).
(d) Confirm HARD_ERR bits. HARD_ERR is DIAG_STAT[3Ch]'s bit[6:5].
TXdata={0x3C,0x00,0x0d}. /* DIAG_STAT read command */
TXdata={0x3C,MSByte,LSByte,0x0d}. /* get response */
Confirm HARD_ERR is 00.
If HARD_ERR is 00, the IMU is OK. Otherwise, the IMU is faulty.

Register read and write:

[Read Example]
To read a 16bit-data from a register(addr=0x38).
TXdata={0x38,0x00,0x0d}. /* command */
RXdata={0x38,0x04,0x04,0x0d} /* response */
0x04 in 2nd byte of RXdata is Configuration mode.
0x04 in 3rd byte of RXdata is TAP=16.
Please note that read data unit is 16bit, and Most Significant Byte first.
-------------------------------------------------------------
[Write Example]
To write a 8bit-data into a register(addr=0x39).
TXdata={0xB9,0x01,0x0d}. /* command */
RXdata= w/o response
By sending this command, the IMU moves to Sampling mode.
Please note that write data unit is 8bit.

On my Linux Ubuntu there is a ttyUSB0 device given after connecting IMU.

So i tried to set Baudrate, Databits, Stopbits, Parity, flowcontrol. First via stty-command, later with a simple c++-code.

I'm using this c++-code:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstdlib>

void SleepMs(int);

int main(int argc, char** argv)
{
    int fd; // port file descriptor
    char port[20] = "/dev/ttyUSB0"; // port to connect to
    fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY); // connect to port
    if(fd == -1)
    {
        printf("Error while opening the port.\n");
        return 1;
    }
    printf("Port opened successfully.\n");

    fcntl(fd, F_SETOWN, getpid());
    struct termios settings;
    tcgetattr(fd, &settings);
    settings.c_cflag &= ~(CBAUD | CSIZE | CREAD);
    settings.c_cflag |= B230400;
    settings.c_cflag |= CS8;


    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &settings); // apply the settings

    int len = 7;
    unsigned char bytes[len];
    bytes[0] = 0x3E;
    bytes[1] = 0x00;
    bytes[2] = 0x0D;
    bytes[3] = 0x3E;
    bytes[4] = 0x00;
    bytes[5] = 0x00;
    bytes[6] = 0x0D;

    int wr = write(fd, bytes, len);
    unsigned char answer[32];
    SleepMs(350);
    int rd = -1;
    int i;

    while (rd==-1)
    {

    if(wr != 7)
    {
        printf("Error while sending!\n");
    }


    for(i=0; i<len; i++)
    {
        printf("%X sent\n", (unsigned int)bytes[i]);
          SleepMs(350);
    }
    printf("\n");
    printf("%d bytes sent.\n", wr);
    printf("\n");
    printf("Trying to read...\n");
    printf("\n");
    rd = read(fd, answer, 32);
    SleepMs(350);

        printf("%d\n", rd);

    for(i=0; i<rd; i++)
    {
        printf("%X ", (unsigned int)answer[i]);
    }
    printf("\n\n");

    }

    close(fd);
    return 0;
}

void SleepMs(int ms) {
usleep(ms*1000); //convert to microseconds
return;
}

If i start program, it tells me "Port open successfully" and writes given bytes in program. But it receives no data.

I transmit 0x3E 0x00 0x0D to activate GLOB_CMD read command. I have to confirm "Not Ready"-Bit is 0 but i dont get an answer with my serial connection.

So this is where i need your help, maybe someone got a hint for me. How can i communicate with my IMU or via serialcommunication properly with Linux?

1

1 Answers

0
votes

int wr = write(fd, bytes, len);

Your bytes array only needs to be 3 bytes long, so len should be 3. (The 0x3e is what the IMU should respond with, so it shouldn't be in your program except when checking the response.) When you read, you should only read the expected size of the answer (len=4). You don't need to sleep after writing, and probably not after reading.