首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我试着从LIS3DH加速度计上得到读数,我得到了随机数

我试着从LIS3DH加速度计上得到读数,我得到了随机数
EN

Stack Overflow用户
提问于 2022-02-03 23:45:16
回答 1查看 299关注 0票数 0

我有LIS3DH加速度计与i2c连接,当我运行脚本时,它应该打印出x,y,z值,我得到的是随机数。

我在C++中使用i2csmbus库,它们是Linux的一部分。

这是加速度计的(datasheet)https://cdn-shop.adafruit.com/datasheets/LIS3DH.pdf。

我试过更改收款机的地址。

我尝试了__s16而不是__s32

我不确定我是不是错过了一些应该在阅读之前发生的事情。我不知道是否还需要写其他登记簿。我有点不清楚到底是怎么回事,函数底部有从寄存器返回的位数和值。我想学习。

代码语言:javascript
复制
extern "C" {
    #include <linux/i2c-dev.h>
    #include <i2c/smbus.h>
}
#include <sys/ioctl.h>
#include <fcntl.h>    /* For O_RDWR */
#include <unistd.h> 
#include <iostream>
using namespace std;

int file;
int adapter_nr = 1;
const char* filename = "/dev/i2c-8";
int initialize_mpu(int file);
__s32 high;
__s32 low;
__s32 value;
int read_raw_data(int file, __u8 addr);

int main() {
    file = open(filename, O_RDWR);
    if (file < 0) {
        exit(1);
    }
    int addr = 0x18;

    if (ioctl(file, I2C_SLAVE, addr) < 0) {
         exit(1);
    }

    __u8 res;

    __s32 accel_x;
    __s32 accel_y;
    __s32 accel_z;
    
    __s32 accel_x_register_high = 0x29;
    __s32 accel_y_register_high = 0x2B;
    __s32 accel_z_register_high = 0x2D;
    
    char buf[10];
    
    res = i2c_smbus_write_byte_data(file, addr, 0);

    if (res < 0) {
      /* ERROR HANDLING: i2c transaction failed */
    } else {
      /* res contains the read word */
    }
    
    buf[1] = 0x02;
    buf[2] = 0x03;
    if (write(file, buf, 3) != 3) {
      /* ERROR HANDLING: i2c transaction failed */
    }
    initialize_mpu(file);

    while (1) {
        
        accel_x = read_raw_data(file, accel_x_register_high) / 131.0;
        accel_y = read_raw_data(file, accel_y_register_high) / 131.0;
        accel_z = read_raw_data(file, accel_z_register_high) / 131.0;

        cout << accel_x <<" " << accel_y << " " << accel_z << " " << endl;

        usleep(100000);
    }
}


int initialize_mpu(int file) {
    i2c_smbus_write_byte_data(file, 0x20, 0xA7); //Write A7h into CTRL_REG1;      // Turn on the sensor, enable X, Y, Z axes with ODR = 100Hz normal mode.
    i2c_smbus_write_byte_data(file, 0x21, 0x09); //Write 09h into CTRL_REG2;      // High-pass filter (HPF) enabled
    i2c_smbus_write_byte_data(file, 0x22, 0x40); //Write 40h into CTRL_REG3;      // ACC AOI1 interrupt signal is routed to INT1 pin.
    i2c_smbus_write_byte_data(file, 0x23, 0x00); //Write 00h into CTRL_REG4;      // Full Scale = +/-2 g
    i2c_smbus_write_byte_data(file, 0x24, 0x08); //Write 08h into CTRL_REG5;      // Default value is 00 for no latching. Interrupt signals on INT1 pin is not latched.
    // configurations for wakeup and motionless detection
    i2c_smbus_write_byte_data(file, 0x32, 0x10); //Write 10h into INT1_THS;          // Threshold (THS) = 16LSBs * 15.625mg/LSB = 250mg.
    i2c_smbus_write_byte_data(file, 0x33, 0x00); //Write 00h into INT1_DURATION;     // Duration = 1LSBs * (1/10Hz) = 0.1s.
    //readRegister();  //Dummy read to force the HP filter to set reference acceleration/tilt value
    i2c_smbus_write_byte_data(file, 0x30, 0x2A); //Write 2Ah into INT1_CFG;          // Enable XLIE, YLIE, ZLIE interrupt generation, OR logic.
}


// Read the data of two 8-bit registers and compile into one 16-bit value
// register_address is the first (high) register, register_address-1 is the low register
// E.g., if the two registers contain the 8-bit values 0x01 and 0x02, this
// function returns the value 0x0102
int read_raw_data(int file, __u8 register_address) {
    high = i2c_smbus_read_byte_data(file, register_address);
    low = i2c_smbus_read_byte_data(file, register_address-1);
 
    value = (high << 8 | low);
 
    // This converts it from an unsigned 0-63355 value
    // to a signed value between -32769 and 32768
     if (value > 32768)
         value = value - 65536;
 
    return value;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-04 22:52:51

我使用的initialize_mpu注册地址错误。

这个数据表的某个地方有一些配置选项。我申请了一份,现在我拿到了读数。

代码语言:javascript
复制
extern "C" {
    #include <linux/i2c-dev.h>
    #include <i2c/smbus.h>
}
#include <sys/ioctl.h>
#include <fcntl.h>    /* For O_RDWR */
#include <unistd.h> 
#include <iostream>
using namespace std;

int file;
int adapter_nr = 1;
const char* filename = "/dev/i2c-8";
int initialize_mpu(int file);

__s32 high;
__s32 low;
__s32 value;

int read_raw_data(int file, __u8 addr);

int main() {
    file = open(filename, O_RDWR);
    if (file < 0) {
        exit(1);
    }
    int addr = 0x18;

    if (ioctl(file, I2C_SLAVE, addr) < 0) {
         exit(1);
    }

    __u8 res;

//     __s32 whoami;
    __s32 accel_x2;
    __s32 accel_x;
    __s32 accel_y;
    __s32 accel_z;
    
    __s32 accel_x_register_high = 0x29;
    __s32 accel_y_register_high = 0x2B;
    __s32 accel_z_register_high = 0x2D;
    
    res = i2c_smbus_write_byte_data(file, addr, 0);

    if (res < 0) {
      /* ERROR HANDLING: i2c transaction failed */
    } else {
      /* res contains the read word */
    }


               
    initialize_mpu(file);
    
    
    

    while (1) {

        accel_x = read_raw_data(file, accel_x_register_high) / 133.0;
        accel_y = read_raw_data(file, accel_y_register_high) / 133.0;
        accel_z = read_raw_data(file, accel_z_register_high) / 133.0;

        cout << accel_x <<" " << accel_y << " " << accel_z << " " << endl;

        usleep(150000);
    }
}


int initialize_mpu(int file) {
    i2c_smbus_write_byte_data(file, 0x20, 0x57);
    i2c_smbus_write_byte_data(file, 0x21, 0x00);
    i2c_smbus_write_byte_data(file, 0x22, 0x40);
    i2c_smbus_write_byte_data(file, 0x23, 0x00);
    i2c_smbus_write_byte_data(file, 0x24, 0x08);
    i2c_smbus_write_byte_data(file, 0x32, 0x10);
    i2c_smbus_write_byte_data(file, 0x33, 0x00);
    i2c_smbus_write_byte_data(file, 0x30, 0x0A);
}

// Read the data of two 8-bit registers and compile into one 16-bit value
// register_address is the first (high) register, register_address-1 is the low register
// E.g., if the two registers contain the 8-bit values 0x01 and 0x02, this
// function returns the value 0x0102
int read_raw_data(int file, __u8 register_address) {
    high = i2c_smbus_read_byte_data(file, register_address);
    low = i2c_smbus_read_byte_data(file, register_address-1);
 
    value = (high << 8 | low);
 
//     This converts it from an unsigned 0-63355 value
//     to a signed value between -32769 and 32768
     if (value > 32768)
         value = value - 65536);
 
    return value;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70979866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档