Невозможно прочитать необработанные данные из MPU 6050, используя rpi3, используя linux/i2c-dev.h open() и read()

Я новичок в I2C, пытаюсь прочитать данные с GY-521 (MPU-6050), используя RPI 3

Сначала я использовал библиотеку WiringPi для C, а затем библиотеку python smbus. Оба работали нормально и давали постоянные показания. Затем я переключился на метод в этой статье: https://elinux.org/Interfacing_with_I2C_Devices. У меня все адреса выстроены в очередь, но я получаю очень странное и непоследовательное поведение:

• Функция open() завершается успешно почти каждый раз, но функция read() очень часто устанавливает errno в REMOTE I/O ERROR (мне нужно поковыряться с соединением в течение 20-30 секунд, прежде чем я получу успешное чтение). Это странно для меня, учитывая, что методы wiringPi и smbus не имели этой проблемы.

• Согласно данным таблицы ( https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf), IMU должен отправлять данные через буфер FIFO либо в 1024 байта пакеты в "пакетах" или в 16-битных пакетах чаще. Когда я получаю успешное чтение, я заполняю короткий беззнаковый буфер размером 1100 байт. Однако read() всегда возвращает целое число, соответствующее размеру буфера, даже если размер буфера превышает 1024 байта (в данном случае 1100). Возможно ли, что MPU-6050 не может отправить eof после записи 1024 байта в файл? Или это стандартная практика, и программист должен знать, что нужно перестать читать в 1024?

• Я также сравнил множество допустимых выходных данных и не вижу очень очевидной схемы, с которой устанавливаются биты в буфере. Из этого документа https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf я предполагаю, что "чтение из регистра", например, ACCEL_XOUT данные, начинающиеся с 0x3C и заканчивающиеся 0x3D (со страницы 7), просто извлекают данные из некоторого индекса, соответствующего 0x3C и 0x3D в заполненном буфере... Но я не могу найти каких-либо очевидных линейных отображений. Включает ли чтение из регистра какую-либо другую форму сопоставления файлов, а буфер просто заполняется случайными, посторонними данными?

Благодарю.

    // from https://elinux.org/Interfacing_with_I2C_Devices

    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <linux/i2c-dev.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    void sensors_ADC_init(void) {
        int file;
        char filename[40];
        const char *buffer;
        int addr = 0b1101001;   // The I2C address of GY-521, LSB == 1 -> read only

        sprintf(filename,"/dev/i2c-1");
        if ((file = open(filename,O_RDWR)) < 0) {
            printf("Failed to open the bus.");
            /* ERROR HANDLING; you can check errno to see what went wrong */
            exit(1);
        }

        else if (ioctl(file,I2C_SLAVE,addr) < 0) {
            printf("Failed to acquire bus access and/or talk to slave.\n");
            /* ERROR HANDLING; you can check errno to see what went wrong */
            exit(1);
        }
        else{ // opened successfully
            // GY-521 writes 16 bits or 1024 bytes 
            unsigned short buf[550] = {0}; // 1100 byte buffer 
            unsigned short datachunk;
            // Using I2C Read
            int read_ = read(file,buf,1100);
            if (read_ < 0) {
                /* ERROR HANDLING: i2c transaction failed */
                printf("Failed to read from the i2c bus.\n");
                printf("errno =  %s\n", strerror(errno));
                printf("\n\n");
            } else { //successful read
                printf("read  %d bytes\n", read_);
                for(unsigned short i = 0; i < 550; i++){
                    datachunk = buf[i];
                    printf("output: %d , %d index of 550\n", datachunk, i);
                }
            }
        }
    }

    int main(){
        while(1){
            sensors_ADC_init();
        }
    }

0 ответов

Другие вопросы по тегам