ESPHome  2024.4.1
max44009.cpp
Go to the documentation of this file.
1 #include "max44009.h"
2 
3 #include "esphome/core/log.h"
4 
5 namespace esphome {
6 namespace max44009 {
7 
8 static const char *const TAG = "max44009.sensor";
9 
10 // REGISTERS
11 static const uint8_t MAX44009_REGISTER_CONFIGURATION = 0x02;
12 static const uint8_t MAX44009_LUX_READING_HIGH = 0x03;
13 static const uint8_t MAX44009_LUX_READING_LOW = 0x04;
14 // CONFIGURATION MASKS
15 static const uint8_t MAX44009_CFG_CONTINUOUS = 0x80;
16 // ERROR CODES
17 static const uint8_t MAX44009_OK = 0;
18 static const uint8_t MAX44009_ERROR_WIRE_REQUEST = -10;
19 static const uint8_t MAX44009_ERROR_OVERFLOW = -20;
20 static const uint8_t MAX44009_ERROR_HIGH_BYTE = -30;
21 static const uint8_t MAX44009_ERROR_LOW_BYTE = -31;
22 
24  ESP_LOGCONFIG(TAG, "Setting up MAX44009...");
25  bool state_ok = false;
27  state_ok = this->set_low_power_mode();
28  } else if (this->mode_ == MAX44009Mode::MAX44009_MODE_CONTINUOUS) {
29  state_ok = this->set_continuous_mode();
30  } else {
31  /*
32  * Mode AUTO: Set mode depending on update interval
33  * - On low power mode, the IC measures lux intensity only once every 800ms
34  * regardless of integration time
35  * - On continuous mode, the IC continuously measures lux intensity
36  */
37  if (this->get_update_interval() < 800) {
38  state_ok = this->set_continuous_mode();
39  } else {
40  state_ok = this->set_low_power_mode();
41  }
42  }
43  if (!state_ok)
44  this->mark_failed();
45 }
46 
48  ESP_LOGCONFIG(TAG, "MAX44009:");
49  LOG_I2C_DEVICE(this);
50  if (this->is_failed()) {
51  ESP_LOGE(TAG, "Communication with MAX44009 failed!");
52  }
53 }
54 
56 
58  // update sensor illuminance value
59  float lux = this->read_illuminance_();
60  if (this->error_ != MAX44009_OK) {
61  this->status_set_warning();
62  this->publish_state(NAN);
63  } else {
64  this->status_clear_warning();
65  this->publish_state(lux);
66  }
67 }
68 
70  uint8_t datahigh = this->read_(MAX44009_LUX_READING_HIGH);
71  if (error_ != MAX44009_OK) {
72  this->error_ = MAX44009_ERROR_HIGH_BYTE;
73  return this->error_;
74  }
75  uint8_t datalow = this->read_(MAX44009_LUX_READING_LOW);
76  if (error_ != MAX44009_OK) {
77  this->error_ = MAX44009_ERROR_LOW_BYTE;
78  return this->error_;
79  }
80  uint8_t exponent = datahigh >> 4;
81  if (exponent == 0x0F) {
82  this->error_ = MAX44009_ERROR_OVERFLOW;
83  return this->error_;
84  }
85 
86  return this->convert_to_lux_(datahigh, datalow);
87 }
88 
89 float MAX44009Sensor::convert_to_lux_(uint8_t data_high, uint8_t data_low) {
90  uint8_t exponent = data_high >> 4;
91  uint32_t mantissa = ((data_high & 0x0F) << 4) + (data_low & 0x0F);
92  return ((0x0001 << exponent) * 0.045) * mantissa;
93 }
94 
96  uint8_t config = this->read_(MAX44009_REGISTER_CONFIGURATION);
97  if (this->error_ == MAX44009_OK) {
98  config |= MAX44009_CFG_CONTINUOUS;
99  this->write_(MAX44009_REGISTER_CONFIGURATION, config);
100  this->status_clear_warning();
101  ESP_LOGV(TAG, "set to continuous mode");
102  return true;
103  } else {
104  this->status_set_warning();
105  return false;
106  }
107 }
108 
110  uint8_t config = this->read_(MAX44009_REGISTER_CONFIGURATION);
111  if (this->error_ == MAX44009_OK) {
112  config &= ~MAX44009_CFG_CONTINUOUS;
113  this->write_(MAX44009_REGISTER_CONFIGURATION, config);
114  this->status_clear_warning();
115  ESP_LOGV(TAG, "set to low power mode");
116  return true;
117  } else {
118  this->status_set_warning();
119  return false;
120  }
121 }
122 
123 uint8_t MAX44009Sensor::read_(uint8_t reg) {
124  uint8_t data = 0;
125  if (!this->read_byte(reg, &data)) {
126  this->error_ = MAX44009_ERROR_WIRE_REQUEST;
127  } else {
128  this->error_ = MAX44009_OK;
129  }
130  return data;
131 }
132 
133 void MAX44009Sensor::write_(uint8_t reg, uint8_t value) {
134  if (!this->write_byte(reg, value)) {
135  this->error_ = MAX44009_ERROR_WIRE_REQUEST;
136  } else {
137  this->error_ = MAX44009_OK;
138  }
139 }
140 
142 
143 } // namespace max44009
144 } // namespace esphome
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
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
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition: i2c.h:149
void set_mode(MAX44009Mode mode)
Definition: max44009.cpp:141
float read_illuminance_()
Read the illuminance value.
Definition: max44009.cpp:69
float convert_to_lux_(uint8_t data_high, uint8_t data_low)
Definition: max44009.cpp:89
void status_clear_warning()
Definition: component.cpp:166
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
Definition: component.cpp:228
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:262
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
uint8_t read_(uint8_t reg)
Definition: max44009.cpp:123
float get_setup_priority() const override
Definition: max44009.cpp:55
void write_(uint8_t reg, uint8_t value)
Definition: max44009.cpp:133