ESPHome  2022.8.0
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/log.h"
8 #include "esphome/core/hal.h"
9 
10 namespace esphome {
11 namespace am2320 {
12 
13 static const char *const TAG = "am2320";
14 
15 // ---=== Calc CRC16 ===---
16 uint16_t crc_16(uint8_t *ptr, uint8_t length) {
17  uint16_t crc = 0xFFFF;
18  uint8_t i;
19  //------------------------------
20  while (length--) {
21  crc ^= *ptr++;
22  for (i = 0; i < 8; i++) {
23  if ((crc & 0x01) != 0) {
24  crc >>= 1;
25  crc ^= 0xA001;
26  } else {
27  crc >>= 1;
28  }
29  }
30  }
31  return crc;
32 }
33 
35  uint8_t data[8];
36  data[0] = 0;
37  data[1] = 4;
38  if (!this->read_data_(data)) {
39  this->status_set_warning();
40  return;
41  }
42 
43  float temperature = (((data[4] & 0x7F) << 8) + data[5]) / 10.0f;
44  temperature = (data[4] & 0x80) ? -temperature : temperature;
45  float humidity = ((data[2] << 8) + data[3]) / 10.0f;
46 
47  ESP_LOGD(TAG, "Got temperature=%.1f°C humidity=%.1f%%", temperature, humidity);
48  if (this->temperature_sensor_ != nullptr)
49  this->temperature_sensor_->publish_state(temperature);
50  if (this->humidity_sensor_ != nullptr)
51  this->humidity_sensor_->publish_state(humidity);
52  this->status_clear_warning();
53 }
55  ESP_LOGCONFIG(TAG, "Setting up AM2320...");
56  uint8_t data[8];
57  data[0] = 0;
58  data[1] = 4;
59  if (!this->read_data_(data)) {
60  this->mark_failed();
61  return;
62  }
63 }
65  ESP_LOGD(TAG, "AM2320:");
66  LOG_I2C_DEVICE(this);
67  if (this->is_failed()) {
68  ESP_LOGE(TAG, "Communication with AM2320 failed!");
69  }
70  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
71  LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
72 }
74 
75 bool AM2320Component::read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion) {
76  if (!this->write_bytes(a_register, data, 2)) {
77  ESP_LOGW(TAG, "Writing bytes for AM2320 failed!");
78  return false;
79  }
80 
81  if (conversion > 0)
82  delay(conversion);
83  return this->read(data, len) == i2c::ERROR_OK;
84 }
85 
86 bool AM2320Component::read_data_(uint8_t *data) {
87  // Wake up
88  this->write_bytes(0, data, 0);
89 
90  // Write instruction 3, 2 bytes, get 8 bytes back (2 preamble, 2 bytes temperature, 2 bytes humidity, 2 bytes CRC)
91  if (!this->read_bytes_(3, data, 8, 2)) {
92  ESP_LOGW(TAG, "Updating AM2320 failed!");
93  return false;
94  }
95 
96  uint16_t checksum;
97 
98  checksum = data[7] << 8;
99  checksum += data[6];
100 
101  if (crc_16(data, 6) != checksum) {
102  ESP_LOGW(TAG, "AM2320 Checksum invalid!");
103  return false;
104  }
105 
106  return true;
107 }
108 
109 } // namespace am2320
110 } // 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:75
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
void status_clear_warning()
Definition: component.cpp:148
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:72
void dump_config() override
Definition: am2320.cpp:64
uint8_t checksum
Definition: bl0939.h:35
float get_setup_priority() const override
Definition: am2320.cpp:73
void status_set_warning()
Definition: component.cpp:140
std::string size_t len
Definition: helpers.h:278
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:111
Definition: a4988.cpp:4
uint16_t crc_16(uint8_t *ptr, uint8_t length)
Definition: am2320.cpp:16
bool read_data_(uint8_t *data)
Definition: am2320.cpp:86
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