Init
This commit is contained in:
20
main/CMakeLists.txt
Normal file
20
main/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
idf_component_register(SRCS
|
||||
"hw/i2cbrn.c"
|
||||
"hw/i2cbrn.h"
|
||||
"components/util.c"
|
||||
"components/util.h"
|
||||
"hw/bme680b.c"
|
||||
"hw/bme680b.h"
|
||||
"hw/ccs811.c"
|
||||
"hw/ccs811.h"
|
||||
"hw/ina260.c"
|
||||
"hw/ina260.h"
|
||||
"hw/mcp23018.c"
|
||||
"hw/mcp23018.h"
|
||||
"hw/mpu9250.c"
|
||||
"hw/mpu9250.h"
|
||||
"components/sensors.c"
|
||||
"components/sensors.h"
|
||||
"main.c"
|
||||
|
||||
INCLUDE_DIRS ".")
|
88
main/components/sensors.c
Normal file
88
main/components/sensors.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "sensors.h"
|
||||
|
||||
#define BLINK_GPIO 2
|
||||
|
||||
static uint8_t s_led_state = 0;
|
||||
|
||||
static void configure_led(void)
|
||||
{
|
||||
gpio_reset_pin(BLINK_GPIO);
|
||||
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
|
||||
}
|
||||
|
||||
void i2c_sensors_task(void *pvParameters)
|
||||
{
|
||||
// initialize the xLastWakeTime variable with the current time.
|
||||
TickType_t last_wake_time = xTaskGetTickCount();
|
||||
const TickType_t I2C0_TASK_SAMPLING_RATE = 5;
|
||||
//
|
||||
// initialize i2c device configuration
|
||||
|
||||
bme680b_init();
|
||||
mpu9250_init();
|
||||
mcp23018_init();
|
||||
ina260_init();
|
||||
ccs811_init();
|
||||
|
||||
configure_led();
|
||||
|
||||
int16_t accel[3], gyro[3], temp;
|
||||
float accel_f[3], gyro_f[3], temp_f;
|
||||
uint16_t eCO2;
|
||||
uint16_t tvoc;
|
||||
uint32_t volts;
|
||||
uint32_t current;
|
||||
uint32_t power;
|
||||
|
||||
// task loop entry point
|
||||
for (;;)
|
||||
{
|
||||
//
|
||||
// handle sensor
|
||||
|
||||
bme680_data_t data;
|
||||
esp_err_t result = bme680_get_data(BME680_DEV_HANDLE, &data);
|
||||
if (result != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG_BME, "bme680 device read failed (%s)", esp_err_to_name(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
data.barometric_pressure = data.barometric_pressure / 100;
|
||||
// ESP_LOGI(TAG, "dewpoint temperature:%.2f °C", data.dewpoint_temperature);
|
||||
ESP_LOGI(TAG_BME, "air temperature: %.2f °C", data.air_temperature);
|
||||
ESP_LOGI(TAG_BME, "relative humidity: %.2f %%", data.relative_humidity);
|
||||
ESP_LOGI(TAG_BME, "barometric pressure: %.2f hPa", data.barometric_pressure);
|
||||
// ESP_LOGI(TAG, "gas resistance: %.2f kOhms", data.gas_resistance / 1000);
|
||||
// ESP_LOGI(TAG, "iaq score: %u (%s)", data.iaq_score, bme680_air_quality_to_string(data.iaq_score));
|
||||
}
|
||||
|
||||
ccs811_get_data(&eCO2, &tvoc);
|
||||
ESP_LOGI(TAG_CCS, "eCO₂: %d ppm, TVOC: %d ppb", eCO2, tvoc);
|
||||
|
||||
if (mpu9250_read_sensor_data(MPU9250_DEV_HANDLE, accel, gyro, &temp) == ESP_OK)
|
||||
{
|
||||
mpu9250_convert_data(accel, gyro, temp, accel_f, gyro_f, &temp_f);
|
||||
|
||||
ESP_LOGI(TAG_MPU, "Accel: X=%.2f g, Y=%.2f g, Z=%.2f g", accel_f[0], accel_f[1], accel_f[2]);
|
||||
ESP_LOGI(TAG_MPU, "Gyro: X=%.2f°/s, Y=%.2f°/s, Z=%.2f°/s", gyro_f[0], gyro_f[1], gyro_f[2]);
|
||||
ESP_LOGI(TAG_MPU, "Temperature: %.2f °C", temp_f);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_MPU, "Failed to read sensor data");
|
||||
}
|
||||
|
||||
ina260_readParams(&volts, ¤t, &power);
|
||||
ina260_printParams(volts, current, power);
|
||||
|
||||
gpio_set_level(BLINK_GPIO, s_led_state);
|
||||
/* Toggle the LED state */
|
||||
s_led_state = !s_led_state;
|
||||
vTaskDelaySecUntil(&last_wake_time, I2C0_TASK_SAMPLING_RATE);
|
||||
}
|
||||
//
|
||||
// free resources
|
||||
bme680_delete(BME680_DEV_HANDLE);
|
||||
vTaskDelete(NULL);
|
||||
}
|
23
main/components/sensors.h
Normal file
23
main/components/sensors.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef SENSORS_COMPONENT
|
||||
#define SENSORS_COMPONENT
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "util.h"
|
||||
#include "driver/gpio.h"
|
||||
#include <bme680.h>
|
||||
#include "esp_mac.h"
|
||||
|
||||
#include "../hw/bme680b.h"
|
||||
#include "../hw/ccs811.h"
|
||||
#include "../hw/i2cbrn.h"
|
||||
|
||||
#include "../hw/mcp23018.h"
|
||||
#include "../hw/ina260.h"
|
||||
#include "../hw/mpu9250.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
|
||||
void i2c_sensors_task(void *pvParameters);
|
||||
|
||||
#endif
|
7
main/components/util.c
Normal file
7
main/components/util.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "util.h"
|
||||
|
||||
void vTaskDelaySecUntil(TickType_t *previousWakeTime, const unsigned int sec)
|
||||
{
|
||||
const TickType_t xFrequency = ((sec * 100) / portTICK_PERIOD_MS);
|
||||
vTaskDelayUntil(previousWakeTime, xFrequency);
|
||||
}
|
9
main/components/util.h
Normal file
9
main/components/util.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef UTIL_COMPONENT
|
||||
#define UTIL_COMPONENT
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
void vTaskDelaySecUntil(TickType_t *previousWakeTime, const unsigned int sec);
|
||||
|
||||
#endif
|
51
main/hw/bme680b.c
Normal file
51
main/hw/bme680b.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "bme680.h"
|
||||
#include "bme680b.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2cbrn.h"
|
||||
|
||||
bme680_config_t BME680_DEV_CFG = I2C_BME680_CONFIG_DEFAULT;
|
||||
bme680_handle_t BME680_DEV_HANDLE;
|
||||
|
||||
void bme680_print_registers(bme680_handle_t handle)
|
||||
{
|
||||
/* configuration registers */
|
||||
bme680_control_measurement_register_t ctrl_meas_reg;
|
||||
bme680_control_humidity_register_t ctrl_humi_reg;
|
||||
bme680_config_register_t config_reg;
|
||||
bme680_control_gas0_register_t ctrl_gas0_reg;
|
||||
bme680_control_gas1_register_t ctrl_gas1_reg;
|
||||
|
||||
/* attempt to read control humidity register */
|
||||
bme680_get_control_humidity_register(handle, &ctrl_humi_reg);
|
||||
|
||||
/* attempt to read control measurement register */
|
||||
bme680_get_control_measurement_register(handle, &ctrl_meas_reg);
|
||||
|
||||
/* attempt to read configuration register */
|
||||
bme680_get_configuration_register(handle, &config_reg);
|
||||
|
||||
/* attempt to read control gas 0 register */
|
||||
bme680_get_control_gas0_register(handle, &ctrl_gas0_reg);
|
||||
|
||||
/* attempt to read control gas 1 register */
|
||||
bme680_get_control_gas1_register(handle, &ctrl_gas1_reg);
|
||||
|
||||
ESP_LOGI(TAG_BME, "Variant Id (0x%02x): %s", handle->variant_id, uint8_to_binary(handle->variant_id));
|
||||
ESP_LOGI(TAG_BME, "Configuration (0x%02x): %s", config_reg.reg, uint8_to_binary(config_reg.reg));
|
||||
ESP_LOGI(TAG_BME, "Control Measurement (0x%02x): %s", ctrl_meas_reg.reg, uint8_to_binary(ctrl_meas_reg.reg));
|
||||
ESP_LOGI(TAG_BME, "Control Humidity (0x%02x): %s", ctrl_humi_reg.reg, uint8_to_binary(ctrl_humi_reg.reg));
|
||||
ESP_LOGI(TAG_BME, "Control Gas 0 (0x%02x): %s", ctrl_gas0_reg.reg, uint8_to_binary(ctrl_gas0_reg.reg));
|
||||
ESP_LOGI(TAG_BME, "Control Gas 1 (0x%02x): %s", ctrl_gas1_reg.reg, uint8_to_binary(ctrl_gas1_reg.reg));
|
||||
}
|
||||
|
||||
void bme680b_init() {
|
||||
// init device
|
||||
bme680_init(i2c0_bus_hdl, &BME680_DEV_CFG, &BME680_DEV_HANDLE);
|
||||
if (BME680_DEV_HANDLE == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG_BME, "bme680 handle init failed");
|
||||
assert(BME680_DEV_HANDLE);
|
||||
}
|
||||
|
||||
bme680_print_registers(BME680_DEV_HANDLE);
|
||||
}
|
13
main/hw/bme680b.h
Normal file
13
main/hw/bme680b.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef BME680_COMPONENT
|
||||
#define BME680_COMPONENT
|
||||
|
||||
#include <bme680.h>
|
||||
#include "i2cbrn.h"
|
||||
#define TAG_BME "BME680"
|
||||
extern bme680_config_t BME680_DEV_CFG;
|
||||
extern bme680_handle_t BME680_DEV_HANDLE;
|
||||
|
||||
void bme680_print_registers(bme680_handle_t handle);
|
||||
void bme680b_init();
|
||||
|
||||
#endif
|
46
main/hw/ccs811.c
Normal file
46
main/hw/ccs811.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "ccs811.h"
|
||||
|
||||
#define CONFIG_FREERTOS_HZ 100
|
||||
|
||||
i2c_device_config_t CCS811_DEV_CFG = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x5A,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t CCS811_DEV_HANDLE;
|
||||
|
||||
void ccs811_init()
|
||||
{
|
||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c0_bus_hdl, &CCS811_DEV_CFG, &CCS811_DEV_HANDLE));
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_WAKE, 0);
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_POWER, 1);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
uint8_t reset_seq[4] = {0x11, 0xE5, 0x72, 0x8A};
|
||||
i2c_write_register(CCS811_DEV_HANDLE, 0xFF, reset_seq, sizeof(reset_seq)); //Reset
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
uint8_t status;
|
||||
uint16_t version;
|
||||
i2c_read_register_8(CCS811_DEV_HANDLE, 0x00, &status);
|
||||
i2c_read_register_16(CCS811_DEV_HANDLE, 0x24, &version);
|
||||
ESP_LOGW(TAG_CCS, "CCS811 status: %d, version: %d", status, version);
|
||||
i2c_write_register(CCS811_DEV_HANDLE, 0xF4, NULL, 0); //start
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
i2c_write_register_8(CCS811_DEV_HANDLE, 0x10, 0x0001); // MODE 1 interrupts vypnuté
|
||||
i2c_read_register_8(CCS811_DEV_HANDLE, 0x00, &status);
|
||||
i2c_read_register_16(CCS811_DEV_HANDLE, 0x24, &version);
|
||||
ESP_LOGW(TAG_CCS, "CCS811 status: %d, version: %d", status, version);
|
||||
}
|
||||
|
||||
esp_err_t ccs811_get_data(uint16_t * eCO2, uint16_t * tvoc)
|
||||
{
|
||||
uint8_t ccsResult[8];
|
||||
esp_err_t ret = i2c_read_register(CCS811_DEV_HANDLE, 0x05, ccsResult, 8);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
*eCO2 = (ccsResult[0] << 8) | ccsResult[1];
|
||||
*tvoc = (ccsResult[2] << 8) | ccsResult[3];
|
||||
ESP_LOGI(TAG_CCS, "CCS Status: %d, Error %d", ccsResult[4], ccsResult[5]);
|
||||
}
|
||||
return ret;
|
||||
}
|
15
main/hw/ccs811.h
Normal file
15
main/hw/ccs811.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef CCS811_COMPONENT
|
||||
#define CCS811_COMPONENT
|
||||
#include "i2cbrn.h"
|
||||
#include "mcp23018.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#define TAG_CCS "CCS811"
|
||||
extern i2c_device_config_t CCS811_DEV_CFG;
|
||||
|
||||
extern i2c_master_dev_handle_t CCS811_DEV_HANDLE;
|
||||
|
||||
void ccs811_init();
|
||||
esp_err_t ccs811_get_data(uint16_t * eCO2, uint16_t * tvoc);
|
||||
|
||||
#endif
|
204
main/hw/i2cbrn.c
Normal file
204
main/hw/i2cbrn.c
Normal file
@@ -0,0 +1,204 @@
|
||||
#include "i2cbrn.h"
|
||||
|
||||
i2c_master_bus_config_t i2c0_bus_cfg = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = I2C_NUM_0,
|
||||
.scl_io_num = GPIO_NUM_9,
|
||||
.sda_io_num = GPIO_NUM_8,
|
||||
.glitch_ignore_cnt = 7,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t i2c0_bus_hdl;
|
||||
|
||||
esp_err_t i2c_master_bus_detect_devices(i2c_master_bus_handle_t handle)
|
||||
{
|
||||
const uint16_t probe_timeout_ms = 50; // timeout in milliseconds
|
||||
uint8_t address;
|
||||
|
||||
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
||||
|
||||
for (int i = 0; i < 128; i += 16)
|
||||
{
|
||||
printf("%02x: ", i);
|
||||
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
fflush(stdout);
|
||||
|
||||
address = i + j;
|
||||
|
||||
esp_err_t ret = i2c_master_probe(handle, address, probe_timeout_ms);
|
||||
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
printf("%02x ", address);
|
||||
}
|
||||
else if (ret == ESP_ERR_TIMEOUT)
|
||||
{
|
||||
printf("UU ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("-- ");
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes data to a specific register of an I2C device.
|
||||
*
|
||||
* @param dev_handle I2C device handle
|
||||
* @param reg_addr Register address to write to
|
||||
* @param data Pointer to the data buffer to write
|
||||
* @param len Number of bytes to write
|
||||
* @return esp_err_t ESP_OK on success, or an error code
|
||||
*/
|
||||
esp_err_t i2c_write_register(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t *data, size_t len)
|
||||
{
|
||||
if (len == 0) {
|
||||
// If no data, send just the register address
|
||||
return i2c_master_transmit(dev_handle, ®_addr, 1, I2C_TIMEOUT_MS_VALUE);
|
||||
}
|
||||
|
||||
uint8_t buffer[len + 1];
|
||||
buffer[0] = reg_addr;
|
||||
memcpy(&buffer[1], data, len);
|
||||
|
||||
esp_err_t ret = i2c_master_transmit(dev_handle, buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGV(TAG_I2C, "Write to register 0x%02X successful", reg_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_I2C, "Write to register 0x%02X failed: %s", reg_addr, esp_err_to_name(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads data from a specific register of an I2C device.
|
||||
*
|
||||
* @param dev_handle I2C device handle
|
||||
* @param reg_addr Register address to read from
|
||||
* @param data Pointer to a buffer to store read data
|
||||
* @param len Number of bytes to read
|
||||
* @return esp_err_t ESP_OK on success, or an error code
|
||||
*/
|
||||
esp_err_t i2c_read_register(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t *data, size_t len)
|
||||
{
|
||||
esp_err_t ret = i2c_master_transmit_receive(dev_handle, ®_addr, 1, data, len, I2C_TIMEOUT_MS_VALUE);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGV(TAG_I2C, "Read from register 0x%02X successful", reg_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_I2C, "Read from register 0x%02X failed: %s", reg_addr, esp_err_to_name(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a 16-bit value to a specific register of an I2C device.
|
||||
*
|
||||
* @param dev_handle I2C device handle
|
||||
* @param reg_addr Register address to write to
|
||||
* @param value 16-bit value to write
|
||||
* @return esp_err_t ESP_OK on success, or an error code
|
||||
*/
|
||||
esp_err_t i2c_write_register_16(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint16_t value)
|
||||
{
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = reg_addr; // Register address
|
||||
buffer[1] = (value >> 8); // High byte
|
||||
buffer[2] = (value & 0xFF); // Low byte
|
||||
|
||||
esp_err_t ret = i2c_master_transmit(dev_handle, buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGV(TAG_I2C, "Write to register 0x%02X successful (Value: 0x%04X)", reg_addr, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_I2C, "Write to register 0x%02X failed: %s", reg_addr, esp_err_to_name(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a 16-bit value from a specific register of an I2C device.
|
||||
*
|
||||
* @param dev_handle I2C device handle
|
||||
* @param reg_addr Register address to read from
|
||||
* @param value Pointer to store the read 16-bit value
|
||||
* @return esp_err_t ESP_OK on success, or an error code
|
||||
*/
|
||||
esp_err_t i2c_read_register_16(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint16_t *value)
|
||||
{
|
||||
uint8_t buffer[2];
|
||||
|
||||
esp_err_t ret = i2c_master_transmit_receive(dev_handle, ®_addr, 1, buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
*value = (buffer[0] << 8) | buffer[1]; // Combine MSB and LSB
|
||||
ESP_LOGV(TAG_I2C, "Read from register 0x%02X successful (Value: 0x%04X)", reg_addr, *value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_I2C, "Read from register 0x%02X failed: %s", reg_addr, esp_err_to_name(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes an 8-bit value to a specific register of an I2C device.
|
||||
*
|
||||
* @param dev_handle I2C device handle
|
||||
* @param reg_addr Register address to write to
|
||||
* @param value 8-bit value to write
|
||||
* @return esp_err_t ESP_OK on success, or an error code
|
||||
*/
|
||||
esp_err_t i2c_write_register_8(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t value)
|
||||
{
|
||||
uint8_t buffer[2];
|
||||
buffer[0] = reg_addr; // Register address
|
||||
buffer[1] = value; // 8-bit value
|
||||
|
||||
esp_err_t ret = i2c_master_transmit(dev_handle, buffer, sizeof(buffer), I2C_TIMEOUT_MS_VALUE);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGV(TAG_I2C, "Write to register 0x%02X successful (Value: 0x%02X)", reg_addr, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_I2C, "Write to register 0x%02X failed: %s", reg_addr, esp_err_to_name(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads an 8-bit value from a specific register of an I2C device.
|
||||
*
|
||||
* @param dev_handle I2C device handle
|
||||
* @param reg_addr Register address to read from
|
||||
* @param value Pointer to store the read 8-bit value
|
||||
* @return esp_err_t ESP_OK on success, or an error code
|
||||
*/
|
||||
esp_err_t i2c_read_register_8(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t *value)
|
||||
{
|
||||
esp_err_t ret = i2c_master_transmit_receive(dev_handle, ®_addr, 1, value, 1, I2C_TIMEOUT_MS_VALUE);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGV(TAG_I2C, "Read from register 0x%02X successful (Value: 0x%02X)", reg_addr, *value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG_I2C, "Read from register 0x%02X failed: %s", reg_addr, esp_err_to_name(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
20
main/hw/i2cbrn.h
Normal file
20
main/hw/i2cbrn.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef I2CBRN_COMPONENT
|
||||
#define I2CBRN_COMPONENT
|
||||
#define I2C_TIMEOUT_MS_VALUE 20
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#define TAG_I2C "cani2c"
|
||||
|
||||
#include "driver/i2c_master.h"
|
||||
extern i2c_master_bus_config_t i2c0_bus_cfg;
|
||||
extern i2c_master_bus_handle_t i2c0_bus_hdl;
|
||||
|
||||
esp_err_t i2c_master_bus_detect_devices(i2c_master_bus_handle_t handle);
|
||||
esp_err_t i2c_write_register(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t *data, size_t len);
|
||||
esp_err_t i2c_read_register(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t *data, size_t len);
|
||||
esp_err_t i2c_write_register_16(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint16_t value);
|
||||
esp_err_t i2c_read_register_16(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint16_t *value);
|
||||
esp_err_t i2c_write_register_8(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t value);
|
||||
esp_err_t i2c_read_register_8(i2c_master_dev_handle_t dev_handle, uint8_t reg_addr, uint8_t *value);
|
||||
#endif
|
53
main/hw/ina260.c
Normal file
53
main/hw/ina260.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "ina260.h"
|
||||
|
||||
i2c_device_config_t INA260_DEV_CFG = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x40,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t INA260_DEV_HANDLE;
|
||||
|
||||
void ina260_init()
|
||||
{
|
||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c0_bus_hdl, &INA260_DEV_CFG, &INA260_DEV_HANDLE));
|
||||
i2c_write_register_16(INA260_DEV_HANDLE, 0x00, 0x0FFF); // set ina max averaging and max time
|
||||
}
|
||||
|
||||
void ina260_readParams(uint32_t *volt, uint32_t *cur, uint32_t *pow)
|
||||
{
|
||||
for (uint8_t reg_addr = 1; reg_addr <= 3; reg_addr++)
|
||||
{
|
||||
uint8_t reg_value[2] = {0}; // Buffer for storing register data
|
||||
|
||||
// Perform the register read
|
||||
ESP_ERROR_CHECK(i2c_master_transmit_receive(INA260_DEV_HANDLE, ®_addr, 1, reg_value, sizeof(reg_value), I2C_TIMEOUT_MS_VALUE));
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 1:
|
||||
*cur = *((uint16_t *)reg_value);
|
||||
|
||||
break;
|
||||
case 2:
|
||||
*volt = *((uint16_t *)reg_value);
|
||||
|
||||
break;
|
||||
case 3:
|
||||
*pow = *((uint16_t *)reg_value);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ina260_printParams(uint32_t volt, uint32_t cur, uint32_t pow)
|
||||
{
|
||||
cur *= 125;
|
||||
ESP_LOGI(TAG_INA, "Current: %ld.%ld mA", cur / 10000, cur % 10000);
|
||||
cur *= 125;
|
||||
ESP_LOGI(TAG_INA, "Voltage: %ld.%ld V", volt / 10000, volt % 10000);
|
||||
|
||||
ESP_LOGI(TAG_INA, "Power: %ld.%ld W", pow / 10000, pow % 10000);
|
||||
}
|
15
main/hw/ina260.h
Normal file
15
main/hw/ina260.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef INA260_COMPONENT
|
||||
#define INA260_COMPONENT
|
||||
#include "i2cbrn.h"
|
||||
#define TAG_INA "INA260"
|
||||
extern i2c_device_config_t INA260_DEV_CFG;
|
||||
|
||||
extern i2c_master_dev_handle_t INA260_DEV_HANDLE;
|
||||
|
||||
|
||||
void ina260_init();
|
||||
void ina260_readParams(uint32_t *volt, uint32_t *cur, uint32_t *pow);
|
||||
void ina260_printParams(uint32_t volt, uint32_t cur, uint32_t pow);
|
||||
|
||||
|
||||
#endif
|
51
main/hw/mcp23018.c
Normal file
51
main/hw/mcp23018.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "mcp23018.h"
|
||||
// Local buffer for tracking GPIO state
|
||||
|
||||
i2c_device_config_t MCP23018_DEV_CFG = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x20,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t MCP23018_DEV_HANDLE;
|
||||
uint8_t gpioa_state = 0x00; // All LOW initially
|
||||
uint8_t gpiob_state = 0x00; // All LOW initially
|
||||
|
||||
void mcp23018_set_pin(i2c_master_dev_handle_t dev_handle, uint8_t pin, uint8_t value)
|
||||
{
|
||||
if (pin < 8)
|
||||
{
|
||||
// GPIOA (Pins 0-7)
|
||||
if (value)
|
||||
gpioa_state |= (1 << pin); // Set bit
|
||||
else
|
||||
gpioa_state &= ~(1 << pin); // Clear bit
|
||||
|
||||
// Write updated buffer to MCP23018
|
||||
i2c_write_register_8(dev_handle, MCP23018_GPIOA, gpioa_state);
|
||||
}
|
||||
else if (pin < 16)
|
||||
{
|
||||
// GPIOB (Pins 8-15)
|
||||
uint8_t pinB = pin - 8;
|
||||
if (value)
|
||||
gpiob_state |= (1 << pinB); // Set bit
|
||||
else
|
||||
gpiob_state &= ~(1 << pinB); // Clear bit
|
||||
|
||||
// Write updated buffer to MCP23018
|
||||
i2c_write_register_8(dev_handle, MCP23018_GPIOB, gpiob_state);
|
||||
}
|
||||
}
|
||||
|
||||
void mcp23018_init()
|
||||
{
|
||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c0_bus_hdl, &MCP23018_DEV_CFG, &MCP23018_DEV_HANDLE));
|
||||
i2c_write_register_8(MCP23018_DEV_HANDLE, MCP23018_IODIRA, gpioa_state);
|
||||
i2c_write_register_8(MCP23018_DEV_HANDLE, MCP23018_IODIRB, gpiob_state);
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CS_ADC_CO, 1);
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CS_ADC_NH3, 1);
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CS_ADC_NO2, 1);
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CS_ADC_UVC, 1);
|
||||
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_LORA_RST, 1);
|
||||
}
|
31
main/hw/mcp23018.h
Normal file
31
main/hw/mcp23018.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef MCP23018_COMPONENT
|
||||
#define MCP23018_COMPONENT
|
||||
#include "i2cbrn.h"
|
||||
#define TAG_MCP "MCP23018"
|
||||
#define MCP23018_IODIRA 0x00 // I/O Direction A
|
||||
#define MCP23018_IODIRB 0x01 // I/O Direction B
|
||||
#define MCP23018_GPIOA 0x12 // GPIO Output A
|
||||
#define MCP23018_GPIOB 0x13 // GPIO Output B
|
||||
|
||||
#define MCP_LORA_RST 4
|
||||
#define MCP_MICS_POWER 5
|
||||
#define MCP_CCS811_WAKE 6
|
||||
#define MCP_CCS811_POWER 7
|
||||
|
||||
#define MCP_CS_ADC_NH3 8
|
||||
#define MCP_CS_ADC_CO 9
|
||||
#define MCP_CS_ADC_NO2 10
|
||||
#define MCP_CS_ADC_UVC 11
|
||||
|
||||
|
||||
|
||||
extern i2c_device_config_t MCP23018_DEV_CFG;
|
||||
|
||||
extern i2c_master_dev_handle_t MCP23018_DEV_HANDLE;
|
||||
extern uint8_t gpioa_state;
|
||||
extern uint8_t gpiob_state;
|
||||
|
||||
void mcp23018_set_pin(i2c_master_dev_handle_t dev_handle, uint8_t pin, uint8_t value);
|
||||
void mcp23018_init();
|
||||
|
||||
#endif
|
46
main/hw/mpu9250.c
Normal file
46
main/hw/mpu9250.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "mpu9250.h"
|
||||
|
||||
i2c_device_config_t MPU9250_DEV_CFG = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x68,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t MPU9250_DEV_HANDLE;
|
||||
|
||||
esp_err_t mpu9250_read_sensor_data(i2c_master_dev_handle_t dev_handle, int16_t *accel, int16_t *gyro, int16_t *temp)
|
||||
{
|
||||
uint8_t buffer[14]; // 6 (Accel) + 2 (Temp) + 6 (Gyro)
|
||||
esp_err_t ret = i2c_read_register(dev_handle, 0x3B, buffer, 14);
|
||||
if (ret != ESP_OK)
|
||||
return ret;
|
||||
|
||||
// Convert raw data (Big-Endian)
|
||||
accel[0] = (buffer[0] << 8) | buffer[1]; // Accel X
|
||||
accel[1] = (buffer[2] << 8) | buffer[3]; // Accel Y
|
||||
accel[2] = (buffer[4] << 8) | buffer[5]; // Accel Z
|
||||
*temp = (buffer[6] << 8) | buffer[7]; // Temperature
|
||||
gyro[0] = (buffer[8] << 8) | buffer[9]; // Gyro X
|
||||
gyro[1] = (buffer[10] << 8) | buffer[11]; // Gyro Y
|
||||
gyro[2] = (buffer[12] << 8) | buffer[13]; // Gyro Z
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void mpu9250_convert_data(int16_t *accel, int16_t *gyro, int16_t temp, float *accel_out, float *gyro_out, float *temp_out)
|
||||
{
|
||||
accel_out[0] = accel[0] / 16384.0; // Accel X in g
|
||||
accel_out[1] = accel[1] / 16384.0; // Accel Y in g
|
||||
accel_out[2] = accel[2] / 16384.0; // Accel Z in g
|
||||
|
||||
gyro_out[0] = gyro[0] / 131.0; // Gyro X in deg/s
|
||||
gyro_out[1] = gyro[1] / 131.0; // Gyro Y in deg/s
|
||||
gyro_out[2] = gyro[2] / 131.0; // Gyro Z in deg/s
|
||||
|
||||
*temp_out = (temp / 333.87) + 21.0; // Temperature in °C
|
||||
}
|
||||
|
||||
void mpu9250_init() {
|
||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c0_bus_hdl, &MPU9250_DEV_CFG, &MPU9250_DEV_HANDLE));
|
||||
i2c_write_register_16(MPU9250_DEV_HANDLE, 0x6B, 0x0001); // zapni uz tu hovadinu
|
||||
}
|
15
main/hw/mpu9250.h
Normal file
15
main/hw/mpu9250.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef MPU9250_COMPONENT
|
||||
#define MPU9250_COMPONENT
|
||||
#include "i2cbrn.h"
|
||||
#define TAG_MPU "MPU9250"
|
||||
|
||||
extern i2c_device_config_t MPU9250_DEV_CFG;
|
||||
|
||||
extern i2c_master_dev_handle_t MPU9250_DEV_HANDLE;
|
||||
|
||||
|
||||
esp_err_t mpu9250_read_sensor_data(i2c_master_dev_handle_t dev_handle, int16_t *accel, int16_t *gyro, int16_t *temp);
|
||||
void mpu9250_convert_data(int16_t *accel, int16_t *gyro, int16_t temp, float *accel_out, float *gyro_out, float *temp_out);
|
||||
void mpu9250_init();
|
||||
|
||||
#endif
|
17
main/idf_component.yml
Normal file
17
main/idf_component.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
# # Put list of dependencies here
|
||||
# # For components maintained by Espressif:
|
||||
# component: "~1.0.0"
|
||||
# # For 3rd party components:
|
||||
# username/component: ">=1.0.0,<2.0.0"
|
||||
# username2/component2:
|
||||
# version: "~1.0.0"
|
||||
# # For transient dependencies `public` flag can be set.
|
||||
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||
# # All dependencies of `main` are public by default.
|
||||
# public: true
|
||||
k0i05/esp_bme680: ^1.2.5
|
57
main/main.c
Normal file
57
main/main.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Blink Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_mac.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "components/sensors.h"
|
||||
#include "components/util.h"
|
||||
#include "hw/bme680b.h"
|
||||
#include "hw/ccs811.h"
|
||||
#include "hw/i2cbrn.h"
|
||||
#include "hw/ina260.h"
|
||||
#include "hw/mcp23018.h"
|
||||
#include "hw/mpu9250.h"
|
||||
|
||||
#define TAG "cantest"
|
||||
|
||||
|
||||
#define CONFIG_FREERTOS_HZ 100
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
|
||||
/* instantiate i2c master bus 0 */
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c0_bus_cfg, &i2c0_bus_hdl));
|
||||
|
||||
/* scan i2c devices on i2c master bus 0 and print results */
|
||||
ESP_ERROR_CHECK(i2c_master_bus_detect_devices(i2c0_bus_hdl));
|
||||
|
||||
/* create task pinned to the app core */
|
||||
xTaskCreatePinnedToCore(
|
||||
i2c_sensors_task,
|
||||
"I2CTaskBME",
|
||||
8192,
|
||||
NULL,
|
||||
(tskIDLE_PRIORITY + 2),
|
||||
NULL,
|
||||
APP_CPU_NUM);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user