rm3100 status register not changing

brand17
Posts: 7
Joined: Wed Jun 01, 2022 6:16 pm

rm3100 status register not changing

Postby brand17 » Sun Dec 25, 2022 12:28 pm

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).

Code: Select all

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/uplo ... -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.

Code: Select all

    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");
2. According to the datasheet – I need to send “stop” when after sending 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.

Code: Select all

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);
}
Attachments
datasheet2.png
datasheet2.png (158.16 KiB) Viewed 1424 times
rm3100.png
rm3100.png (144.72 KiB) Viewed 1424 times
datasheet1.png
datasheet1.png (43.98 KiB) Viewed 1424 times

brand17
Posts: 7
Joined: Wed Jun 01, 2022 6:16 pm

Re: rm3100 status register not changing

Postby brand17 » Tue Dec 27, 2022 5:27 am

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:

Code: Select all

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);
}

Who is online

Users browsing this forum: Majestic-12 [Bot] and 86 guests