Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverts #37

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: esp-idf build
uses: espressif/esp-idf-ci-action@v1
with:
esp_idf_version: v5.0
esp_idf_version: v5.1
target: esp32s3
path: ''

Expand Down
8 changes: 5 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"idf.adapterTargetName": "esp32s3",
"idf.openOcdConfigs": [
"board/esp32s3-bridge.cfg"
"board/esp32s3-builtin.cfg"
],
"idf.portWin": "COM3",
"idf.portWin": "COM4",
"idf.flashType": "UART",
"files.associations": {
"sdkconfig.h": "c",
Expand Down Expand Up @@ -92,7 +92,9 @@
"sps30_sensor_device.h": "c",
"csetjmp": "cpp",
"unordered_set": "cpp",
"esp_http_server.h": "c"
"esp_http_server.h": "c",
"sht3x_sensor_device.h": "c",
"scd4x_sensor_device.h": "c"
},
"C_Cpp.errorSquiggles": "disabled"
}
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(EXTRA_COMPONENT_DIRS ${ESP_IDF_LIB_PATH}/esp_idf_lib_helpers
${ESP_IDF_LIB_PATH}/bh1750
${ESP_IDF_LIB_PATH}/sht3x
${ESP_IDF_LIB_PATH}/scd30
${ESP_IDF_LIB_PATH}/scd4x
${HOMEKIT_LIB_PATH}/esp_hap_apple_profiles
${HOMEKIT_LIB_PATH}/esp_hap_platform
${HOMEKIT_LIB_PATH}/json_parser
Expand All @@ -36,4 +37,5 @@ message(STATUS "SDKCONFIG = ${SDKCONFIG}")
message(STATUS "SDKCONFIG_DEFAULTS = ${SDKCONFIG_DEFAULTS}")
message(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}")
message(STATUS "CMAKE_BINARY_DIR = ${CMAKE_BINARY_DIR}")
message(STATUS "COMPILE_OPTIONS = ${COMPILE_OPTIONS}")
message(STATUS "---------------------------------------")
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Air quality sensor on ESP32-S3 using ESP-IDF framework
* BH1750 - Light Sensor
* SPS30 Sensirion - Particle sensor
* SCD30 Sensirion - CO2 Sensor (Optional)
* SCD4x Sensirion - CO2 Sensor (Optional)

## Features
* LVGL based display UI
Expand Down
2 changes: 1 addition & 1 deletion components/lvgl
Submodule lvgl updated 142 files
2 changes: 1 addition & 1 deletion dependencies.lock
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dependencies:
component_hash: null
source:
type: idf
version: 5.0.0
version: 5.1.0
manifest_hash: 9275a596616c0a70cfe5b167d7bb0650aa90eb700c5b2ebe12470c3274692aa7
target: esp32s3
version: 1.0.0
3 changes: 2 additions & 1 deletion main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ idf_component_register(SRCS "main.cpp"
"hardware/display/display.cpp"
"hardware/hardware.cpp"
"hardware/sensors/sht3x_sensor_device.cpp"
"hardware/sensors/scd4x_sensor_device.cpp"
"hardware/sensors/scd30_sensor_device.cpp"
"hardware/sensors/sps30_sensor_device.cpp"
"hardware/sensors/bh1750_sensor_device.cpp"
Expand Down Expand Up @@ -60,7 +61,7 @@ idf_component_register(SRCS "main.cpp"
INCLUDE_DIRS "."
REQUIRES fatfs spi_flash LovyanGFX lvgl mbedtls esp_wifi
esp_hw_support app_update esp_http_server esp-tls espcoredump
esp_idf_lib_helpers i2cdev bh1750 sht3x scd30
esp_idf_lib_helpers i2cdev bh1750 sht3x scd30 scd4x
esp_hap_core esp_hap_apple_profiles json_generator)

target_compile_options(${COMPONENT_LIB} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>)
9 changes: 9 additions & 0 deletions main/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ config SCD30_SENSOR_TEMPERATURE_OFFSET
default 0
depends on SCD30_SENSOR_ENABLE

config SCD4x_SENSOR_ENABLE
bool "Enable Sensor SCD4x for CO2, temperature & humidity"
default n

config SCD4x_SENSOR_TEMPERATURE_OFFSET
int "Temperature offset for SCD4x in increment of 0.01C"
default 400
depends on SCD4x_SENSOR_ENABLE

config ENABLE_SD_CARD_SUPPORT
bool "Enable SD Card Support"
default n
Expand Down
17 changes: 17 additions & 0 deletions main/hardware/hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ void hardware::sensor_task_ftn()
initial_delay = std::max<TickType_t>(initial_delay, scd30_sensor_.get_initial_delay());
#endif

#ifdef CONFIG_SCD4x_SENSOR_ENABLE
scd4x_sensor_.init();
initial_delay = std::max<TickType_t>(initial_delay, scd4x_sensor_.get_initial_delay());
#endif

// Wait until all sensors_ are ready
vTaskDelay(initial_delay);

Expand All @@ -104,6 +109,11 @@ void hardware::sensor_task_ftn()
#ifdef CONFIG_SCD30_SENSOR_ENABLE
read_scd30_sensor();
#endif

#ifdef CONFIG_SCD4x_SENSOR_ENABLE
read_scd4x_sensor();
#endif

#ifdef CONFIG_SHT3X_SENSOR_ENABLE
read_sht3x_sensor();
#endif
Expand Down Expand Up @@ -156,6 +166,13 @@ void hardware::read_scd30_sensor()
}
#endif

#ifdef CONFIG_SCD4x_SENSOR_ENABLE
void hardware::read_scd4x_sensor()
{
read_sensor_if_time(scd4x_sensor_, scd4x_sensor_last_read_);
}
#endif

void hardware::read_sps30_sensor()
{
read_sensor_if_time(sps30_sensor_, sps30_sensor_last_read_);
Expand Down
10 changes: 10 additions & 0 deletions main/hardware/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "hardware/sensors/bh1750_sensor_device.h"
#include "hardware/sensors/scd30_sensor_device.h"
#include "hardware/sensors/scd4x_sensor_device.h"
#include "hardware/sensors/sensor.h"
#include "hardware/sensors/sht3x_sensor_device.h"
#include "hardware/sensors/sps30_sensor_device.h"
Expand Down Expand Up @@ -66,6 +67,12 @@ class hardware final : public esp32::singleton<hardware>
uint64_t scd30_sensor_last_read_ = 0;
#endif

#ifdef CONFIG_SCD4x_SENSOR_ENABLE
// SCD4x
scd4x_sensor_device &scd4x_sensor_{scd4x_sensor_device::create_instance()};
uint64_t scd4x_sensor_last_read_ = 0;
#endif

// SPS 30
sps30_sensor_device &sps30_sensor_{sps30_sensor_device::create_instance()};
uint64_t sps30_sensor_last_read_ = 0;
Expand All @@ -82,6 +89,9 @@ class hardware final : public esp32::singleton<hardware>
#endif
#ifdef CONFIG_SCD30_SENSOR_ENABLE
void read_scd30_sensor();
#endif
#ifdef CONFIG_SCD4x_SENSOR_ENABLE
void read_scd4x_sensor();
#endif
esp_err_t sps30_i2c_init();
void read_sps30_sensor();
Expand Down
8 changes: 4 additions & 4 deletions main/hardware/sensors/scd30_sensor_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
void scd30_sensor_device::init()
{
CHECK_THROW_ESP(scd30_init_desc(&scd30_sensor_, I2C_NUM_1, SDAWire, SCLWire));
CHECK_THROW_ESP(scd30_set_measurement_interval(&scd30_sensor_, (decltype(last_measurement_value_)::max_value_interval_ms / 1000) / 2));
CHECK_THROW_ESP(scd30_set_temperature_offset(&scd30_sensor_, CONFIG_SCD30_SENSOR_TEMPERATURE_OFFSET / 100));
constexpr uint16_t interval = (decltype(last_measurement_value_)::max_value_interval_ms / 1000) / 2;
ESP_LOGI(SENSOR_SCD30_TAG, "Interval is :%u seconds", interval);
CHECK_THROW_ESP(scd30_set_measurement_interval(&scd30_sensor_, interval));
CHECK_THROW_ESP(scd30_set_automatic_self_calibration(&scd30_sensor_, true));
}

Expand All @@ -35,9 +38,6 @@ std::array<std::tuple<sensor_id_index, float>, 4> scd30_sensor_device::read()
auto err = scd30_read_measurement(&scd30_sensor_, &co2, &temperatureC, &humidity);
if (err == ESP_OK)
{
#ifdef CONFIG_SCD30_SENSOR_TEMPERATURE_OFFSET
temperatureC -= CONFIG_SCD30_SENSOR_TEMPERATURE_OFFSET / 100; // offset for the heat generated by sensor itself.
#endif
temperatureF = (temperatureC * 1.8) + 32;
ESP_LOGI(SENSOR_SCD30_TAG, "Read SCD30 sensor values:%g ppm %g F, %g C %g %%", co2, temperatureF, temperatureC, humidity);
}
Expand Down
2 changes: 1 addition & 1 deletion main/hardware/sensors/scd30_sensor_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class scd30_sensor_device final : public esp32::singleton<scd30_sensor_device>

private:
i2c_dev_t scd30_sensor_{};
last_measurement_helper<std::tuple<float, float, float, float>, 20000> last_measurement_value_;
last_measurement_helper<std::tuple<float, float, float, float>, 60000> last_measurement_value_;

scd30_sensor_device() = default;
friend class esp32::singleton<scd30_sensor_device>;
Expand Down
91 changes: 91 additions & 0 deletions main/hardware/sensors/scd4x_sensor_device.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@


#include "hardware/sensors/scd4x_sensor_device.h"

#ifdef CONFIG_SCD4x_SENSOR_ENABLE
#include "hardware/pins.h"
#include "logging/logging_tags.h"
#include "util/exceptions.h"
#include "util/misc.h"
#include "util/noncopyable.h"
#include <esp_log.h>
#include <i2cdev.h>

void scd4x_sensor_device::init()
{
vTaskDelay(pdMS_TO_TICKS(1000)); // needs 1000 ms to start working
CHECK_THROW_ESP(scd4x_init_desc(&scd4x_sensor_, I2C_NUM_1, SDAWire, SCLWire));

ESP_LOGI(SENSOR_SCD4x_TAG, "Initializing sensor...");
CHECK_THROW_ESP(scd4x_stop_periodic_measurement(&scd4x_sensor_));
CHECK_THROW_ESP(scd4x_reinit(&scd4x_sensor_));
ESP_LOGI(SENSOR_SCD4x_TAG, "Sensor initialized");

bool mal_function = false;
CHECK_THROW_ESP(scd4x_perform_self_test(&scd4x_sensor_, &mal_function));
if (mal_function)
{
CHECK_THROW_ESP2(ESP_FAIL, "SCD4x Self Test Failed");
}
#ifdef CONFIG_SCD4x_SENSOR_TEMPERATURE_OFFSET
CHECK_THROW_ESP(scd4x_set_temperature_offset(&scd4x_sensor_, CONFIG_SCD4x_SENSOR_TEMPERATURE_OFFSET / 100));
#endif
CHECK_THROW_ESP(scd4x_set_automatic_self_calibration(&scd4x_sensor_, true));

// low power mode to avoid additional heat generated
CHECK_THROW_ESP(scd4x_start_low_power_periodic_measurement(&scd4x_sensor_));
}

std::array<std::tuple<sensor_id_index, float>, 4> scd4x_sensor_device::read()
{
float co2 = NAN;
float temperatureC = NAN;
float temperatureF = NAN;
float humidity = NAN;

bool ready = false;
auto error = scd4x_get_data_ready_status(&scd4x_sensor_, &ready);

if ((error == ESP_OK))
{
if (ready)
{
uint16_t co2_int;
auto err = scd4x_read_measurement(&scd4x_sensor_, &co2_int, &temperatureC, &humidity);
if (err == ESP_OK)
{
co2 = co2_int;
temperatureF = (temperatureC * 1.8) + 32;
ESP_LOGI(SENSOR_SCD4x_TAG, "Read SCD40 sensor values:%g ppm %g F, %g C %g %%", co2, temperatureF, temperatureC, humidity);
}
else
{
ESP_LOGE(SENSOR_SCD4x_TAG, "Failed to read from SCD40 sensor with error:%s", esp_err_to_name(err));
}
last_measurement_value_.store(std::tie(co2, temperatureC, temperatureF, humidity));
}
else
{
std::tuple<float, float, float, float> old_values;
if (last_measurement_value_.update(old_values))
{
std::tie(co2, temperatureC, temperatureF, humidity) = old_values;
}
}
}
else
{
ESP_LOGE(SENSOR_SCD4x_TAG, "Failed to read from SCD40 sensor with failed to read measurement error:0x%x", error);
}

return {std::tuple<sensor_id_index, float>{sensor_id_index::temperatureC, esp32::round_with_precision(temperatureC, 0.01)},
std::tuple<sensor_id_index, float>{sensor_id_index::temperatureF, esp32::round_with_precision(temperatureF, 0.1)},
std::tuple<sensor_id_index, float>{sensor_id_index::CO2, esp32::round_with_precision(co2, 1)},
std::tuple<sensor_id_index, float>{sensor_id_index::humidity, esp32::round_with_precision(humidity, 1)}};
}

uint8_t scd4x_sensor_device::get_initial_delay()
{
return 0;
}
#endif
28 changes: 28 additions & 0 deletions main/hardware/sensors/scd4x_sensor_device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once
#include "sdkconfig.h"

#ifdef CONFIG_SCD4x_SENSOR_ENABLE
#include "hardware/sensors/last_measurement_helper.h"
#include "hardware/sensors/sensor_id.h"
#include "util/singleton.h"
#include <array>
#include <i2cdev.h>
#include <scd4x.h>
#include <tuple>

class scd4x_sensor_device final : public esp32::singleton<scd4x_sensor_device>
{
public:
void init();
std::array<std::tuple<sensor_id_index, float>, 4> read();

uint8_t get_initial_delay();

private:
i2c_dev_t scd4x_sensor_{};
last_measurement_helper<std::tuple<float, float, float, float>, 60000> last_measurement_value_;

scd4x_sensor_device() = default;
friend class esp32::singleton<scd4x_sensor_device>;
};
#endif
26 changes: 14 additions & 12 deletions main/hardware/sensors/sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "util/circular_buffer.h"
#include "util/psram_allocator.h"
#include "util/semaphore_lockable.h"
#include <array>
#include <atomic>
#include <cmath>
#include <mutex>
Expand Down Expand Up @@ -265,7 +266,7 @@ constexpr std::array<sensor_definition_display, 6> pm_10_definition_display{
sensor_definition_display{424, std::numeric_limits<uint32_t>::max(), sensor_level::level_6},
};

#ifdef CONFIG_SCD30_SENSOR_ENABLE
#if defined CONFIG_SCD30_SENSOR_ENABLE || defined CONFIG_SCD4x_SENSOR_ENABLE
constexpr std::array<sensor_definition_display, 6> co2_definition_display{
sensor_definition_display{0, 600, sensor_level::level_1},
sensor_definition_display{600, 800, sensor_level::level_2},
Expand All @@ -277,19 +278,20 @@ constexpr std::array<sensor_definition_display, 6> co2_definition_display{

#endif

constexpr std::array<sensor_definition, total_sensors> sensor_definitions{
constexpr std::array<sensor_definition, total_sensors> sensor_definitions
{
sensor_definition{"PM 2.5", "µg/m³", pm_2_5_definition_display.data(), pm_2_5_definition_display.size(), 0, 1000, 1},
sensor_definition{"Temperature", "°F", no_level.data(), no_level.size(), -40, 140, 1},
sensor_definition{"Temperature", "°C", no_level.data(), no_level.size(), -40, 70, 0.1},
sensor_definition{"Humidity", "⁒", no_level.data(), no_level.size(), 0, 100, 1},
#ifdef CONFIG_SCD30_SENSOR_ENABLE
sensor_definition{"CO2", "ppm", co2_definition_display.data(), co2_definition_display.size(), 0, 2000, 1},
sensor_definition{"Temperature", "°F", no_level.data(), no_level.size(), -40, 140, 1},
sensor_definition{"Temperature", "°C", no_level.data(), no_level.size(), -40, 70, 0.1},
sensor_definition{"Humidity", "⁒", no_level.data(), no_level.size(), 0, 100, 1},
#if defined CONFIG_SCD30_SENSOR_ENABLE || defined CONFIG_SCD4x_SENSOR_ENABLE
sensor_definition{"CO2", "ppm", co2_definition_display.data(), co2_definition_display.size(), 0, 2000, 1},
#endif
sensor_definition{"PM 1", "µg/m³", no_level.data(), no_level.size(), 0, 1000, 1},
sensor_definition{"PM 4", "µg/m³", no_level.data(), no_level.size(), 0, 1000, 1},
sensor_definition{"PM 10", "µg/m³", pm_10_definition_display.data(), pm_10_definition_display.size(), 0, 1000, 1},
sensor_definition{"Typical Particle Size", "µg", no_level.data(), no_level.size(), 0, 10, 0.1},
sensor_definition{"Light Intensity", "lux", no_level.data(), no_level.size(), 0, 65535, 1},
sensor_definition{"PM 1", "µg/m³", no_level.data(), no_level.size(), 0, 1000, 1},
sensor_definition{"PM 4", "µg/m³", no_level.data(), no_level.size(), 0, 1000, 1},
sensor_definition{"PM 10", "µg/m³", pm_10_definition_display.data(), pm_10_definition_display.size(), 0, 1000, 1},
sensor_definition{"Typical Particle Size", "µg", no_level.data(), no_level.size(), 0, 10, 0.1},
sensor_definition{"Light Intensity", "lux", no_level.data(), no_level.size(), 0, 65535, 1},
};

constexpr auto &&get_sensor_definition(sensor_id_index id)
Expand Down
2 changes: 1 addition & 1 deletion main/hardware/sensors/sensor_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ enum class sensor_id_index : uint8_t
temperatureF,
temperatureC,
humidity,
#ifdef CONFIG_SCD30_SENSOR_ENABLE
#if defined CONFIG_SCD30_SENSOR_ENABLE || defined CONFIG_SCD4x_SENSOR_ENABLE
CO2,
#endif
pm_1,
Expand Down
Loading