ESPHome 2025.5.0
Loading...
Searching...
No Matches
pm1006.cpp
Go to the documentation of this file.
1#include "pm1006.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace pm1006 {
6
7static const char *const TAG = "pm1006";
8
9static const uint8_t PM1006_RESPONSE_HEADER[] = {0x16, 0x11, 0x0B};
10static const uint8_t PM1006_REQUEST[] = {0x11, 0x02, 0x0B, 0x01, 0xE1};
11
13 // because this implementation is currently rx-only, there is nothing to setup
14}
15
17 ESP_LOGCONFIG(TAG, "PM1006:");
18 LOG_SENSOR(" ", "PM2.5", this->pm_2_5_sensor_);
19 LOG_UPDATE_INTERVAL(this);
20 this->check_uart_settings(9600);
21}
22
24 ESP_LOGV(TAG, "sending measurement request");
25 this->write_array(PM1006_REQUEST, sizeof(PM1006_REQUEST));
26}
27
29 while (this->available() != 0) {
30 this->read_byte(&this->data_[this->data_index_]);
31 auto check = this->check_byte_();
32 if (!check.has_value()) {
33 // finished
34 this->parse_data_();
35 this->data_index_ = 0;
36 } else if (!*check) {
37 // wrong data
38 ESP_LOGV(TAG, "Byte %i of received data frame is invalid.", this->data_index_);
39 this->data_index_ = 0;
40 } else {
41 // next byte
42 this->data_index_++;
43 }
44 }
45}
46
48
49uint8_t PM1006Component::pm1006_checksum_(const uint8_t *command_data, uint8_t length) const {
50 uint8_t sum = 0;
51 for (uint8_t i = 0; i < length; i++) {
52 sum += command_data[i];
53 }
54 return sum;
55}
56
58 uint8_t index = this->data_index_;
59 uint8_t byte = this->data_[index];
60
61 // index 0..2 are the fixed header
62 if (index < sizeof(PM1006_RESPONSE_HEADER)) {
63 return byte == PM1006_RESPONSE_HEADER[index];
64 }
65
66 // just some additional notes here:
67 // index 3..4 is unused
68 // index 5..6 is our PM2.5 reading (3..6 is called DF1-DF4 in the datasheet at
69 // http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf
70 // that datasheet goes on up to DF16, which is unused for PM1006 but used in PM1006K
71 // so this code should be trivially extensible to support that one later
72 if (index < (sizeof(PM1006_RESPONSE_HEADER) + 16))
73 return true;
74
75 // checksum
76 if (index == (sizeof(PM1006_RESPONSE_HEADER) + 16)) {
77 uint8_t checksum = pm1006_checksum_(this->data_, sizeof(PM1006_RESPONSE_HEADER) + 17);
78 if (checksum != 0) {
79 ESP_LOGW(TAG, "PM1006 checksum is wrong: %02x, expected zero", checksum);
80 return false;
81 }
82 return {};
83 }
84
85 return false;
86}
87
89 const int pm_2_5_concentration = this->get_16_bit_uint_(5);
90
91 ESP_LOGD(TAG, "Got PM2.5 Concentration: %d µg/m³", pm_2_5_concentration);
92
93 if (this->pm_2_5_sensor_ != nullptr) {
94 this->pm_2_5_sensor_->publish_state(pm_2_5_concentration);
95 }
96}
97
98uint16_t PM1006Component::get_16_bit_uint_(uint8_t start_index) const {
99 return encode_uint16(this->data_[start_index], this->data_[start_index + 1]);
100}
101
102} // namespace pm1006
103} // namespace esphome
uint8_t checksum
Definition bl0906.h:3
uint8_t pm1006_checksum_(const uint8_t *command_data, uint8_t length) const
Definition pm1006.cpp:49
float get_setup_priority() const override
Definition pm1006.cpp:47
uint16_t get_16_bit_uint_(uint8_t start_index) const
Definition pm1006.cpp:98
sensor::Sensor * pm_2_5_sensor_
Definition pm1006.h:28
optional< bool > check_byte_() const
Definition pm1006.cpp:57
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
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
bool read_byte(uint8_t *data)
Definition uart.h:29
void write_array(const uint8_t *data, size_t len)
Definition uart.h:21
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:19
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
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:191
uint16_t length
Definition tt21100.cpp:0