ESPHome 2025.6.2
Loading...
Searching...
No Matches
cm1106.cpp
Go to the documentation of this file.
1#include "cm1106.h"
2#include "esphome/core/log.h"
3
4#include <cinttypes>
5
6namespace esphome {
7namespace cm1106 {
8
9static const char *const TAG = "cm1106";
10static const uint8_t C_M1106_CMD_GET_CO2[4] = {0x11, 0x01, 0x01, 0xED};
11static const uint8_t C_M1106_CMD_SET_CO2_CALIB[6] = {0x11, 0x03, 0x03, 0x00, 0x00, 0x00};
12static const uint8_t C_M1106_CMD_SET_CO2_CALIB_RESPONSE[4] = {0x16, 0x01, 0x03, 0xE6};
13
14uint8_t cm1106_checksum(const uint8_t *response, size_t len) {
15 uint8_t crc = 0;
16 for (int i = 0; i < len - 1; i++) {
17 crc -= response[i];
18 }
19 return crc;
20}
21
23 ESP_LOGCONFIG(TAG, "Running setup");
24 uint8_t response[8] = {0};
25 if (!this->cm1106_write_command_(C_M1106_CMD_GET_CO2, sizeof(C_M1106_CMD_GET_CO2), response, sizeof(response))) {
26 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
27 this->mark_failed();
28 return;
29 }
30}
31
33 uint8_t response[8] = {0};
34 if (!this->cm1106_write_command_(C_M1106_CMD_GET_CO2, sizeof(C_M1106_CMD_GET_CO2), response, sizeof(response))) {
35 ESP_LOGW(TAG, "Reading data from CM1106 failed!");
36 this->status_set_warning();
37 return;
38 }
39
40 if (response[0] != 0x16 || response[1] != 0x05 || response[2] != 0x01) {
41 ESP_LOGW(TAG, "Got wrong UART response from CM1106: %02X %02X %02X %02X", response[0], response[1], response[2],
42 response[3]);
43 this->status_set_warning();
44 return;
45 }
46
47 uint8_t checksum = cm1106_checksum(response, sizeof(response));
48 if (response[7] != checksum) {
49 ESP_LOGW(TAG, "CM1106 Checksum doesn't match: 0x%02X!=0x%02X", response[7], checksum);
50 this->status_set_warning();
51 return;
52 }
53
55
56 uint16_t ppm = response[3] << 8 | response[4];
57 ESP_LOGD(TAG, "CM1106 Received CO₂=%uppm DF3=%02X DF4=%02X", ppm, response[5], response[6]);
58 if (this->co2_sensor_ != nullptr)
59 this->co2_sensor_->publish_state(ppm);
60}
61
63 uint8_t cmd[6];
64 memcpy(cmd, C_M1106_CMD_SET_CO2_CALIB, sizeof(cmd));
65 cmd[3] = ppm >> 8;
66 cmd[4] = ppm & 0xFF;
67 uint8_t response[4] = {0};
68
69 if (!this->cm1106_write_command_(cmd, sizeof(cmd), response, sizeof(response))) {
70 ESP_LOGW(TAG, "Reading data from CM1106 failed!");
71 this->status_set_warning();
72 return;
73 }
74
75 // check if correct response received
76 if (memcmp(response, C_M1106_CMD_SET_CO2_CALIB_RESPONSE, sizeof(response)) != 0) {
77 ESP_LOGW(TAG, "Got wrong UART response from CM1106: %02X %02X %02X %02X", response[0], response[1], response[2],
78 response[3]);
79 this->status_set_warning();
80 return;
81 }
82
84 ESP_LOGD(TAG, "CM1106 Successfully calibrated sensor to %uppm", ppm);
85}
86
87bool CM1106Component::cm1106_write_command_(const uint8_t *command, size_t command_len, uint8_t *response,
88 size_t response_len) {
89 // Empty RX Buffer
90 while (this->available())
91 this->read();
92 this->write_array(command, command_len - 1);
93 this->write_byte(cm1106_checksum(command, command_len));
94 this->flush();
95
96 if (response == nullptr)
97 return true;
98
99 return this->read_array(response, response_len);
100}
101
103 ESP_LOGCONFIG(TAG, "CM1106:");
104 LOG_SENSOR(" ", "CO2", this->co2_sensor_);
105 this->check_uart_settings(9600);
106 if (this->is_failed()) {
107 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
108 }
109}
110
111} // namespace cm1106
112} // namespace esphome
uint8_t checksum
Definition bl0906.h:3
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message="unspecified")
void status_clear_warning()
void calibrate_zero(uint16_t ppm)
Definition cm1106.cpp:62
bool cm1106_write_command_(const uint8_t *command, size_t command_len, uint8_t *response, size_t response_len)
Definition cm1106.cpp:87
sensor::Sensor * co2_sensor_
Definition cm1106.h:24
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
optional< std::array< uint8_t, N > > read_array()
Definition uart.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:13
void write_byte(uint8_t data)
Definition uart.h:19
void write_array(const uint8_t *data, size_t len)
Definition uart.h:21
uint8_t cm1106_checksum(const uint8_t *response, size_t len)
Definition cm1106.cpp:14
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:302