SI1145 always read the same value

iv6455434
Posts: 2
Joined: Mon Sep 02, 2024 4:21 pm

SI1145 always read the same value

Postby iv6455434 » Mon Sep 02, 2024 4:37 pm

Hello!
I am trying to read the values of UV, VIS and IR from the SI1145 (I2C device), but I always get the same results. The config values have been taken from the SI1145 datasheet. I think that could be the problem and I am not understanding well the configuration.

I am coding on Visual Studio with ESP-IDF v.5.3.0

Any suggestions to solve the problem?? Thank you so much.

I attach an image with the results:
si1145.png
si1145.png (12.29 KiB) Viewed 1524 times
And here is my code:

Code: Select all

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/i2c.h"

#define SI1145_ADDR                 0x60        

#define SI1145_REG_PART_ID          0x00
#define SI1145_REG_HW_KEY           0x07
#define SI1145_REG_MEAS_RATE0       0x08
#define SI1145_REG_MEAS_RATE1       0x09
#define SI1145_REG_PARAM_WR         0x17
#define SI1145_REG_COMMAND          0x18
#define SI1145_REG_UCOEF0           0x13
#define SI1145_REG_UCOEF1           0x14
#define SI1145_REG_UCOEF2           0x15
#define SI1145_REG_UCOEF3           0x16
#define SI1145_REG_PARAM_READ       0x2E
#define SI1145_REG_RESPONSE         0x20
#define SI1145_REG_UV_INDEX         0x2C
#define SI1145_REG_VISIBLE          0x22
#define SI1145_REG_IR               0x24

#define PARAM_CHLIST                0x01
#define EN_UV                       0x80
#define EN_AUX                      0x40
#define EN_ALS_IR                   0x20
#define EN_ALS_VIS                  0x10

#define I2C_MASTER_SCL_IO           22
#define I2C_MASTER_SDA_IO           21
#define I2C_MASTER_NUM              I2C_NUM_0
#define I2C_MASTER_FREQ_HZ          100000
#define I2C_MASTER_TX_BUF_DISABLE   0
#define I2C_MASTER_RX_BUF_DISABLE   0
#define I2C_MASTER_TIMEOUT_MS       1000

static const char *TAG = "SI1145_example";

esp_err_t i2c_master_init(void)
{
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
    };
    esp_err_t err = i2c_param_config(I2C_MASTER_NUM, &conf);
    if (err != ESP_OK) {
        return err;
    }
    return i2c_driver_install(I2C_MASTER_NUM, conf.mode,
                              I2C_MASTER_RX_BUF_DISABLE,
                              I2C_MASTER_TX_BUF_DISABLE, 0);
}

void si1145_read_register(uint8_t reg, uint16_t *data)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (SI1145_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, reg, true);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (SI1145_ADDR << 1) | I2C_MASTER_READ, true);
    i2c_master_read(cmd, data, sizeof(data), I2C_MASTER_LAST_NACK);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    vTaskDelay(pdMS_TO_TICKS(100));
}

void si1145_write_register(uint8_t reg, uint8_t value)
{
    uint8_t data[2] = {reg, value};

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (SI1145_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write(cmd, data, sizeof(data), true);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);

    vTaskDelay(pdMS_TO_TICKS(100));
}

void si1145_write_command(uint8_t command)
{
    si1145_write_register(SI1145_REG_COMMAND, command);
}

void si1145_configure(void)
{
    si1145_write_command(0x01);  // Send command RESET
    vTaskDelay(pdMS_TO_TICKS(10));  // Wait for reset

    // Write 0x17 in HW_KEY register
    si1145_write_register(SI1145_REG_HW_KEY, 0x17);
    vTaskDelay(pdMS_TO_TICKS(100));

    // Config CHLIST to enable UV, VIS e IR
    si1145_write_register(SI1145_REG_PARAM_WR, EN_UV | EN_ALS_IR | EN_ALS_VIS);
    vTaskDelay(pdMS_TO_TICKS(100));
    si1145_write_command(PARAM_CHLIST | 0xA0);  // Update CHLIST
    vTaskDelay(pdMS_TO_TICKS(100));

    // Config UCOEF for UV
    si1145_write_register(SI1145_REG_UCOEF0, 0x7B);
    vTaskDelay(pdMS_TO_TICKS(100));
    si1145_write_register(SI1145_REG_UCOEF1, 0x6B);
    vTaskDelay(pdMS_TO_TICKS(100));
    si1145_write_register(SI1145_REG_UCOEF2, 0x01);
    vTaskDelay(pdMS_TO_TICKS(100));
    si1145_write_register(SI1145_REG_UCOEF3, 0x00);
    vTaskDelay(pdMS_TO_TICKS(100));

    // Config MEAS_RATE
    si1145_write_register(SI1145_REG_MEAS_RATE0, 0xFF);
    vTaskDelay(pdMS_TO_TICKS(100));
    si1145_write_register(SI1145_REG_MEAS_RATE1, 0x00);
    vTaskDelay(pdMS_TO_TICKS(100));

    // Iniciar las mediciones automáticas
    si1145_write_command(0x08);  // ALS_FORCE
    vTaskDelay(pdMS_TO_TICKS(100));

    ESP_LOGI(TAG, "Config Si1145 complete");
}

void app_main(void)
{
    i2c_master_init();
    vTaskDelay(pdMS_TO_TICKS(100));

    si1145_configure();
    vTaskDelay(pdMS_TO_TICKS(100));

    while (1) 
    {
        uint16_t uv_index, visible, ir;

        // Read UV, VIS and IR
        si1145_read_register(SI1145_REG_UV_INDEX, &uv_index);
        ESP_LOGI(TAG, "UV Index: %u", uv_index);
        vTaskDelay(pdMS_TO_TICKS(1000));

        si1145_read_register(SI1145_REG_VISIBLE, &visible);
        ESP_LOGI(TAG, "Visible Light: %u", visible);
        vTaskDelay(pdMS_TO_TICKS(1000));

        si1145_read_register(SI1145_REG_IR, &ir);
        ESP_LOGI(TAG, "IR Light: %u", ir);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

MicroController
Posts: 1735
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: SI1145 always read the same value

Postby MicroController » Tue Sep 03, 2024 5:07 am

In si1145_read_register(),

Code: Select all

i2c_master_read(cmd, data, sizeof(data), ...)
should be

Code: Select all

i2c_master_read(cmd, data, sizeof(*data), ...)

iv6455434
Posts: 2
Joined: Mon Sep 02, 2024 4:21 pm

Re: SI1145 always read the same value

Postby iv6455434 » Tue Sep 03, 2024 4:10 pm

MicroController wrote:
Tue Sep 03, 2024 5:07 am
In si1145_read_register(),

Code: Select all

i2c_master_read(cmd, data, sizeof(data), ...)
should be

Code: Select all

i2c_master_read(cmd, data, sizeof(*data), ...)
Thank you¡¡ I didn't notice about it. Now, I read correctly the register but the values that I get are wrong. For example, the UV index I got was 18 (much higher than expected) without any direct light. I am trying different configurations but I am getting the same results.

MicroController
Posts: 1735
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: SI1145 always read the same value

Postby MicroController » Wed Sep 04, 2024 10:32 am

iv6455434 wrote:
Tue Sep 03, 2024 4:10 pm
For example, the UV index I got was 18 (much higher than expected) without any direct light.
Did you scale the read value correctly?
... AUX_DATA will contain a 16-bit value representing 100 times the sunlight UV Index. Host software must divide the results from AUX_DATA by 100.

Who is online

Users browsing this forum: No registered users and 128 guests