Last active
November 21, 2023 17:11
-
-
Save leyyce/cd0e2fbc5d8f219772bb5a8b859abef5 to your computer and use it in GitHub Desktop.
IoT_Ubung3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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