Skip to content

Commit

Permalink
Add SPS30 support (#25)
Browse files Browse the repository at this point in the history
* Add SPS30 support
* Move code to cpp files for ui classes
* Misc fixes
  • Loading branch information
dk307 committed May 4, 2023
1 parent d033d02 commit df5d977
Show file tree
Hide file tree
Showing 48 changed files with 1,845 additions and 1,457 deletions.
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"idf.openOcdConfigs": [
"board/esp32s3-bridge.cfg"
],
"idf.portWin": "COM3",
"idf.portWin": "COM4",
"idf.flashType": "UART",
"files.associations": {
"sdkconfig.h": "c",
Expand Down Expand Up @@ -88,7 +88,8 @@
"esp_httpd_priv.h": "c",
"esp_system.h": "c",
"hap.h": "c",
"ui.h": "c"
"ui.h": "c",
"sps30_sensor_device.h": "c"
},
"C_Cpp.errorSquiggles": "disabled"
}
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(EXTRA_COMPONENT_DIRS ${ESP_IDF_LIB_PATH}/esp_idf_lib_helpers
${ESP_IDF_LIB_PATH}/i2cdev
${ESP_IDF_LIB_PATH}/bh1750
${ESP_IDF_LIB_PATH}/sht3x
${ESP_IDF_LIB_PATH}/scd30
${HOMEKIT_LIB_PATH}/esp_hap_apple_profiles
${HOMEKIT_LIB_PATH}/esp_hap_platform
${HOMEKIT_LIB_PATH}/json_parser
Expand Down
9 changes: 8 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ gulp.task('display-fonts-big-font', function() {
'big_panel_font.c', '--symbols="0,1,2,3,4,5,6,7,8,9,-"');
});

gulp.task('display-fonts-big-font-dual', function() {
return font_create(
8, 130,
'./node_modules/@fontsource/montserrat/files/montserrat-all-300-normal.woff',
'big_panel_font_dual.c', '--symbols="0,1,2,3,4,5,6,7,8,9,-"');
});

gulp.task('display-fonts-temp-hum', function() {
return font_create(
4, 72,
Expand Down Expand Up @@ -233,7 +240,7 @@ gulp.task('display-fonts-14-all', function() {
gulp.task(
'display-fonts',
gulp.series(
'display-fonts-big-font', 'display-fonts-temp-hum',
'display-fonts-big-font', 'display-fonts-big-font-dual', 'display-fonts-temp-hum',
'display-fonts-40-regular-number', 'display-fonts-48-all',
'display-fonts-18-uints', 'display-fonts-14-all'));

Expand Down
14 changes: 13 additions & 1 deletion main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@ idf_component_register(SRCS "main.cpp"
"hardware/display/display.cpp"
"hardware/hardware.cpp"
"hardware/sensors/sht3x_sensor_device.cpp"
"hardware/sensors/scd30_sensor_device.cpp"
"hardware/sensors/sps30_sensor_device.cpp"
"hardware/sensors/bh1750_sensor_device.cpp"
"hardware/sensors/sps30/sps30.c"
"hardware/sensors/sps30/sensirion_common.c"
"ui/ui2.cpp"
"ui/ui_interface.cpp"
"ui/ui_screen.cpp"
"ui/ui_boot_screen.cpp"
"ui/ui_hardware_screen.cpp"
"ui/ui_homekit_screen.cpp"
"ui/ui_main_screen.cpp"
"ui/ui_screen_with_sensor_panel.cpp"
"ui/ui_information_screen.cpp"
"ui/ui_sensor_detail_screen.cpp"
"ui/ui_wifi_enroll_screen.cpp"
"ui/ui_launcher_screen.cpp"
"config/config_manager.cpp"
"config/preferences.cpp"
"wifi/wifi_sta.cpp"
Expand All @@ -29,6 +40,7 @@ idf_component_register(SRCS "main.cpp"
"logging/commands.cpp"
"homekit/homekit_integration.cpp"
"generated/display/src/big_panel_font.c"
"generated/display/src/big_panel_font_dual.c"
"generated/display/src/temp_hum_font.c"
"generated/display/src/regular_numbers_40_font.c"
"generated/display/src/all_48_font.c"
Expand All @@ -48,7 +60,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
esp_idf_lib_helpers i2cdev bh1750 sht3x scd30
esp_hap_core esp_hap_apple_profiles json_generator)

target_compile_options(${COMPONENT_LIB} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>)
7 changes: 6 additions & 1 deletion main/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@ menu "Project"

config SHT3X_SENSOR_ENABLE
bool "Enable Sensor SHT 3x for temperature & humidity"
default n
default n

config SCD30_SENSOR_ENABLE
bool "Enable Sensor SCD30 for CO2, temperature & humidity"
default n

endmenu
1 change: 1 addition & 0 deletions main/config/config_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ std::optional<uint8_t> config::get_manual_screen_brightness()
const auto value = nvs_storage.get(screen_brightness_key, static_cast<uint8_t>(0));
return value == 0 ? std::nullopt : std::optional<uint8_t>(value);
}

void config::set_manual_screen_brightness(const std::optional<uint8_t> &screen_brightness)
{
std::lock_guard<esp32::semaphore> lock(data_mutex_);
Expand Down
64 changes: 40 additions & 24 deletions main/hardware/hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "util/helper.h"
#include "util/misc.h"
#include <driver/i2c.h>
#include <esp_log.h>

template <class T> void hardware::read_sensor_if_time(T &sensor, uint64_t &last_read)
{
Expand All @@ -33,18 +34,18 @@ float hardware::get_sensor_value(sensor_id_index index) const

sensor_history::sensor_history_snapshot hardware::get_sensor_detail_info(sensor_id_index index)
{
return (*sensors_history)[static_cast<size_t>(index)].get_snapshot(sensor_history::reads_per_minute);
return (*sensors_history_)[static_cast<size_t>(index)].get_snapshot(sensor_history::reads_per_minute);
}

bool hardware::clean_sps_30()
{
return sps30_sensor.clean();
return sps30_sensor_.clean();
}

void hardware::begin()
{
CHECK_THROW_ESP(i2cdev_init());
sensor_refresh_task.spawn_pinned("sensor_task", 4 * 1024, esp32::task::default_priority, esp32::hardware_core);
sensor_refresh_task_.spawn_pinned("sensor_task", 4 * 1024, esp32::task::default_priority, esp32::hardware_core);
}

void hardware::set_sensor_value(sensor_id_index index, float value)
Expand All @@ -53,16 +54,16 @@ void hardware::set_sensor_value(sensor_id_index index, float value)
const auto i = static_cast<size_t>(index);
if (!std::isnan(value))
{
(*sensors_history)[i].add_value(value);
changed = sensors[i].set_value(value);
(*sensors_history_)[i].add_value(value);
changed = sensors_[i].set_value(value);
ESP_LOGI(HARDWARE_TAG, "Updated for sensor:%.*s Value:%g", get_sensor_name(index).size(), get_sensor_name(index).data(),
sensors[i].get_value());
sensors_[i].get_value());
}
else
{
ESP_LOGW(HARDWARE_TAG, "Got an invalid value for sensor:%.*s", get_sensor_name(index).size(), get_sensor_name(index).data());
(*sensors_history)[i].clear();
changed = sensors[i].set_invalid_value();
(*sensors_history_)[i].clear();
changed = sensors_[i].set_invalid_value();
}

if (changed)
Expand All @@ -79,70 +80,85 @@ void hardware::sensor_task_ftn()

TickType_t initial_delay = 0;

sps30_sensor.init();
bh1750_sensor.init();
initial_delay = std::max(initial_delay, bh1750_sensor.get_initial_delay());
sps30_sensor_.init();
bh1750_sensor_.init();
initial_delay = std::max(initial_delay, bh1750_sensor_.get_initial_delay());

#ifdef CONFIG_SHT3X_SENSOR_ENABLE
sht3x_sensor.init();
initial_delay = std::max<TickType_t>(initial_delay, sht3x_sensor.get_initial_delay());
sht3x_sensor_.init();
initial_delay = std::max<TickType_t>(initial_delay, sht3x_sensor_.get_initial_delay());
#endif

// Wait until all sensors are ready
#ifdef CONFIG_SCD30_SENSOR_ENABLE
scd30_sensor_.init();
initial_delay = std::max<TickType_t>(initial_delay, scd30_sensor_.get_initial_delay());
#endif

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

do
{
read_bh1750_sensor();
set_auto_display_brightness();
#ifdef CONFIG_SCD30_SENSOR_ENABLE
read_scd30_sensor();
#endif
#ifdef CONFIG_SHT3X_SENSOR_ENABLE
read_sht3x_sensor();
#endif
read_sps30_sensor();

vTaskDelay(pdMS_TO_TICKS(500));
vTaskDelay(pdMS_TO_TICKS(sensor_history::sensor_interval / 20));
} while (true);
}
catch (const std::exception &ex)
{
ESP_LOGE(OPERATIONS_TAG, "Hardware Task Failure:%s", ex.what());
throw;
// throw;
}

vTaskDelete(NULL);
}

void hardware::read_bh1750_sensor()
{
const auto values = bh1750_sensor.read();
const auto values = bh1750_sensor_.read();

if (!std::isnan(std::get<1>(values[0])))
{
light_sensor_values.add_value(std::get<1>(values[0]));
light_sensor_values_.add_value(std::get<1>(values[0]));
}

const auto now = esp32::millis();
if (now - bh1750_sensor_last_read >= sensor_history::sensor_interval)
if (now - bh1750_sensor_last_read_ >= sensor_history::sensor_interval)
{
for (auto &&value : values)
{
set_sensor_value(std::get<0>(value), std::get<1>(value));
}

bh1750_sensor_last_read = now;
bh1750_sensor_last_read_ = now;
}
}

#ifdef CONFIG_SHT3X_SENSOR_ENABLE
void hardware::read_sht3x_sensor()
{
read_sensor_if_time(sht3x_sensor, sht3x_sensor_last_read);
read_sensor_if_time(sht3x_sensor_, sht3x_sensor_last_read_);
}
#endif

#ifdef CONFIG_SCD30_SENSOR_ENABLE
void hardware::read_scd30_sensor()
{
read_sensor_if_time(scd30_sensor_, scd30_sensor_last_read_);
}
#endif

void hardware::read_sps30_sensor()
{
read_sensor_if_time(sps30_sensor, sps30_sensor_last_read);
read_sensor_if_time(sps30_sensor_, sps30_sensor_last_read_);
}

uint8_t hardware::lux_to_intensity(uint16_t lux)
Expand Down Expand Up @@ -171,7 +187,7 @@ void hardware::set_auto_display_brightness()
}
else
{
const auto avg_lux = light_sensor_values.get_average();
const auto avg_lux = light_sensor_values_.get_average();
ESP_LOGD(SENSOR_BH1750_TAG, "Average lux:%g", avg_lux.value_or(128));
required_brightness = lux_to_intensity(avg_lux.value_or(128));
}
Expand All @@ -182,5 +198,5 @@ void hardware::set_auto_display_brightness()

std::string hardware::get_sps30_error_register_status()
{
return sps30_sensor.get_error_register_status();
return sps30_sensor_.get_error_register_status();
}
43 changes: 27 additions & 16 deletions main/hardware/hardware.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "hardware/sensors/bh1750_sensor_device.h"
#include "hardware/sensors/scd30_sensor_device.h"
#include "hardware/sensors/sensor.h"
#include "hardware/sensors/sht3x_sensor_device.h"
#include "hardware/sensors/sps30_sensor_device.h"
Expand All @@ -19,22 +20,22 @@ class hardware final : public esp32::singleton<hardware>

const sensor_value &get_sensor(sensor_id_index index) const
{
return sensors[static_cast<uint8_t>(index)];
return sensors_[static_cast<uint8_t>(index)];
}

float get_sensor_value(sensor_id_index index) const;
sensor_history::sensor_history_snapshot get_sensor_detail_info(sensor_id_index index);

const sensor_history &get_sensor_history(sensor_id_index index) const
{
return (*sensors_history)[static_cast<uint8_t>(index)];
return (*sensors_history_)[static_cast<uint8_t>(index)];
}

std::string get_sps30_error_register_status();
bool clean_sps_30();

private:
hardware(config &config, display &display) : config_(config), display_(display), sensor_refresh_task([this] { sensor_task_ftn(); })
hardware(config &config, display &display) : config_(config), display_(display), sensor_refresh_task_([this] { sensor_task_ftn(); })
{
}

Expand All @@ -44,34 +45,44 @@ class hardware final : public esp32::singleton<hardware>
display &display_;

// same index as sensor_id_index
std::array<sensor_value, total_sensors> sensors;
std::unique_ptr<std::array<sensor_history, total_sensors>, esp32::psram::deleter> sensors_history =
std::array<sensor_value, total_sensors> sensors_;
std::unique_ptr<std::array<sensor_history, total_sensors>, esp32::psram::deleter> sensors_history_ =
esp32::psram::make_unique<std::array<sensor_history, total_sensors>>();

esp32::task sensor_refresh_task;
esp32::task sensor_refresh_task_;

using light_sensor_values_t = sensor_history_t<6>;
light_sensor_values_t light_sensor_values;
using light_sensor_values_t = sensor_history_t<12>;
light_sensor_values_t light_sensor_values_;

#ifdef CONFIG_SHT3X_SENSOR_ENABLE
// // SHT31
sht3x_sensor_device &sht3x_sensor{sht3x_sensor_device::create_instance()};
uint64_t sht3x_sensor_last_read = 0;
// SHT31
sht3x_sensor_device &sht3x_sensor_{sht3x_sensor_device::create_instance()};
uint64_t sht3x_sensor_last_read_ = 0;
#endif

// // SPS 30
sps30_sensor_device &sps30_sensor{sps30_sensor_device::create_instance()};
uint64_t sps30_sensor_last_read = 0;
#ifdef CONFIG_SCD30_SENSOR_ENABLE
// SCD30
scd30_sensor_device &scd30_sensor_{
scd30_sensor_device::create_instance(static_cast<uint16_t>(sensor_history::sensor_interval / 1000), sensor_history::sensor_interval / 30)};
uint64_t scd30_sensor_last_read_ = 0;
#endif

// SPS 30
sps30_sensor_device &sps30_sensor_{sps30_sensor_device::create_instance(sensor_history::sensor_interval / 30)};
uint64_t sps30_sensor_last_read_ = 0;

// BH1750
bh1750_sensor_device &bh1750_sensor{bh1750_sensor_device::create_instance()};
uint64_t bh1750_sensor_last_read = 0;
bh1750_sensor_device &bh1750_sensor_{bh1750_sensor_device::create_instance()};
uint64_t bh1750_sensor_last_read_ = 0;

void set_sensor_value(sensor_id_index index, float value);

void read_bh1750_sensor();
#ifdef CONFIG_SHT3X_SENSOR_ENABLE
void read_sht3x_sensor();
#endif
#ifdef CONFIG_SCD30_SENSOR_ENABLE
void read_scd30_sensor();
#endif
esp_err_t sps30_i2c_init();
void read_sps30_sensor();
Expand Down
2 changes: 1 addition & 1 deletion main/hardware/sd_card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void sd_card::begin()

esp_vfs_fat_mount_config_t mount_config{};
mount_config.format_if_mount_failed = false;
mount_config.max_files = 15;
mount_config.max_files = 10;
mount_config.allocation_unit_size = 512;
// mount_config.disk_status_check_enable = true;

Expand Down
Loading

0 comments on commit df5d977

Please sign in to comment.