ESPHome  2024.4.1
mics_4514.cpp
Go to the documentation of this file.
1 #include "mics_4514.h"
2 
3 #include "esphome/core/helpers.h"
4 #include "esphome/core/log.h"
5 
6 namespace esphome {
7 namespace mics_4514 {
8 
9 static const char *const TAG = "mics_4514";
10 
11 static const uint8_t SENSOR_REGISTER = 0x04;
12 static const uint8_t POWER_MODE_REGISTER = 0x0a;
13 
15  ESP_LOGCONFIG(TAG, "Setting up MICS 4514...");
16  uint8_t power_mode;
17  this->read_register(POWER_MODE_REGISTER, &power_mode, 1);
18  if (power_mode == 0x00) {
19  ESP_LOGCONFIG(TAG, "Waking up MICS 4514, sensors will have data after 3 minutes...");
20  power_mode = 0x01;
21  this->write_register(POWER_MODE_REGISTER, &power_mode, 1);
22  delay(100); // NOLINT
23  this->set_timeout("warmup", 3 * 60 * 1000, [this]() {
24  this->warmed_up_ = true;
25  ESP_LOGCONFIG(TAG, "MICS 4514 setup complete.");
26  });
27  this->status_set_warning();
28  return;
29  }
30  ESP_LOGCONFIG(TAG, "Device already awake.");
31  this->warmed_up_ = true;
32  ESP_LOGCONFIG(TAG, "MICS 4514 setup complete.");
33 }
34 void MICS4514Component::dump_config() {
35  ESP_LOGCONFIG(TAG, "MICS 4514:");
36  LOG_I2C_DEVICE(this);
37  LOG_UPDATE_INTERVAL(this);
38  LOG_SENSOR(" ", "Nitrogen Dioxide", this->nitrogen_dioxide_sensor_);
39  LOG_SENSOR(" ", "Carbon Monoxide", this->carbon_monoxide_sensor_);
40  LOG_SENSOR(" ", "Methane", this->methane_sensor_);
41  LOG_SENSOR(" ", "Ethanol", this->ethanol_sensor_);
42  LOG_SENSOR(" ", "Hydrogen", this->hydrogen_sensor_);
43  LOG_SENSOR(" ", "Ammonia", this->ammonia_sensor_);
44 }
45 float MICS4514Component::get_setup_priority() const { return setup_priority::DATA; }
46 void MICS4514Component::update() {
47  if (!this->warmed_up_) {
48  return;
49  }
50  uint8_t data[6];
51  if (this->read_register(SENSOR_REGISTER, data, 6) != i2c::ERROR_OK) {
52  this->status_set_warning();
53  return;
54  }
55  this->status_clear_warning();
56  ESP_LOGV(TAG, "Got data: %02X %02X %02X %02X %02X %02X", data[0], data[1], data[2], data[3], data[4], data[5]);
57  uint16_t ox = encode_uint16(data[0], data[1]);
58  uint16_t red = encode_uint16(data[2], data[3]);
59  uint16_t power = encode_uint16(data[4], data[5]);
60 
61  if (this->initial_) {
62  this->initial_ = false;
63  this->ox_calibration_ = (float) (power - ox);
64  this->red_calibration_ = (float) (power - red);
65  return;
66  }
67 
68  float red_f = (float) (power - red) / this->red_calibration_;
69  float ox_f = (float) (power - ox) / this->ox_calibration_;
70 
71  if (this->carbon_monoxide_sensor_ != nullptr) {
72  float co = 0.0f;
73  if (red_f <= 0.425f) {
74  co = (0.425f - red_f) / 0.000405f;
75  if (co < 1.0f)
76  co = 0.0f;
77  if (co > 1000.0f)
78  co = 1000.0f;
79  }
80  this->carbon_monoxide_sensor_->publish_state(co);
81  }
82 
83  if (this->nitrogen_dioxide_sensor_ != nullptr) {
84  float nitrogendioxide = 0.0f;
85  if (ox_f >= 1.1f) {
86  nitrogendioxide = (ox_f - 0.045f) / 6.13f;
87  if (nitrogendioxide < 0.1f)
88  nitrogendioxide = 0.0f;
89  if (nitrogendioxide > 10.0f)
90  nitrogendioxide = 10.0f;
91  }
92  this->nitrogen_dioxide_sensor_->publish_state(nitrogendioxide);
93  }
94 
95  if (this->methane_sensor_ != nullptr) {
96  float methane = 0.0f;
97  if (red_f <= 0.786f) {
98  methane = (0.786f - red_f) / 0.000023f;
99  if (methane < 1000.0f)
100  methane = 0.0f;
101  if (methane > 25000.0f)
102  methane = 25000.0f;
103  }
104  this->methane_sensor_->publish_state(methane);
105  }
106 
107  if (this->ethanol_sensor_ != nullptr) {
108  float ethanol = 0.0f;
109  if (red_f <= 0.306f) {
110  ethanol = (0.306f - red_f) / 0.00057f;
111  if (ethanol < 10.0f)
112  ethanol = 0.0f;
113  if (ethanol > 500.0f)
114  ethanol = 500.0f;
115  }
116  this->ethanol_sensor_->publish_state(ethanol);
117  }
118 
119  if (this->hydrogen_sensor_ != nullptr) {
120  float hydrogen = 0.0f;
121  if (red_f <= 0.279f) {
122  hydrogen = (0.279f - red_f) / 0.00026f;
123  if (hydrogen < 1.0f)
124  hydrogen = 0.0f;
125  if (hydrogen > 1000.0f)
126  hydrogen = 1000.0f;
127  }
128  this->hydrogen_sensor_->publish_state(hydrogen);
129  }
130 
131  if (this->ammonia_sensor_ != nullptr) {
132  float ammonia = 0.0f;
133  if (red_f <= 0.8f) {
134  ammonia = (0.8f - red_f) / 0.0015f;
135  if (ammonia < 1.0f)
136  ammonia = 0.0f;
137  if (ammonia > 500.0f)
138  ammonia = 500.0f;
139  }
140  this->ammonia_sensor_->publish_state(ammonia);
141  }
142 }
143 
144 } // namespace mics_4514
145 } // namespace esphome
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:19
ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
Definition: i2c.cpp:10
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
uint8_t power_mode
Definition: qmp6988.h:70
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition: component.cpp:69
virtual void setup()
Where the component&#39;s initialization should happen.
Definition: component.cpp:48
No error found during execution of method.
Definition: i2c_bus.h:13
void status_clear_warning()
Definition: component.cpp:166
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
Definition: helpers.h:182
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a specific register in the I²C device
Definition: i2c.cpp:25
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26