10static const uint8_t COUNT_PAYLOAD_BYTES = 28;
11static const uint8_t COUNT_PAYLOAD_LENGTH_BYTES = 2;
12static const uint8_t COUNT_START_CHARACTER_BYTES = 2;
13static const uint8_t COUNT_DATA_BYTES = COUNT_START_CHARACTER_BYTES + COUNT_PAYLOAD_LENGTH_BYTES + COUNT_PAYLOAD_BYTES;
14static const uint8_t CHECKSUM_START_INDEX = COUNT_DATA_BYTES - 2;
15static const uint8_t COUNT_16_BIT_VALUES = (COUNT_PAYLOAD_LENGTH_BYTES + COUNT_PAYLOAD_BYTES) / 2;
16static const uint8_t START_CHARACTER_1 = 0x42;
17static const uint8_t START_CHARACTER_2 = 0x4D;
24static const uint32_t READY_TIMEOUT_MS = 3000;
27static const uint32_t READY_POLL_INTERVAL_MS = 100;
40 buffer[1] == START_CHARACTER_2) {
41 ESP_LOGD(TAG,
"PMSA003I is ready");
46 if (
millis() - start_time < READY_TIMEOUT_MS) {
54 ESP_LOGCONFIG(TAG,
"PMSA003I:");
61 bool successful_read = this->
read_data_(&data);
64 if (successful_read) {
66 ESP_LOGV(TAG,
"Read success. Updating sensors.");
98 ESP_LOGV(TAG,
"Read failure. Skipping update.");
103 uint8_t
buffer[COUNT_DATA_BYTES];
107 ESP_LOGW(TAG,
"I2C error %d", error);
114 if (
buffer[0] != START_CHARACTER_1 ||
buffer[1] != START_CHARACTER_2) {
115 ESP_LOGW(TAG,
"Start character mismatch: %02X %02X != %02X %02X",
buffer[0],
buffer[1], START_CHARACTER_1,
121 if (payload_length != COUNT_PAYLOAD_BYTES) {
122 ESP_LOGW(TAG,
"Payload length mismatch: %u != %u", payload_length, COUNT_PAYLOAD_BYTES);
131 ESP_LOGW(TAG,
"Checksum mismatch: %u != %u",
checksum, check);
136 uint16_t buffer_u16[COUNT_16_BIT_VALUES];
137 for (uint8_t i = 0; i < COUNT_16_BIT_VALUES; i++) {
138 const uint8_t buffer_index = COUNT_START_CHARACTER_BYTES + i * 2;
143 memcpy((
void *) data, (
void *) buffer_u16, COUNT_16_BIT_VALUES * 2);
void mark_failed()
Mark this component as failed.
void status_set_warning()
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void status_clear_warning()
ErrorCode read(uint8_t *data, size_t len) const
reads an array of bytes from the device using an I2CBus
sensor::Sensor * pmc_0_5_sensor_
sensor::Sensor * pmc_1_0_sensor_
sensor::Sensor * pm_1_0_sensor_
sensor::Sensor * pmc_5_0_sensor_
void poll_until_ready_or_timeout_(uint32_t start_time)
sensor::Sensor * pmc_10_0_sensor_
void dump_config() override
sensor::Sensor * pmc_0_3_sensor_
sensor::Sensor * pmc_2_5_sensor_
sensor::Sensor * pm_2_5_sensor_
sensor::Sensor * pm_10_0_sensor_
bool read_data_(PM25AQIData *data)
void publish_state(float state)
Publish a new state to the front-end.
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
@ ERROR_OK
No error found during execution of method.
ESPHOME_LOG_TAG(TAG, "pmsa003i")
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
uint32_t IRAM_ATTR HOT millis()
constexpr uint16_t sum16_bytes(const uint8_t *data, size_t len, uint16_t sum=0)
Add up the bytes of data with size len, truncated to 16 bits.
! Structure holding Plantower's standard packet
uint16_t particles_50um
5.0um Particle Count
uint16_t pm25_standard
Standard PM2.5.
uint16_t pm10_env
Environmental PM1.0.
uint16_t particles_25um
2.5um Particle Count
uint16_t pm100_env
Environmental PM10.0.
uint16_t particles_03um
0.3um Particle Count
uint16_t particles_05um
0.5um Particle Count
uint16_t particles_10um
1.0um Particle Count
uint16_t particles_100um
10.0um Particle Count
uint16_t pm10_standard
Standard PM1.0.
uint16_t pm25_env
Environmental PM2.5.
uint16_t pm100_standard
Standard PM10.0.