我是I2C的初学者,尝试使用rpi 3从GY-521(MPU-6050)读取数据
起初,我使用了C的WiringPi库,然后使用了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在向文件写入1024字节后是否可能无法发送eof?或者这是标准练习,程序员应该知道在1024处停止阅读?
•我也一直在比较很多有效的输出,我没有看到一个非常明显的模式,用于设置缓冲区中的哪些位 . 从这个文档https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf,我假设“从寄存器读取”,例如,从0x3C开始到0x3D(从第7页开始)的ACCEL_XOUT数据,只是从对应于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();
}
}