简体   繁体   中英

rm3100 status register not changing

The rm3100 is working with Arduino Leonardo. I am trying to make it work with esp32.

I am able to write to the registers of an rm3100 and read them. I tried to write to the register and then read its value - it works as expected.

But the measurement registers not changing and the senior bit of the status register (0x34) is always 0. DRDY line stays low.

I tried continuous mode (wrote 0x71 to the register 0x01) and single measurement (wrote 0x70 to the register 0x00).

uint8_t data[1];
write_i2c_register(0x33, 0x8f); // wrote to the test register 0x33
usleep(1000000);
read_i2c_registers(0x33, data, 1);
printf("Test register is %02x\n", data[0]); // printing 0x8f in 0x33 register

write_i2c_register(0x00, 0x70); // initialize single measurement
usleep(1000000);
read_i2c_registers(0x34, data, 1);
printf("Status register is %02x\n", data[0]); // printing 0x00 in 0x34 register

write_i2c_register(0x01, 0x71); // initialize continuous measurement
usleep(1000000);
read_i2c_registers(0x34, data, 1);
printf("Status register is %02x\n", data[0]); // printing 0x00 in 0x34 register

The following points look suspicious:

  1. According to the datasheet https://www.pnicorp.com/wp-content/uploads/RM3100-RM2100-Sensor-Suite-User-Manual-R09-1.pdf – I need to add 0x80 to the register address when reading.

在此处输入图像描述

But it doesn't work in my case – when I add 0x80 – I am getting 0. But when I read without adding – I am getting correct results.

    std::vector<int> regs = {0, 1, 4, 5, 6, 7, 8, 9, 11, 36, 37, 38, 39, 40, 
                             41, 42, 43, 44, 51, 52, 53, 54};
    for (auto i: regs)
    {
        read_i2c_registers(i, data, 1); // when I read without adding 0x80
        printf("%02x=%02x ", i, data[0]); // I am getting reasonable values
    }
    printf("\n");

    for (auto i: regs)
    {
        read_i2c_registers(i + 0x80, data, 1); // when I add 0x80 to the reg address
        printf("%02x=%02x ", i, data[0]);       // I am getting zeros
    }
    printf("\n");
  1. According to the datasheet – I need to send “stop” when after sending the register address when reading.

在此处输入图像描述

It doesn't work – I am getting timeout error.

void read_i2c_registers(uint8_t reg, uint8_t* data, const uint8_t bytes){
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    ESP_ERROR_CHECK(i2c_master_start(cmd));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS_GEO << 1) | I2C_MASTER_WRITE, 1));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, reg, 1));
    // ESP_ERROR_CHECK(i2c_master_stop(cmd)); // <-- timeout when uncommented
    ESP_ERROR_CHECK(i2c_master_start(cmd));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS_GEO << 1) | I2C_MASTER_READ, 1));
    if (bytes > 1)
        ESP_ERROR_CHECK(i2c_master_read(cmd, data, bytes - 1, (i2c_ack_type_t) 0));
    ESP_ERROR_CHECK(i2c_master_read_byte(cmd, data + bytes - 1, (i2c_ack_type_t) 1));
    ESP_ERROR_CHECK(i2c_master_stop(cmd));
    auto err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    if (err != ESP_OK)
    {
        std::cout << "err=" << int(err) << "\n";
    }
}

void write_i2c_register(const uint8_t reg, const uint8_t data){
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    ESP_ERROR_CHECK(i2c_master_start(cmd));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS_GEO << 1) | I2C_MASTER_WRITE, 1));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, reg, 1));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, data, 1)); 
    ESP_ERROR_CHECK(i2c_master_stop(cmd));
    esp_err_t err;
    do err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
    while (err != ESP_OK);
    i2c_cmd_link_delete(cmd);
}

As far as I understand read_i2c_registers should call i2c_master_cmd_begin twice (separately for write part and read part).

I adjusted the code and it works now in continuous mode:

void read_i2c_registers(uint8_t reg, uint8_t* data, const uint8_t bytes){
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    ESP_ERROR_CHECK(i2c_master_start(cmd));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS_GEO << 1) | I2C_MASTER_WRITE, 1));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, reg, 1));
    ESP_ERROR_CHECK(i2c_master_stop(cmd)); // uncommented
    ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 1/portTICK_PERIOD_MS)); // line added
    i2c_cmd_link_delete(cmd); // line added

    cmd = i2c_cmd_link_create(); // line added
    ESP_ERROR_CHECK(i2c_master_start(cmd));
    ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS_GEO << 1) | I2C_MASTER_READ, 1));
    if (bytes > 1)
        ESP_ERROR_CHECK(i2c_master_read(cmd, data, bytes - 1, (i2c_ack_type_t) 0));
    ESP_ERROR_CHECK(i2c_master_read_byte(cmd, data + bytes - 1, (i2c_ack_type_t) 1));
    ESP_ERROR_CHECK(i2c_master_stop(cmd));
    ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 1/portTICK_PERIOD_MS));
    i2c_cmd_link_delete(cmd);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM