Skip to content

Instantly share code, notes, and snippets.

@leyyce
Last active November 21, 2023 17:11
Show Gist options
  • Save leyyce/cd0e2fbc5d8f219772bb5a8b859abef5 to your computer and use it in GitHub Desktop.
Save leyyce/cd0e2fbc5d8f219772bb5a8b859abef5 to your computer and use it in GitHub Desktop.
IoT_Ubung3
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c.h"
#include "sdkconfig.h"
#include <math.h>
#define I2C_MASTER_PORT I2C_NUM_0
#define I2C_MASTER_SDA_IO 21
#define I2C_MASTER_SCL_IO 22
#define I2C_MASTER_FREQ_HZ 400000
void i2c_init() {
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ
};
i2c_param_config(I2C_MASTER_PORT, &conf);
i2c_driver_install(I2C_MASTER_PORT, conf.mode, 0, 0, 0);
}
uint8_t i2c_register_read(i2c_port_t port_num, uint8_t dev_addr, uint8_t reg_addr) {
uint8_t data;
i2c_cmd_handle_t cmd;
esp_err_t ret;
reg_addr = (0b1000 << 4) | reg_addr;
uint8_t dev_addr_w = (dev_addr << 1) | I2C_MASTER_WRITE;
uint8_t dev_addr_r = (dev_addr << 1) | I2C_MASTER_READ;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev_addr_w, 1);
i2c_master_write_byte(cmd, reg_addr, 1);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev_addr_r, 1);
i2c_master_read_byte(cmd, &data, I2C_MASTER_NACK);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(port_num, cmd, portMAX_DELAY);
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
puts("Single byte read failed!");
exit(EXIT_FAILURE);
}
return data;
}
esp_err_t i2c_register_write(i2c_port_t port_num, uint8_t dev_addr, uint8_t reg_addr, uint8_t data) {
i2c_cmd_handle_t cmd;
esp_err_t ret;
uint8_t dev_addr_w = (dev_addr << 1) | I2C_MASTER_WRITE;
reg_addr = (0b1000 << 4) | reg_addr;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev_addr_w, 1);
i2c_master_write_byte(cmd, reg_addr, 1);
i2c_master_write_byte(cmd, data, 1);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(port_num, cmd, portMAX_DELAY);
i2c_cmd_link_delete(cmd);
return ret;
}
esp_err_t i2c_multi_register_read(i2c_port_t port_num, uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, size_t size) {
i2c_cmd_handle_t cmd;
esp_err_t ret;
reg_addr = (0b1000 << 4) | reg_addr;
uint8_t dev_addr_w = (dev_addr << 1) | I2C_MASTER_WRITE;
uint8_t dev_addr_r = (dev_addr << 1) | I2C_MASTER_READ;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev_addr_w, 1);
i2c_master_write_byte(cmd, reg_addr, 1);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev_addr_r, 1);
i2c_master_read(cmd, data, size, I2C_MASTER_ACK);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(port_num, cmd, portMAX_DELAY);
i2c_cmd_link_delete(cmd);
return ret;
}
void lux_sensor_init() {
i2c_register_write(I2C_MASTER_PORT, 0x29, 0x0, 0x03);
i2c_register_write(I2C_MASTER_PORT, 0x29, 0x1, 0b10010);
}
uint8_t lux_read_sensor_id() {
return i2c_register_read(I2C_MASTER_PORT, 0x29, 0xA);
}
uint8_t lux_read_ctrl_reg() {
return i2c_register_read(I2C_MASTER_PORT, 0x29, 0x0);
}
float lux_read_sensor_value() {
uint8_t ch0[2];
uint8_t ch1[2];
float CH0;
float CH1;
float div;
float lux = 0;
i2c_multi_register_read(I2C_MASTER_PORT, 0x29, 0xC, ch0, 2);
i2c_multi_register_read(I2C_MASTER_PORT, 0x29, 0xE, ch1, 2);
CH0 = (float) ((ch0[1] << 8) | ch0[0]);
CH1 = (float) ((ch1[1] << 8) | ch1[0]);
div = CH1 / CH0;
printf("CH0: %d, CH1: %d; DIV: %f\n", ch0[1] << 8 | ch0[0], ch1[1] << 8 | ch1[0], div);
if (0 < div && div <= 0.5) {
lux = (float) (0.0304 * CH0 - 0.062 * CH0 * pow(div, 1.4));
} else if (0.5 < div && div <= 0.61) {
lux = (float) (0.0224 * CH0 - 0.031 * CH1);
} else if (0.61 < div && div <= 0.8) {
lux = (float) (0.0128 * CH0 - 0.0153 * CH1);
} else if (0.8 < div && div <= 1.3) {
lux = (float) (0.00146 * CH0 - 0.00112 * CH1);
} else if (div > 1.3) {
lux = 0;
}
return lux;
}
_Noreturn void app_main() {
i2c_init();
lux_sensor_init();
puts("Init success!");
int delay_ticks = pdMS_TO_TICKS(400);
vTaskDelay(delay_ticks);
uint8_t id = lux_read_sensor_id();
uint8_t ctrl = lux_read_ctrl_reg();
printf("Sensor id: 0x%x, Control Register: 0x%x\n", id, ctrl & 0b11);
while (true) {
double ll = lux_read_sensor_value();
printf("Light level: %f lux\n", ll);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment