ESPHome  2024.12.2
tem3200.cpp
Go to the documentation of this file.
1 #include "tem3200.h"
2 #include "esphome/core/log.h"
3 #include "esphome/core/helpers.h"
4 #include "esphome/core/hal.h"
5 
6 namespace esphome {
7 namespace tem3200 {
8 
9 static const char *const TAG = "tem3200";
10 
11 enum ErrorCode {
12  NONE = 0,
13  RESERVED = 1,
14  STALE = 2,
15  FAULT = 3,
16 };
17 
19  ESP_LOGCONFIG(TAG, "Setting up TEM3200...");
20 
21  uint8_t status(NONE);
22  uint16_t raw_temperature(0);
23  uint16_t raw_pressure(0);
24 
25  i2c::ErrorCode err = this->read_(status, raw_temperature, raw_pressure);
26  if (err != i2c::ERROR_OK) {
27  ESP_LOGCONFIG(TAG, " I2C Communication Failed...");
28  this->mark_failed();
29  return;
30  }
31 
32  switch (status) {
33  case RESERVED:
34  ESP_LOGE(TAG, "Invalid RESERVED Device Status");
35  this->mark_failed();
36  return;
37  case FAULT:
38  ESP_LOGE(TAG, "FAULT condition in the SSC or sensing element");
39  this->mark_failed();
40  return;
41  case STALE:
42  ESP_LOGE(TAG, "STALE data. Data has not been updated since last fetch");
43  this->status_set_warning();
44  break;
45  }
46  ESP_LOGCONFIG(TAG, " Success...");
47 }
48 
50  ESP_LOGCONFIG(TAG, "TEM3200:");
51  LOG_I2C_DEVICE(this);
52  LOG_UPDATE_INTERVAL(this);
53  LOG_SENSOR(" ", "Raw Pressure", this->raw_pressure_sensor_);
54  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
55 }
56 
58 
59 i2c::ErrorCode TEM3200Component::read_(uint8_t &status, uint16_t &raw_temperature, uint16_t &raw_pressure) {
60  uint8_t response[4] = {0x00, 0x00, 0x00, 0x00};
61 
62  // initiate data read
63  i2c::ErrorCode err = this->read(response, 4);
64  if (err != i2c::ERROR_OK) {
65  return err;
66  }
67 
68  // extract top 2 bits of first byte for status
69  status = (ErrorCode) (response[0] & 0xc0) >> 6;
70  if (status == RESERVED || status == FAULT) {
71  return i2c::ERROR_OK;
72  }
73 
74  // if data is stale; reread
75  if (status == STALE) {
76  // wait for measurement 2ms
77  delay(2);
78 
79  err = this->read(response, 4);
80  if (err != i2c::ERROR_OK) {
81  return err;
82  }
83  }
84 
85  // extract top 2 bits of first byte for status
86  status = (ErrorCode) (response[0] & 0xc0) >> 6;
87  if (status == RESERVED || status == FAULT) {
88  return i2c::ERROR_OK;
89  }
90 
91  // extract top 6 bits of first byte and all bits of second byte for pressure
92  raw_pressure = (((response[0] & 0x3f)) << 8 | response[1]);
93 
94  // extract all bytes of 3rd byte and top 3 bits of fourth byte for temperature
95  raw_temperature = ((response[2] << 3) | (response[3] & 0xe0) >> 5);
96 
97  return i2c::ERROR_OK;
98 }
99 
100 inline float convert_temperature(uint16_t raw_temperature) {
101  const float temperature_bits_span = 2048;
102  const float temperature_max = 150;
103  const float temperature_min = -50;
104  const float temperature_span = temperature_max - temperature_min;
105 
106  float temperature = (raw_temperature * temperature_span / temperature_bits_span) + temperature_min;
107 
108  return temperature;
109 }
110 
112  uint8_t status(NONE);
113  uint16_t raw_temperature(0);
114  uint16_t raw_pressure(0);
115  i2c::ErrorCode err = this->read_(status, raw_temperature, raw_pressure);
116 
117  if (err != i2c::ERROR_OK) {
118  ESP_LOGW(TAG, "I2C Communication Failed");
119  this->status_set_warning();
120  return;
121  }
122 
123  switch (status) {
124  case RESERVED:
125  ESP_LOGE(TAG, "Failed: Device return RESERVED status");
126  this->status_set_warning();
127  return;
128  case FAULT:
129  ESP_LOGE(TAG, "Failed: FAULT condition in the SSC or sensing element");
130  this->mark_failed();
131  return;
132  case STALE:
133  ESP_LOGE(TAG, "Warning: STALE data. Data has not been updated since last fetch");
134  this->status_set_warning();
135  return;
136  }
137 
138  float temperature = convert_temperature(raw_temperature);
139 
140  ESP_LOGD(TAG, "Got raw pressure=%d, temperature=%.1f°C", raw_pressure, temperature);
141 
142  if (this->temperature_sensor_ != nullptr)
143  this->temperature_sensor_->publish_state(temperature);
144  if (this->raw_pressure_sensor_ != nullptr)
145  this->raw_pressure_sensor_->publish_state(raw_pressure);
146 
147  this->status_clear_warning();
148 }
149 
150 } // namespace tem3200
151 } // namespace esphome
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:19
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
ErrorCode read(uint8_t *data, size_t len)
reads an array of bytes from the device using an I2CBus
Definition: i2c.h:160
i2c::ErrorCode read_(uint8_t &status, uint16_t &raw_temperature, uint16_t &raw_pressure)
Definition: tem3200.cpp:59
float convert_temperature(uint16_t raw_temperature)
Definition: tem3200.cpp:100
float get_setup_priority() const override
Definition: tem3200.cpp:57
No error found during execution of method.
Definition: i2c_bus.h:13
void status_clear_warning()
Definition: component.cpp:166
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
uint16_t temperature
Definition: sun_gtil2.cpp:26
sensor::Sensor * temperature_sensor_
Definition: tem3200.h:25
uint8_t status
Definition: bl0942.h:74
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
ErrorCode
Error codes returned by I2CBus and I2CDevice methods.
Definition: i2c_bus.h:11
sensor::Sensor * raw_pressure_sensor_
Definition: tem3200.h:26
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26