Compare commits

..

1 Commits

Author SHA1 Message Date
72a6ceb30c chore: moving to more dynamic structure 2024-09-22 02:52:57 +03:00
14 changed files with 95710 additions and 439 deletions

View File

@ -1,20 +1,25 @@
// BMP280Sensor.h
#ifndef BMP280SENSOR_H #ifndef BMP280SENSOR_H
#define BMP280SENSOR_H #define BMP280SENSOR_H
#define BMP280_ADDR (0x76)
#include "i2cSensor.h"
#include <Adafruit_BME280.h> // Adafruit library for BMP280
#define BMP280_ADDR (0x76)
#define SEALEVELPRESSURE_HPA (1013.25) #define SEALEVELPRESSURE_HPA (1013.25)
#include <Adafruit_BME280.h> class BMP280Sensor : public i2cSensor {
class BMP280Sensor {
public: public:
BMP280Sensor(uint8_t address = BMP280_ADDR); // Constructor BMP280Sensor(uint8_t address = BMP280_ADDR); // Constructor
void init();
void read_values(float* temperature, float* humidity, float* pressure, float* altitude); // Override init method from i2cSensor
void init() override;
// Override methods from Sensor
std::string getName() const override;
std::vector<ReadingType> getFeatures() const override;
float readValue(ReadingType feature) override;
private: private:
uint8_t _address; // BMP280 wake pin
Adafruit_BME280 bmp280; // BMP280 object Adafruit_BME280 bmp280; // BMP280 object
}; };

View File

@ -1,23 +1,26 @@
// CCS811Sensor.h
#ifndef CCS811SENSOR_H #ifndef CCS811SENSOR_H
#define CCS811SENSOR_H #define CCS811SENSOR_H
#define CCS811_WAK 23
#include "i2cSensor.h"
#include <ccs811.h> // Include CCS811 library #include <ccs811.h> // Include CCS811 library
class CCS811Sensor { class CCS811Sensor : public i2cSensor {
public: public:
CCS811Sensor(uint8_t wakePin = CCS811_WAK); // Constructor explicit CCS811Sensor(uint8_t wakePin = 23); // Constructor with default wake pin
void init(double* temperature, double* humidity); // temp and hum needed to correct env
void init(); // Initialize without temperature and humidity void init() override; // Override init method from i2cSensor
void read_values(uint16_t* eco2, uint16_t* etvoc, uint16_t* errstat, uint16_t* raw); void init(double* temperature, double* humidity); // Initialize with environmental data
// Override methods from Sensor
std::string getName() const override;
std::vector<ReadingType> getFeatures() const override;
float readValue(ReadingType feature) override;
private: private:
uint8_t _wakePin; // CCS811 wake pin uint8_t wakePin_; // CCS811 wake pin
CCS811 ccs811; // CCS811 object CCS811 ccs811_; // CCS811 object
double* _temperaturePtr; // Pointer to temperature value double* temperaturePtr_; // Pointer to temperature value
double* _humidityPtr; // Pointer to humidity value double* humidityPtr_; // Pointer to humidity value
}; };
#endif // CCS811SENSOR_H #endif // CCS811SENSOR_H

View File

@ -1,20 +1,22 @@
// HDC1080Sensor.h
#ifndef HDC1080SENSOR_H #ifndef HDC1080SENSOR_H
#define HDC1080SENSOR_H #define HDC1080SENSOR_H
#define HDC1080_ADDR 0x40
#include "ClosedCube_HDC1080.h" #include "i2cSensor.h"
#include "ClosedCube_HDC1080.h" // Include the HDC1080 library
class HDC1080Sensor { class HDC1080Sensor : public i2cSensor {
public: public:
HDC1080Sensor(uint8_t address = HDC1080_ADDR); // Constructor explicit HDC1080Sensor(uint8_t address = 0x40); // Constructor with default I2C address
void init(); // Initialize HDC1080 sensor
void read_values(double* temperature, double* humidity, bool* success); // Read temperature and humidity values void init() override; // Override init method from i2cSensor
// Override methods from Sensor
std::string getName() const override;
std::vector<ReadingType> getFeatures() const override;
float readValue(ReadingType feature) override;
private: private:
uint8_t _address; // HDC1080 I2C address ClosedCube_HDC1080 hdc1080_; // HDC1080 object
ClosedCube_HDC1080 hdc1080; // HDC1080 object
}; };
#endif // HDC1080SENSOR_H #endif // HDC1080SENSOR_H

34
include/ReadingType.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef READING_TYPE_LIST_H
#define READING_TYPE_LIST_H
#include <string>
#include <iostream>
// Define a macro to list all the enum values with their names
#define READING_TYPE_LIST \
X(Temperature) \
X(Humidity) \
X(Pressure) \
X(Altitude) \
X(eCO2) \
X(eTVOC) \
X(ErrorStatus)
// Enum class for different types of readings
enum class ReadingType {
#define X(name) name,
READING_TYPE_LIST
#undef X
};
// Inline function to convert ReadingType to a string
inline std::string readingTypeToString(ReadingType type) {
switch (type) {
#define X(name) case ReadingType::name: return #name;
READING_TYPE_LIST
#undef X
default: return "Unknown";
}
}
#endif // READING_TYPE_LIST_H

17
include/Sensor.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SENSOR_H
#define SENSOR_H
#include <string>
#include <vector>
#include "ReadingType.h"
// Abstract base class for sensors
class Sensor {
public:
virtual ~Sensor() {}
virtual std::string getName() const = 0;
virtual std::vector<ReadingType> getFeatures() const = 0;
virtual float readValue(ReadingType feature) = 0;
};
#endif // SENSOR_H

24
include/i2cSensor.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef I2CSENSOR_H
#define I2CSENSOR_H
#include "Sensor.h"
#include <Wire.h> // Include the Wire library for I2C
// Abstract base class for I2C sensors
class i2cSensor : public Sensor {
public:
virtual ~i2cSensor() {}
// Initializes the sensor
virtual void init() = 0;
// Returns the I2C address of the sensor
uint8_t getAddress() const {
return i2c_address;
}
protected:
uint8_t i2c_address; // I2C address of the sensor
};
#endif // I2CSENSOR_H

View File

@ -21,3 +21,4 @@ lib_deps =
monitor_speed = 115200 monitor_speed = 115200
monitor_filters = default, log2file monitor_filters = default, log2file
extra_scripts = populate_static.py extra_scripts = populate_static.py
lib_ldf_mode = deep

View File

@ -0,0 +1,420 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.09999999999999999,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.15,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.508
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.0,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"use_height_for_length_calcs": true
},
"track_widths": [],
"via_dimensions": [],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "satPowerPot.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"692abbba-6e8f-4955-ace9-f9a6de54691a",
""
]
],
"text_variables": {}
}

View File

@ -0,0 +1,753 @@
(kicad_sch (version 20211123) (generator eeschema)
(uuid 692abbba-6e8f-4955-ace9-f9a6de54691a)
(paper "A4")
(lib_symbols
(symbol "Conn_01x19_Female_1" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
(property "Reference" "J1" (id 0) (at -1.27 1.2701 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "Conn_01x19_Female_1" (id 1) (at 34.29 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "connector" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Generic connector, single row, 01x19, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "Conn_01x19_Female_1_1_1"
(arc (start 0 -22.352) (mid -0.508 -22.86) (end 0 -23.368)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -19.812) (mid -0.508 -20.32) (end 0 -20.828)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -17.272) (mid -0.508 -17.78) (end 0 -18.288)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -14.732) (mid -0.508 -15.24) (end 0 -15.748)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -12.192) (mid -0.508 -12.7) (end 0 -13.208)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -9.652) (mid -0.508 -10.16) (end 0 -10.668)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -7.112) (mid -0.508 -7.62) (end 0 -8.128)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -4.572) (mid -0.508 -5.08) (end 0 -5.588)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -2.032) (mid -0.508 -2.54) (end 0 -3.048)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -22.86)
(xy -0.508 -22.86)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -20.32)
(xy -0.508 -20.32)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -17.78)
(xy -0.508 -17.78)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -15.24)
(xy -0.508 -15.24)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -12.7)
(xy -0.508 -12.7)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -10.16)
(xy -0.508 -10.16)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -7.62)
(xy -0.508 -7.62)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -5.08)
(xy -0.508 -5.08)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -2.54)
(xy -0.508 -2.54)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 0)
(xy -0.508 0)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 2.54)
(xy -0.508 2.54)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 5.08)
(xy -0.508 5.08)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 7.62)
(xy -0.508 7.62)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 10.16)
(xy -0.508 10.16)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 12.7)
(xy -0.508 12.7)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 15.24)
(xy -0.508 15.24)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 17.78)
(xy -0.508 17.78)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 20.32)
(xy -0.508 20.32)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 22.86)
(xy -0.508 22.86)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 0.508) (mid -0.508 0) (end 0 -0.508)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 3.048) (mid -0.508 2.54) (end 0 2.032)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 5.588) (mid -0.508 5.08) (end 0 4.572)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 8.128) (mid -0.508 7.62) (end 0 7.112)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 10.668) (mid -0.508 10.16) (end 0 9.652)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 13.208) (mid -0.508 12.7) (end 0 12.192)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 15.748) (mid -0.508 15.24) (end 0 14.732)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 18.288) (mid -0.508 17.78) (end 0 17.272)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 20.828) (mid -0.508 20.32) (end 0 19.812)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 23.368) (mid -0.508 22.86) (end 0 22.352)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(pin passive line (at -5.08 -22.86 0) (length 3.81)
(name "Pin_39" (effects (font (size 1.27 1.27))))
(number "19" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 22.86 0) (length 3.81)
(name "Pin_20" (effects (font (size 1.27 1.27))))
(number "20" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 20.32 0) (length 3.81)
(name "Pin_22" (effects (font (size 1.27 1.27))))
(number "22" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 17.78 0) (length 3.81)
(name "Pin_23" (effects (font (size 1.27 1.27))))
(number "23" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 15.24 0) (length 3.81)
(name "Pin_24" (effects (font (size 1.27 1.27))))
(number "24" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 12.7 0) (length 3.81)
(name "Pin_25" (effects (font (size 1.27 1.27))))
(number "25" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 10.16 0) (length 3.81)
(name "Pin_26" (effects (font (size 1.27 1.27))))
(number "26" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 7.62 0) (length 3.81)
(name "Pin_27" (effects (font (size 1.27 1.27))))
(number "27" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 5.08 0) (length 3.81)
(name "Pin_28" (effects (font (size 1.27 1.27))))
(number "28" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 2.54 0) (length 3.81)
(name "Pin_29" (effects (font (size 1.27 1.27))))
(number "29" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 0 0) (length 3.81)
(name "Pin_30" (effects (font (size 1.27 1.27))))
(number "30" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -2.54 0) (length 3.81)
(name "Pin_31" (effects (font (size 1.27 1.27))))
(number "31" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -5.08 0) (length 3.81)
(name "Pin_32" (effects (font (size 1.27 1.27))))
(number "32" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -7.62 0) (length 3.81)
(name "Pin_33" (effects (font (size 1.27 1.27))))
(number "33" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -10.16 0) (length 3.81)
(name "Pin_34" (effects (font (size 1.27 1.27))))
(number "34" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -12.7 0) (length 3.81)
(name "Pin_35" (effects (font (size 1.27 1.27))))
(number "35" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -15.24 0) (length 3.81)
(name "Pin_36" (effects (font (size 1.27 1.27))))
(number "36" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -17.78 0) (length 3.81)
(name "Pin_37" (effects (font (size 1.27 1.27))))
(number "37" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -20.32 0) (length 3.81)
(name "Pin_38" (effects (font (size 1.27 1.27))))
(number "38" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Connector:Conn_01x19_Female" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
(property "Reference" "J" (id 0) (at 0 25.4 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "Conn_01x19_Female" (id 1) (at 0 -25.4 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "connector" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Generic connector, single row, 01x19, script generated (kicad-library-utils/schlib/autogen/connector/)" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "Connector*:*_1x??_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "Conn_01x19_Female_1_1"
(arc (start 0 -22.352) (mid -0.508 -22.86) (end 0 -23.368)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -19.812) (mid -0.508 -20.32) (end 0 -20.828)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -17.272) (mid -0.508 -17.78) (end 0 -18.288)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -14.732) (mid -0.508 -15.24) (end 0 -15.748)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -12.192) (mid -0.508 -12.7) (end 0 -13.208)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -9.652) (mid -0.508 -10.16) (end 0 -10.668)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -7.112) (mid -0.508 -7.62) (end 0 -8.128)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -4.572) (mid -0.508 -5.08) (end 0 -5.588)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 -2.032) (mid -0.508 -2.54) (end 0 -3.048)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -22.86)
(xy -0.508 -22.86)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -20.32)
(xy -0.508 -20.32)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -17.78)
(xy -0.508 -17.78)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -15.24)
(xy -0.508 -15.24)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -12.7)
(xy -0.508 -12.7)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -10.16)
(xy -0.508 -10.16)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -7.62)
(xy -0.508 -7.62)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -5.08)
(xy -0.508 -5.08)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -2.54)
(xy -0.508 -2.54)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 0)
(xy -0.508 0)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 2.54)
(xy -0.508 2.54)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 5.08)
(xy -0.508 5.08)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 7.62)
(xy -0.508 7.62)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 10.16)
(xy -0.508 10.16)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 12.7)
(xy -0.508 12.7)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 15.24)
(xy -0.508 15.24)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 17.78)
(xy -0.508 17.78)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 20.32)
(xy -0.508 20.32)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy -1.27 22.86)
(xy -0.508 22.86)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 0.508) (mid -0.508 0) (end 0 -0.508)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 3.048) (mid -0.508 2.54) (end 0 2.032)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 5.588) (mid -0.508 5.08) (end 0 4.572)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 8.128) (mid -0.508 7.62) (end 0 7.112)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 10.668) (mid -0.508 10.16) (end 0 9.652)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 13.208) (mid -0.508 12.7) (end 0 12.192)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 15.748) (mid -0.508 15.24) (end 0 14.732)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 18.288) (mid -0.508 17.78) (end 0 17.272)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 20.828) (mid -0.508 20.32) (end 0 19.812)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(arc (start 0 23.368) (mid -0.508 22.86) (end 0 22.352)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(pin passive line (at -5.08 22.86 0) (length 3.81)
(name "Pin_1" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 0 0) (length 3.81)
(name "Pin_10" (effects (font (size 1.27 1.27))))
(number "10" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -2.54 0) (length 3.81)
(name "Pin_11" (effects (font (size 1.27 1.27))))
(number "11" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -5.08 0) (length 3.81)
(name "Pin_12" (effects (font (size 1.27 1.27))))
(number "12" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -7.62 0) (length 3.81)
(name "Pin_13" (effects (font (size 1.27 1.27))))
(number "13" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -10.16 0) (length 3.81)
(name "Pin_14" (effects (font (size 1.27 1.27))))
(number "14" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -12.7 0) (length 3.81)
(name "Pin_15" (effects (font (size 1.27 1.27))))
(number "15" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -15.24 0) (length 3.81)
(name "Pin_16" (effects (font (size 1.27 1.27))))
(number "16" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -17.78 0) (length 3.81)
(name "Pin_17" (effects (font (size 1.27 1.27))))
(number "17" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -20.32 0) (length 3.81)
(name "Pin_18" (effects (font (size 1.27 1.27))))
(number "18" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 -22.86 0) (length 3.81)
(name "Pin_19" (effects (font (size 1.27 1.27))))
(number "19" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 20.32 0) (length 3.81)
(name "Pin_2" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 17.78 0) (length 3.81)
(name "Pin_3" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 15.24 0) (length 3.81)
(name "Pin_4" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 12.7 0) (length 3.81)
(name "Pin_5" (effects (font (size 1.27 1.27))))
(number "5" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 10.16 0) (length 3.81)
(name "Pin_6" (effects (font (size 1.27 1.27))))
(number "6" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 7.62 0) (length 3.81)
(name "Pin_7" (effects (font (size 1.27 1.27))))
(number "7" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 5.08 0) (length 3.81)
(name "Pin_8" (effects (font (size 1.27 1.27))))
(number "8" (effects (font (size 1.27 1.27))))
)
(pin passive line (at -5.08 2.54 0) (length 3.81)
(name "Pin_9" (effects (font (size 1.27 1.27))))
(number "9" (effects (font (size 1.27 1.27))))
)
)
)
)
(symbol (lib_name "Conn_01x19_Female_1") (lib_id "Connector:Conn_01x19_Female") (at 125.73 85.09 0) (mirror y) (unit 1)
(in_bom yes) (on_board yes)
(uuid c3f73aed-9c37-49ab-a29b-ddda19863dc6)
(property "Reference" "J1" (id 0) (at 127 83.8199 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "Conn_01x19_Female" (id 1) (at 158.75 82.55 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 125.73 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 125.73 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "19" (uuid 18b7ab83-d859-4ae4-8bd5-390d548827e1))
(pin "20" (uuid 4621c71a-7341-4f49-98ba-fa91307e9af8))
(pin "22" (uuid a1999e16-6c12-483d-92d4-c76f6e4c5eb6))
(pin "23" (uuid 88b4d64b-2ef7-467d-944a-eea26872fcba))
(pin "24" (uuid 720bd5c0-c68e-4e57-b8b4-91fa0b699f4d))
(pin "25" (uuid 18472bc0-9d8c-4842-a947-4e6f88d01f91))
(pin "26" (uuid 2974c536-756d-4313-819f-ecbc3e0e811f))
(pin "27" (uuid 12b2b4f4-555a-4819-9a2f-a51a3decb310))
(pin "28" (uuid 733d4db4-43cf-480f-9163-e4bae6a7dae4))
(pin "29" (uuid f4b313fb-f602-4f0c-9d32-b7f20f57602e))
(pin "30" (uuid 40900843-93ea-4a83-983d-06864fa6ecb1))
(pin "31" (uuid a15a4861-8779-4dcc-9bfb-a948eef66171))
(pin "32" (uuid 51260f6e-69c6-44c2-82e0-ec8a560d01a5))
(pin "33" (uuid 62a13c38-fca7-41b7-88a0-9ce43abe97d6))
(pin "34" (uuid 132823c4-8db9-4b3e-b339-3800f854644c))
(pin "35" (uuid dc221e1a-b54a-4fb9-b2ff-9970ea608718))
(pin "36" (uuid 615bbaba-dbcc-4e6f-b776-12243a62c66f))
(pin "37" (uuid 84232a14-4b24-4618-94f7-a89361ac04dd))
(pin "38" (uuid 7623eff2-08bc-42ec-8b8b-a8eccbfa1781))
)
(symbol (lib_id "Connector:Conn_01x19_Female") (at 113.03 85.09 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid c6ee9baa-6f28-4fea-a32a-9a096e9a4527)
(property "Reference" "J1" (id 0) (at 114.3 83.8199 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "Conn_01x19_Female" (id 1) (at 77.47 78.74 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 113.03 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 113.03 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid bcf17a32-2560-45d4-a2b6-7b12c8150af9))
(pin "10" (uuid 260032a6-d20c-4263-a983-953dcb3bfdd9))
(pin "11" (uuid 01b92c57-83a7-41d4-88c2-ce9d7a2cd004))
(pin "12" (uuid 4d32dbb0-f289-4845-9f7c-0a45e006072e))
(pin "13" (uuid e5445549-6a9b-4df8-a958-f30078d54166))
(pin "14" (uuid 3dba7056-a1c9-4d38-9ede-836675e8333a))
(pin "15" (uuid 62155bec-4f4d-462d-b14a-ee75c9f38fe8))
(pin "16" (uuid 24110a28-e611-4256-9abc-b55dede0c392))
(pin "17" (uuid 2d1e34dd-fc0d-4364-96ea-68094b63eb59))
(pin "18" (uuid f2320d05-2519-4f2a-bbb6-996071d04d06))
(pin "19" (uuid 8e18f880-ce7c-4526-8933-41edbb1f3648))
(pin "2" (uuid 54af0bb8-931a-4e67-a8c4-bdcfa2bd2c10))
(pin "3" (uuid 2ca2a042-f6e1-490e-a025-2631b0df5f9a))
(pin "4" (uuid c0822d44-eedc-4b57-82e9-3133e278ce2f))
(pin "5" (uuid 69c55231-7d1f-4733-aadb-e1d3f64bd2ed))
(pin "6" (uuid 06a325cb-9027-4bdb-a1a8-1c383d5aee95))
(pin "7" (uuid 7c8b4d72-3fa7-4b27-965e-0194a3123094))
(pin "8" (uuid 0ae0f7e9-f895-40e0-8de6-2af1924b31b4))
(pin "9" (uuid 0bfb315b-847c-4f88-8d86-7206ced2cfa4))
)
(sheet_instances
(path "/" (page "1"))
)
(symbol_instances
(path "/c3f73aed-9c37-49ab-a29b-ddda19863dc6"
(reference "J1") (unit 1) (value "Conn_01x19_Female") (footprint "")
)
(path "/c6ee9baa-6f28-4fea-a32a-9a096e9a4527"
(reference "J1") (unit 1) (value "Conn_01x19_Female") (footprint "")
)
)
)

File diff suppressed because it is too large Load Diff

View File

@ -1,378 +1,131 @@
#include "ESPAsyncWebServer.h" #include <Arduino.h>
#include <WiFi.h>
#include <Wire.h> #include <Wire.h>
#include <time.h> #include <map>
#include <vector>
#include <string>
// Sensors
#include "HDC1080Sensor.h"
#include "CCS811Sensor.h"
#include "MS5611Sensor.h"
#include "BMP280Sensor.h" #include "BMP280Sensor.h"
#include "CCS811Sensor.h"
//#include "src/ESPinfluxdb.h" // https://github.com/hwwong/ESP_influxdb // 14.04.2019 #include "HDC1080Sensor.h"
#include "http_static.h" // HTTP pages and JSON request templates
// ********************** Config **********************
// DeepSleep time send data every 60 seconds
const int sleepTimeS = 60;
// WiFi Config
#define WiFi_SSID "Ischtar"
#define WiFi_Password "highfive"
// NTP conf
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 3600;
struct tm timeinfo;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Globals for HDC1080 :: Temp/Humidity
HDC1080Sensor HDC1080_sensors;
double hdc1080_temp, hdc1080_humidity;
bool hdc1080_err;
// Globals for CCS811 :: eTVOC/eCO2
CCS811Sensor CCS811_sensors;
uint16_t ccs811_eco2, ccs811_etvoc, ccs811_errstat, ccs811_raw;
// Globals for MS5611 :: Pressure/Altitude
MS5611Sensor MS5611_sensors;
double ms5611_temp, ms5611_pressure, ms5611_altitude;
// Globals for BMP280 :: Temp/Hum/Pressure
BMP280Sensor BMP280_sensors;
float bmp280_temp, bmp280_humidity, bmp280_pressure, bmp280_altitude;
// loop cycle
#define workCycle 60 //seconds
// ******************** Config End ********************
void scanI2CDevices() { std::map<ReadingType, std::map<std::string, float>> sensorStore;
byte error, address; typedef std::map<uint8_t, i2cSensor*> SensorMap;
int nDevices;
Serial.println("Scanning..."); // Declare sensors
BMP280Sensor bmp280;
CCS811Sensor ccs811;
HDC1080Sensor hdc1080;
nDevices = 0; // global values to make CCS811Sensor and HDC1080Sensor share data
for (address = 1; address < 127; address++) { double sharedTemperature = NAN;
double sharedHumidity = NAN;
// Map to store sensor instances by their I2C addresses
SensorMap i2cSensors;
// Map to store initialized sensors by their names
std::map<std::string, i2cSensor*> initializedi2cSensors;
// Function to initialize sensor store
void initSensorStore() {
for (ReadingType type : {ReadingType::Temperature, ReadingType::Humidity, ReadingType::Pressure, ReadingType::Altitude, ReadingType::eCO2, ReadingType::eTVOC, ReadingType::ErrorStatus}) {
sensorStore[type] = std::map<std::string, float>();
}
}
// Function to scan for I2C devices
std::vector<uint8_t> scanI2C() {
std::vector<uint8_t> devices;
for (uint8_t address = 1; address < 127; ++address) {
Wire.beginTransmission(address); Wire.beginTransmission(address);
error = Wire.endTransmission(); if (Wire.endTransmission() == 0) {
devices.push_back(address);
}
}
return devices;
}
if (error == 0) { void initializeSensors(const std::vector<uint8_t>& i2cDevices, bool specialInit = false) {
Serial.print("I2C device found at address 0x"); for (uint8_t address : i2cDevices) {
if (address < 16) { // Check if the address matches any known sensors
Serial.print("0"); if (i2cSensors.find(address) != i2cSensors.end()) {
} i2cSensor* sensor = i2cSensors[address];
Serial.print(address, HEX); std::string output = sensor->getName();
Serial.println(" !");
nDevices++; if (!specialInit) {
} else if (error == 4) { // First pass: skip sensors that require special initialization
Serial.print("Unknown error at address 0x"); if (sensor->getName() == "CCS811") {
if (address < 16) { continue;
Serial.print("0");
} }
Serial.println(address, HEX); output = "Regualr " + output;
// Default initialization for all other sensors
sensor->init();
} else if (sensor->getName() == "CCS811") {
output = "Special " + output;
// Initialize CCS811 with references to shared temperature and humidity
CCS811Sensor* ccs811Sensor = static_cast<CCS811Sensor*>(sensor);
ccs811Sensor->init(&sharedTemperature, &sharedHumidity);
} }
Serial.println(output.c_str());
// Store the initialized sensor
initializedi2cSensors[sensor->getName()] = sensor;
} }
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
} else {
Serial.println("done\n");
} }
} }
// ---------- HDC1080 ---------- // Main setup function
String readHDC1080Temperature() { void setup() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(hdc1080_temp)) {
Serial.println("Failed to read from HDC1080 sensor!");
return "--";
}
else {
return String(hdc1080_temp);
}
}
String readHDC1080Humidity() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(hdc1080_humidity)) {
Serial.println("Failed to read from HDC1080 sensor!");
return "--";
}
else {
return String(hdc1080_humidity);
}
}
// ---------- End HDC1080 ----------
// ---------- CCS11 ----------
String processCCS811Error(err_t errstat) {
if ( errstat == CCS811_ERRSTAT_OK_NODATA ) {
Serial.println("CCS811: waiting for (new) data");
return "loading";
} else if ( errstat & CCS811_ERRSTAT_I2CFAIL ) {
Serial.println("CCS811: I2C error");
return "i2c error";
} else {
// Serial.print("CCS811: errstat="); Serial.print(errstat, HEX);
// Serial.print("="); Serial.println( ccs811.errstat_str(errstat) );
return "error";
}
}
String readCCS811TVOC() {
if( ccs811_errstat==CCS811_ERRSTAT_OK ){
return String(ccs811_etvoc);
} else {
return processCCS811Error(ccs811_errstat);
}
}
String readCCS811ECO2() {
if( ccs811_errstat==CCS811_ERRSTAT_OK ){
return String(ccs811_eco2);
} else {
return processCCS811Error(ccs811_errstat);
}
}
// ---------- End CCS11 ----------
// ---------- MS5611 ----------
String readMS5611Temperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(ms5611_temp)) {
Serial.println("Failed to read from MS5611 sensor!");
return "--";
}
else {
return String(ms5611_temp);
}
}
String readMS5611Pressure() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(ms5611_pressure)) {
Serial.println("Failed to read from MS5611 sensor!");
return "--";
}
else {
return String(ms5611_temp);
}
}
String readMS5611Altitude() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(ms5611_altitude)) {
Serial.println("Failed to read from MS5611 sensor!");
return "--";
}
else {
return String(ms5611_altitude);
}
}
// ---------- End MS5611 ----------
// ---------- BMP280 ----------
String readBMP280Temperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_temp)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_temp);
}
}
String readBMP280Humidity() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_humidity)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_humidity);
}
}
String readBMP280Pressure() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_pressure)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_pressure);
}
}
String readBMP280Altitude() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if (isnan(bmp280_altitude)) {
Serial.println("Failed to read from BMP280 sensor!");
return "--";
}
else {
return String(bmp280_altitude);
}
}
// ---------- End BMP280 ----------
String formatISO8601() {
char timestamp[20]; // Buffer for timestamp
// Format the time into ISO 8601 format
strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
// Convert the formatted timestamp to a String object
return String(timestamp);
}
// Replaces placeholder in HTML template with real values
// SSR if you will
String processor(const String& var){
if(var == "TEMPERATURE"){
return readHDC1080Temperature();
}
else if(var == "HUMIDITY"){
return readHDC1080Humidity();
}
else if(var == "TVOC"){
return readCCS811TVOC();
}
else if(var == "ECO2"){
return readCCS811ECO2();
} else if(var == "TIMESTAMP"){
return formatISO8601();
}
return String();
}
void connectToWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(WiFi_SSID, WiFi_Password);
Serial.println();
Serial.print("Connecting to WiFi: ");
Serial.print(WiFi_SSID);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 10) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected");
Serial.print("IP address: http://");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nFailed to connect to WiFi");
// Handle connection failure, e.g., retry or reset the ESP32
}
}
void setup()
{
Serial.begin(115200); Serial.begin(115200);
delay(10);
Serial.println("");
connectToWiFi();
delay(10);
Serial.println("");
// Config NTP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
// i2c
Wire.begin(); Wire.begin();
delay(10000);
// Initialize the sensor store
initSensorStore();
// humidity and temperature // Populate the i2cSensors map
HDC1080_sensors.init(); i2cSensors[bmp280.getAddress()] = &bmp280;
// eCO2 and eTVOC, temp and humidity needed to adjust values i2cSensors[hdc1080.getAddress()] = &hdc1080;
CCS811_sensors.init(&hdc1080_temp, &hdc1080_humidity); i2cSensors[ccs811.getAddress()] = &ccs811;
// Todo add pointer to temp, we might allight Altimeter by another sens
// MS5611_sensors.init();
// humidity, temperature, pressure and altitude
BMP280_sensors.init();
// Pages and JSONs // Scan for I2C devices
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ std::vector<uint8_t> i2cDevices = scanI2C();
request->send_P(200, "text/html", http_static::index_html, processor);
});
// Deprecated // First pass: Initialize all sensors with default init()
server.on("/api/sensors.json", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println("First initialization pass...");
request->send_P(200, "text/html", http_static::sensor_things_resp, processor); initializeSensors(i2cDevices, false);
});
// DEPRECATED lightweight named endpoints // Optionally, wait or perform some task to allow initial data collection
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){ delay(5000); // Adjust delay as necessary
request->send_P(200, "text/plain", readHDC1080Temperature().c_str());
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readHDC1080Humidity().c_str());
});
server.on("/tvoc", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readCCS811TVOC().c_str());
});
server.on("/eco2", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readCCS811ECO2().c_str());
});
// For prometheus scrapping. to be deprecated as well // Second pass: Re-initialize sensors with special requirements
server.on("/metrics", HTTP_GET, [](AsyncWebServerRequest *request) { Serial.println("Second initialization pass...");
String response = "hdc1080_temperature " + String(readHDC1080Temperature()) + "\n"; initializeSensors(i2cDevices, true);
response += "hdc1080_humidity " + String(readHDC1080Humidity()) + "\n";
response += "ccs811_tvoc " + String(readCCS811TVOC()) + "\n";
response += "ccs811_eco2 " + String(readCCS811ECO2()) + "\n";
response += "bmp280_temperature " + String(readBMP280Temperature()) + "\n";
response += "bmp280_humidity " + String(readBMP280Humidity()) + "\n";
response += "bmp280_pressure " + String(readBMP280Pressure()) + "\n";
response += "bmp280_altitude " + String(readBMP280Altitude()) + "\n";
request->send(200, "text/plain", response);
});
// Start server
server.begin();
} }
void loop() // Main loop function
{ void loop() {
if (WiFi.status() != WL_CONNECTED) { // Example: Read and store values asynchronously
Serial.println("WiFi connection lost. Reconnecting..."); for (auto& sensorPair : initializedi2cSensors) {
connectToWiFi(); i2cSensor* sensor = sensorPair.second;
for (ReadingType feature : sensor->getFeatures()) {
float value = sensor->readValue(feature);
sensorStore[feature][sensor->getName()] = value;
// Update shared variables if HDC1080 is read
if (sensor->getName() == "HDC1080 Sensor") {
if (feature == ReadingType::Temperature) {
sharedTemperature = static_cast<double>(value);
} else if (feature == ReadingType::Humidity) {
sharedHumidity = static_cast<double>(value);
}
} }
if(!getLocalTime(&timeinfo)){ std::string output = sensor->getName() + " " + readingTypeToString(feature) + ": " + std::to_string(value);
Serial.println("Failed to obtain time"); Serial.println(output.c_str());
return;
} }
scanI2CDevices(); }
Serial.print(&timeinfo, "[%M-%d-%Y--%H:%M:%S]: ");
delay(20000); // Delay between readings
HDC1080_sensors.read_values(&hdc1080_temp, &hdc1080_humidity, &hdc1080_err);
CCS811_sensors.read_values(&ccs811_eco2, &ccs811_etvoc, &ccs811_errstat, &ccs811_raw);
BMP280_sensors.read_values(&bmp280_temp, &bmp280_humidity, &bmp280_pressure, &bmp280_altitude);
Serial.print("T=");
Serial.print(readHDC1080Temperature());
Serial.print(" / ");
Serial.print(readBMP280Temperature());
Serial.print(" °C ");
Serial.print("H=");
Serial.print(readHDC1080Humidity());
Serial.print(" / ");
Serial.print(readBMP280Humidity());
Serial.print(" % ");
Serial.print("eco2="); Serial.print(readCCS811ECO2()); Serial.print(" ppm ");
Serial.print("etvoc="); Serial.print(readCCS811TVOC()); Serial.print(" ppb ");
Serial.print("pressure="); Serial.print(readBMP280Pressure()); Serial.print(" Pa ");
Serial.print("alt="); Serial.print(readBMP280Altitude()); Serial.print(" m ");
Serial.println("");
// Wait
delay(workCycle*1000);
} }

View File

@ -1,16 +1,21 @@
// BMP280Sensor.cpp
#include "BMP280Sensor.h" #include "BMP280Sensor.h"
BMP280Sensor::BMP280Sensor(uint8_t address) : _address(address) { // Constructor sets the I2C address
// Constructor sets the address BMP280Sensor::BMP280Sensor(uint8_t address) {
i2c_address = address; // Set the i2c_address from the base class
} }
// Initialize the BMP280 sensor
void BMP280Sensor::init() { void BMP280Sensor::init() {
// Enable BMP280 // Begin communication with the sensor
bool ok = bmp280.begin(_address); bool ok = bmp280.begin(i2c_address);
/* weather monitoring settings from driver lib */ if (!ok) {
// Handle initialization error
// In a real application, you might want to log this error or retry
}
// Set the sensor to forced mode with basic sampling settings
bmp280.setSampling(Adafruit_BME280::MODE_FORCED, bmp280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // temperature Adafruit_BME280::SAMPLING_X1, // temperature
Adafruit_BME280::SAMPLING_X1, // pressure Adafruit_BME280::SAMPLING_X1, // pressure
@ -18,13 +23,31 @@ void BMP280Sensor::init() {
Adafruit_BME280::FILTER_OFF); Adafruit_BME280::FILTER_OFF);
} }
// Return the name of the sensor
void BMP280Sensor::read_values(float* temperature, float* humidity, float* pressure, float* altitude) { std::string BMP280Sensor::getName() const {
// Only needed in forced mode! In normal mode, you can remove the next line. return "BMP280";
bmp280.takeForcedMeasurement(); // has no effect in normal mode }
if (humidity) *humidity = bmp280.readHumidity(); // Return a list of features the sensor can read
if (temperature) *temperature = bmp280.readTemperature(); std::vector<ReadingType> BMP280Sensor::getFeatures() const {
if (pressure) *pressure = bmp280.readPressure() / 100.0F; return {ReadingType::Temperature, ReadingType::Humidity, ReadingType::Pressure, ReadingType::Altitude};
if (altitude) *altitude = bmp280.readAltitude(SEALEVELPRESSURE_HPA); }
// Read the value of a specified feature
float BMP280Sensor::readValue(ReadingType feature) {
// Take a measurement in forced mode
bmp280.takeForcedMeasurement();
switch (feature) {
case ReadingType::Temperature:
return bmp280.readTemperature();
case ReadingType::Humidity:
return bmp280.readHumidity();
case ReadingType::Pressure:
return bmp280.readPressure() / 100.0F; // Convert to hPa
case ReadingType::Altitude:
return bmp280.readAltitude(SEALEVELPRESSURE_HPA);
default:
return NAN; // Return NaN for unsupported features
}
} }

View File

@ -1,31 +1,54 @@
// CCS811Sensor.cpp
#include "CCS811Sensor.h" #include "CCS811Sensor.h"
CCS811Sensor::CCS811Sensor(uint8_t wakePin) : _wakePin(wakePin), ccs811(wakePin) { CCS811Sensor::CCS811Sensor(uint8_t wakePin)
// Constructor sets the wake pin and initializes the ccs811 object : wakePin_(wakePin), ccs811_(wakePin), temperaturePtr_(nullptr), humidityPtr_(nullptr) {
} i2c_address = 0x5A; // Default I2C address for CCS811
void CCS811Sensor::init(double* temperature, double* humidity) {
// Enable CCS811
bool ok = ccs811.begin();
// let's handle if not OK later
// Lock pointers to temperature and humidity values
ok = ccs811.start(CCS811_MODE_1SEC);
// if( !ok ) Serial.println("setup: CCS811 start FAILED");
_temperaturePtr = temperature;
_humidityPtr = humidity;
} }
void CCS811Sensor::init() { void CCS811Sensor::init() {
bool ok = ccs811.begin(); init(nullptr, nullptr);
} }
void CCS811Sensor::read_values(uint16_t* eco2, uint16_t* etvoc, uint16_t* errstat, uint16_t* raw) { void CCS811Sensor::init(double* temperature, double* humidity) {
if (_temperaturePtr && _humidityPtr) { bool ok = ccs811_.begin();
// Set environmental data for CCS811 sensor using pointers if (!ok) {
ccs811.set_envdata(*_temperaturePtr, *_humidityPtr); // Serial.println("CCS811 initialization failed");
return;
}
ok = ccs811_.start(CCS811_MODE_1SEC);
if (!ok) {
// Serial.println("CCS811 start failed");
return;
}
temperaturePtr_ = temperature;
humidityPtr_ = humidity;
}
std::string CCS811Sensor::getName() const {
return "CCS811";
}
std::vector<ReadingType> CCS811Sensor::getFeatures() const {
return {ReadingType::eCO2, ReadingType::eTVOC, ReadingType::ErrorStatus};
}
float CCS811Sensor::readValue(ReadingType feature) {
uint16_t eco2, etvoc, errstat, raw;
if (temperaturePtr_ && humidityPtr_) {
ccs811_.set_envdata(*temperaturePtr_, *humidityPtr_);
}
ccs811_.read(&eco2, &etvoc, &errstat, &raw);
switch (feature) {
case ReadingType::eCO2:
return static_cast<float>(eco2);
case ReadingType::eTVOC:
return static_cast<float>(etvoc);
case ReadingType::ErrorStatus:
return static_cast<float>(errstat);
default:
return NAN; // Return NaN for unsupported features
} }
// Read eCO2, eTVOC, error status, and raw data values from CCS811 sensor
ccs811.read(eco2, etvoc, errstat, raw);
} }

View File

@ -1,19 +1,28 @@
// HDC1080Sensor.cpp
#include "HDC1080Sensor.h" #include "HDC1080Sensor.h"
HDC1080Sensor::HDC1080Sensor(uint8_t address) : _address(address) { HDC1080Sensor::HDC1080Sensor(uint8_t address) {
// Constructor sets the address i2c_address = address; // Set the I2C address from the base class
} }
void HDC1080Sensor::init() { void HDC1080Sensor::init() {
hdc1080.begin(_address); // Initialize HDC1080 sensor with the specified address hdc1080_.begin(i2c_address); // Initialize HDC1080 sensor with the specified address
} }
void HDC1080Sensor::read_values(double* temperature, double* humidity, bool* success) { std::string HDC1080Sensor::getName() const {
if (temperature) *temperature = hdc1080.readTemperature(); return "HDC1080";
if (humidity) *humidity = hdc1080.readHumidity(); }
// Set success flag based on whether readings were successful std::vector<ReadingType> HDC1080Sensor::getFeatures() const {
if (success) *success = !isnan(*temperature) && !isnan(*humidity); return {ReadingType::Temperature, ReadingType::Humidity};
}
float HDC1080Sensor::readValue(ReadingType feature) {
switch (feature) {
case ReadingType::Temperature:
return hdc1080_.readTemperature();
case ReadingType::Humidity:
return hdc1080_.readHumidity();
default:
return NAN; // Return NaN for unsupported features
}
} }