Skip to content

Commit

Permalink
create ccs811 sensor driver
Browse files Browse the repository at this point in the history
  • Loading branch information
yannherren committed Dec 24, 2024
1 parent d83e07b commit 4e3df59
Show file tree
Hide file tree
Showing 16 changed files with 308 additions and 76 deletions.
27 changes: 3 additions & 24 deletions components/bme280-sensor/bme280.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,6 @@
#define DEFAULT_TIMEOUT pdMS_TO_TICKS(1000)

esp_err_t bme280_init(void) {
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = SDA_PIN,
.scl_io_num = SCL_PIN,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,

.master = {
.clk_speed = 100000
}
};

ESP_ERROR_CHECK(
i2c_param_config(I2C_PORT, &i2c_config)
);

i2c_driver_install(I2C_PORT, I2C_MODE_MASTER, 0, 0, 0);

uint8_t chip_id = 0;
esp_err_t err = bme280_load_chip_id(&chip_id);
if (err != ESP_OK) {
Expand Down Expand Up @@ -79,12 +61,9 @@ static esp_err_t bme280_load_chip_id(uint8_t *chip_id) {
uint8_t reg_addr = 0xD0;
uint8_t bme_chip_id = 0;
i2c_master_write_to_device(I2C_PORT, BME_ADDRESS, &reg_addr, 1, DEFAULT_TIMEOUT);
esp_err_t err = i2c_master_read_from_device(I2C_PORT, BME_ADDRESS, &bme_chip_id, 1, DEFAULT_TIMEOUT);
i2c_master_read_from_device(I2C_PORT, BME_ADDRESS, &bme_chip_id, 1, DEFAULT_TIMEOUT);

if (bme_chip_id != BME_CHIP_ID) {
esp_err_to_name(err);
return err;
}
if (bme_chip_id != BME_CHIP_ID) return ESP_ERR_INVALID_RESPONSE;

*chip_id = bme_chip_id;

Expand All @@ -94,7 +73,7 @@ static esp_err_t bme280_load_chip_id(uint8_t *chip_id) {
static void bme280_read_raw_data(uint8_t *data, uint8_t start_register, uint8_t len) {
i2c_master_write_to_device(I2C_PORT, BME_ADDRESS, &start_register, 1, DEFAULT_TIMEOUT);
ESP_ERROR_CHECK(
i2c_master_read_from_device(I2C_PORT, BME_ADDRESS, data, len, pdMS_TO_TICKS(1000))
i2c_master_read_from_device(I2C_PORT, BME_ADDRESS, data, len, DEFAULT_TIMEOUT)
);
}

Expand Down
2 changes: 0 additions & 2 deletions components/bme280-sensor/include/bme280.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#define BMP280_H
#include <esp_err.h>

typedef struct bme_sensor bme_sensor_t;

esp_err_t bme280_init(void);
void bme280_configure(void);
void bme280_read_data(double *temperature, double *pressure, double *humidity);
Expand Down
4 changes: 4 additions & 0 deletions components/ccs811-sensor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(SRCS "ccs811.c"
INCLUDE_DIRS "include"
REQUIRES driver
)
124 changes: 124 additions & 0 deletions components/ccs811-sensor/ccs811.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//
// Created by yann on 12/17/24.
//

#include "ccs811.h"
#include "ccs811_private.h"

#include <esp_log.h>
#include <driver/i2c.h>

#define TAG "cs811"

#define SDA_PIN GPIO_NUM_16
#define SCL_PIN GPIO_NUM_17

#define I2C_PORT I2C_NUM_0
#define CS811_ADDRESS 0x5A
#define CS811_HW_ID 0x81
#define DEFAULT_TIMEOUT pdMS_TO_TICKS(1000)

#define ALG_RESULT_DATA_SIZE 8
#define MAX_READ_RETRIES 10

esp_err_t cs811_init(void) {
uint8_t hw_id = 0;
esp_err_t err = cs811_load_hw_id(&hw_id);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Couldn't initialize sensor!");
esp_err_to_name(err);
return err;
}
ESP_LOGI(TAG, "Initialized sensor successfully");

cs811_start_application();

return ESP_OK;
}

#define READ_DELAY_MS 500

void cs811_configure(void) {
cs811_init_meas_mode();
}

bool cs811_read_data(uint16_t *co2, uint16_t *tvoc) {
uint8_t retries = 0;
while (!cs811_new_alg_data_ready()) {
cs811_log_error();
vTaskDelay(pdMS_TO_TICKS(READ_DELAY_MS));
if (retries == MAX_READ_RETRIES - 1) return false;
retries++;
}

cs811_read_alg_result_data(co2, tvoc);

return true;
}

static bool cs811_new_alg_data_ready(void) {
uint8_t reg_addr = 0x00;
uint8_t status_data = 0;
i2c_master_write_to_device(I2C_PORT, CS811_ADDRESS, &reg_addr, 1, DEFAULT_TIMEOUT);
ESP_ERROR_CHECK(
i2c_master_read_from_device(I2C_PORT, CS811_ADDRESS, &status_data, 1, DEFAULT_TIMEOUT)
);

printf("Status: %x\n", status_data);

return (status_data >> 3) & 0x01;
}

static void cs811_read_alg_result_data(uint16_t *co2, uint16_t *tvoc) {
uint8_t reg_addr = 0x02;
uint8_t data[ALG_RESULT_DATA_SIZE] = {0};
i2c_master_write_to_device(I2C_PORT, CS811_ADDRESS, &reg_addr, 1, DEFAULT_TIMEOUT);
ESP_ERROR_CHECK(
i2c_master_read_from_device(I2C_PORT, CS811_ADDRESS, data, ALG_RESULT_DATA_SIZE, DEFAULT_TIMEOUT)
);
printf("%x\n", data[0]);
printf("%x\n", data[1]);
printf("%x\n", data[2]);
printf("%x\n", data[3]);
printf("%x\n", data[4]);
printf("%x\n", data[5]);
printf("%x\n", data[6]);
printf("%x\n", data[7]);
*co2 = (data[0] << 8) & data[1];
*tvoc = (data[2] << 8) & data[3];
}

static void cs811_start_application(void) {
uint8_t reg_addr = 0xF4;
i2c_master_write_to_device(I2C_PORT, CS811_ADDRESS, &reg_addr, 1, DEFAULT_TIMEOUT);
}

static void cs811_init_meas_mode(void) {
uint8_t meas_mode[2] = {0x01, 0x10};
i2c_master_write_to_device(I2C_PORT, CS811_ADDRESS, meas_mode, sizeof(meas_mode), DEFAULT_TIMEOUT);
}

static esp_err_t cs811_load_hw_id(uint8_t *hw_id) {
uint8_t reg_addr = 0x20;
uint8_t cs811_hw_id = 0;
i2c_master_write_to_device(I2C_PORT, CS811_ADDRESS, &reg_addr, 1, DEFAULT_TIMEOUT);
ESP_ERROR_CHECK(
i2c_master_read_from_device(I2C_PORT, CS811_ADDRESS, &cs811_hw_id, 1, DEFAULT_TIMEOUT)
);

if (cs811_hw_id != CS811_HW_ID) return ESP_ERR_INVALID_RESPONSE;

*hw_id = cs811_hw_id;

return ESP_OK;
}

static void cs811_log_error(void) {
uint8_t reg_addr = 0xE0;
uint8_t err_data = 0;
i2c_master_write_to_device(I2C_PORT, CS811_ADDRESS, &reg_addr, 1, DEFAULT_TIMEOUT);
ESP_ERROR_CHECK(
i2c_master_read_from_device(I2C_PORT, CS811_ADDRESS, &err_data, 1, DEFAULT_TIMEOUT)
);
ESP_LOG_BUFFER_HEX(TAG, &err_data, 1);
}
17 changes: 17 additions & 0 deletions components/ccs811-sensor/ccs811_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Created by yann on 12/17/24.
//

#ifndef CS811_PRIVATE_H
#define CS811_PRIVATE_H
#include <esp_err.h>
#include <stdbool.h>

static bool cs811_new_alg_data_ready(void);
static void cs811_read_alg_result_data(uint16_t *co2, uint16_t *tvoc);
static void cs811_init_meas_mode(void);
static esp_err_t cs811_load_hw_id(uint8_t *hw_id);
static void cs811_log_error(void);
static void cs811_start_application(void);

#endif //CS811_PRIVATE_H
16 changes: 16 additions & 0 deletions components/ccs811-sensor/include/ccs811.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Created by yann on 12/17/24.
//

#ifndef CS811_H
#define CS811_H
#include <esp_err.h>
#include <stdbool.h>


esp_err_t cs811_init(void);
void cs811_configure(void);
bool cs811_read_data(uint16_t *co2, uint16_t *tvoc);


#endif //CS811_H
2 changes: 1 addition & 1 deletion components/mqtt-data-interface/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(SRCS "mqtt-data-interface.c"
INCLUDE_DIRS "include"
REQUIRES mqtt sensor-readings
REQUIRES mqtt sensors
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define DATA_INTERFACE_H
#include <mqtt_client.h>

#include "sensor-readings.h"
#include "sensors.h"

typedef enum {
TEMPERATURE = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#ifndef MQTT_DATA_INTERFACE_PRIVATE_H
#define MQTT_DATA_INTERFACE_PRIVATE_H
#include "sensor-readings.h"
#include "sensors.h"

static void format_payload(char **payload, sensor_data_t data);

Expand Down
4 changes: 0 additions & 4 deletions components/sensor-readings/CMakeLists.txt

This file was deleted.

17 changes: 0 additions & 17 deletions components/sensor-readings/include/sensor-readings.h

This file was deleted.

25 changes: 0 additions & 25 deletions components/sensor-readings/sensor-readings.c

This file was deleted.

4 changes: 4 additions & 0 deletions components/sensors/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(SRCS "sensors.c"
INCLUDE_DIRS "include"
REQUIRES esp_event bme280-sensor ccs811-sensor
)
29 changes: 29 additions & 0 deletions components/sensors/include/sensors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Created by yann on 11/28/24.
//floa

#ifndef SENSOR_READINGS_H
#define SENSOR_READINGS_H
#include <esp_err.h>

typedef struct {
uint32_t bme_sensor;
uint32_t ccs_sensor;
uint32_t uv_sensor;
} sensor_power_levels_t;

typedef struct {
double temperature;
double humidity;
double pressure;
uint16_t co2;
uint16_t tvoc;
} sensor_data_t ;

esp_err_t sensors_i2c_init(void);
esp_err_t sensors_configure(void);
esp_err_t sensors_set_power_level(sensor_power_levels_t *levels);
esp_err_t sensors_power_off_all(void);
sensor_data_t sensors_read_all(void);

#endif //SENSOR_READINGS_H
Loading

0 comments on commit 4e3df59

Please sign in to comment.