ESPHome  2022.12.8
am2320.cpp
Go to the documentation of this file.
1 // Implementation based on:
2 // - ESPEasy: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P034_DHT12.ino
3 // - DHT12_sensor_library: https://github.com/xreef/DHT12_sensor_library/blob/master/DHT12.cpp
4 // - Arduino - AM2320: https://github.com/EngDial/AM2320/blob/master/src/AM2320.cpp
5 
6 #include "am2320.h"
7 #include "esphome/core/hal.h"
8 #include "esphome/core/helpers.h"
9 #include "esphome/core/log.h"
10 
11 namespace esphome {
12 namespace am2320 {
13 
14 static const char *const TAG = "am2320";
15 
17  uint8_t data[8];
18  data[0] = 0;
19  data[1] = 4;
20  if (!this->read_data_(data)) {
21  this->status_set_warning();
22  return;
23  }
24 
25  float temperature = (((data[4] & 0x7F) << 8) + data[5]) / 10.0f;
26  temperature = (data[4] & 0x80) ? -temperature : temperature;
27  float humidity = ((data[2] << 8) + data[3]) / 10.0f;
28 
29  ESP_LOGD(TAG, "Got temperature=%.1f°C humidity=%.1f%%", temperature, humidity);
30  if (this->temperature_sensor_ != nullptr)
31  this->temperature_sensor_->publish_state(temperature);
32  if (this->humidity_sensor_ != nullptr)
33  this->humidity_sensor_->publish_state(humidity);
34  this->status_clear_warning();
35 }
37  ESP_LOGCONFIG(TAG, "Setting up AM2320...");
38  uint8_t data[8];
39  data[0] = 0;
40  data[1] = 4;
41  if (!this->read_data_(data)) {
42  this->mark_failed();
43  return;
44  }
45 }
47  ESP_LOGD(TAG, "AM2320:");
48  LOG_I2C_DEVICE(this);
49  if (this->is_failed()) {
50  ESP_LOGE(TAG, "Communication with AM2320 failed!");
51  }
52  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
53  LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
54 }
56 
57 bool AM2320Component::read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion) {
58  if (!this->write_bytes(a_register, data, 2)) {
59  ESP_LOGW(TAG, "Writing bytes for AM2320 failed!");
60  return false;
61  }
62 
63  if (conversion > 0)
64  delay(conversion);
65  return this->read(data, len) == i2c::ERROR_OK;
66 }
67 
68 bool AM2320Component::read_data_(uint8_t *data) {
69  // Wake up
70  this->write_bytes(0, data, 0);
71 
72  // Write instruction 3, 2 bytes, get 8 bytes back (2 preamble, 2 bytes temperature, 2 bytes humidity, 2 bytes CRC)
73  if (!this->read_bytes_(3, data, 8, 2)) {
74  ESP_LOGW(TAG, "Updating AM2320 failed!");
75  return false;
76  }
77 
78  uint16_t checksum;
79 
80  checksum = data[7] << 8;
81  checksum += data[6];
82 
83  if (crc16(data, 6) != checksum) {
84  ESP_LOGW(TAG, "AM2320 Checksum invalid!");
85  return false;
86  }
87 
88  return true;
89 }
90 
91 } // namespace am2320
92 } // namespace esphome
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:18
bool read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion=0)
Definition: am2320.cpp:57
sensor::Sensor * temperature_sensor_
Definition: am2320.h:24
sensor::Sensor * humidity_sensor_
Definition: am2320.h:25
ErrorCode read(uint8_t *data, size_t len)
Definition: i2c.h:48
float temperature
Definition: qmp6988.h:71
uint16_t crc16(const uint8_t *data, uint8_t len)
Calculate a CRC-16 checksum of data with size len.
Definition: helpers.cpp:71
void status_clear_warning()
Definition: component.cpp:149
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:72
void dump_config() override
Definition: am2320.cpp:46
uint8_t checksum
Definition: bl0939.h:35
float get_setup_priority() const override
Definition: am2320.cpp:55
void status_set_warning()
Definition: component.cpp:141
std::string size_t len
Definition: helpers.h:281
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:112
Definition: a4988.cpp:4
bool read_data_(uint8_t *data)
Definition: am2320.cpp:68
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:27
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition: i2c.h:109