ESPHome  2023.5.5
mhz19.cpp
Go to the documentation of this file.
1 #include "mhz19.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace mhz19 {
6 
7 static const char *const TAG = "mhz19";
8 static const uint8_t MHZ19_REQUEST_LENGTH = 8;
9 static const uint8_t MHZ19_RESPONSE_LENGTH = 9;
10 static const uint8_t MHZ19_COMMAND_GET_PPM[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00};
11 static const uint8_t MHZ19_COMMAND_ABC_ENABLE[] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00};
12 static const uint8_t MHZ19_COMMAND_ABC_DISABLE[] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00};
13 static const uint8_t MHZ19_COMMAND_CALIBRATE_ZERO[] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00};
14 
15 uint8_t mhz19_checksum(const uint8_t *command) {
16  uint8_t sum = 0;
17  for (uint8_t i = 1; i < MHZ19_REQUEST_LENGTH; i++) {
18  sum += command[i];
19  }
20  return 0xFF - sum + 0x01;
21 }
22 
24  if (this->abc_boot_logic_ == MHZ19_ABC_ENABLED) {
25  this->abc_enable();
26  } else if (this->abc_boot_logic_ == MHZ19_ABC_DISABLED) {
27  this->abc_disable();
28  }
29 }
30 
32  uint8_t response[MHZ19_RESPONSE_LENGTH];
33  if (!this->mhz19_write_command_(MHZ19_COMMAND_GET_PPM, response)) {
34  ESP_LOGW(TAG, "Reading data from MHZ19 failed!");
35  this->status_set_warning();
36  return;
37  }
38 
39  if (response[0] != 0xFF || response[1] != 0x86) {
40  ESP_LOGW(TAG, "Invalid preamble from MHZ19!");
41  this->status_set_warning();
42  return;
43  }
44 
45  uint8_t checksum = mhz19_checksum(response);
46  if (response[8] != checksum) {
47  ESP_LOGW(TAG, "MHZ19 Checksum doesn't match: 0x%02X!=0x%02X", response[8], checksum);
48  this->status_set_warning();
49  return;
50  }
51 
52  this->status_clear_warning();
53  const uint16_t ppm = (uint16_t(response[2]) << 8) | response[3];
54  const int temp = int(response[4]) - 40;
55  const uint8_t status = response[5];
56 
57  ESP_LOGD(TAG, "MHZ19 Received CO₂=%uppm Temperature=%d°C Status=0x%02X", ppm, temp, status);
58  if (this->co2_sensor_ != nullptr)
59  this->co2_sensor_->publish_state(ppm);
60  if (this->temperature_sensor_ != nullptr)
62 }
63 
65  ESP_LOGD(TAG, "MHZ19 Calibrating zero point");
66  this->mhz19_write_command_(MHZ19_COMMAND_CALIBRATE_ZERO, nullptr);
67 }
68 
70  ESP_LOGD(TAG, "MHZ19 Enabling automatic baseline calibration");
71  this->mhz19_write_command_(MHZ19_COMMAND_ABC_ENABLE, nullptr);
72 }
73 
75  ESP_LOGD(TAG, "MHZ19 Disabling automatic baseline calibration");
76  this->mhz19_write_command_(MHZ19_COMMAND_ABC_DISABLE, nullptr);
77 }
78 
79 bool MHZ19Component::mhz19_write_command_(const uint8_t *command, uint8_t *response) {
80  // Empty RX Buffer
81  while (this->available())
82  this->read();
83  this->write_array(command, MHZ19_REQUEST_LENGTH);
84  this->write_byte(mhz19_checksum(command));
85  this->flush();
86 
87  if (response == nullptr)
88  return true;
89 
90  return this->read_array(response, MHZ19_RESPONSE_LENGTH);
91 }
94  ESP_LOGCONFIG(TAG, "MH-Z19:");
95  LOG_SENSOR(" ", "CO2", this->co2_sensor_);
96  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
97  this->check_uart_settings(9600);
98 
99  if (this->abc_boot_logic_ == MHZ19_ABC_ENABLED) {
100  ESP_LOGCONFIG(TAG, " Automatic baseline calibration enabled on boot");
101  } else if (this->abc_boot_logic_ == MHZ19_ABC_DISABLED) {
102  ESP_LOGCONFIG(TAG, " Automatic baseline calibration disabled on boot");
103  }
104 }
105 
106 } // namespace mhz19
107 } // namespace esphome
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:18
void update() override
Definition: mhz19.cpp:31
optional< std::array< uint8_t, N > > read_array()
Definition: uart.h:33
void write_array(const uint8_t *data, size_t len)
Definition: uart.h:21
void write_byte(uint8_t data)
Definition: uart.h:19
sensor::Sensor * temperature_sensor_
Definition: mhz19.h:32
sensor::Sensor * co2_sensor_
Definition: mhz19.h:33
void check_uart_settings(uint32_t baud_rate, uint8_t stop_bits=1, UARTParityOptions parity=UART_CONFIG_PARITY_NONE, uint8_t data_bits=8)
Check that the configuration of the UART bus matches the provided values and otherwise print a warnin...
Definition: uart.cpp:12
void status_clear_warning()
Definition: component.cpp:153
void dump_config() override
Definition: mhz19.cpp:93
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
bool mhz19_write_command_(const uint8_t *command, uint8_t *response)
Definition: mhz19.cpp:79
uint8_t checksum
Definition: bl0939.h:35
void status_set_warning()
Definition: component.cpp:145
void setup() override
Definition: mhz19.cpp:23
uint8_t status
Definition: bl0942.h:23
Definition: a4988.cpp:4
MHZ19ABCLogic abc_boot_logic_
Definition: mhz19.h:34
float get_setup_priority() const override
Definition: mhz19.cpp:92
uint8_t mhz19_checksum(const uint8_t *command)
Definition: mhz19.cpp:15