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