ESPHome  2024.3.1
ufire_ise.cpp
Go to the documentation of this file.
1 #include "esphome/core/log.h"
2 #include "ufire_ise.h"
3 
4 #include <cmath>
5 
6 namespace esphome {
7 namespace ufire_ise {
8 
9 static const char *const TAG = "ufire_ise";
10 
12  ESP_LOGCONFIG(TAG, "Setting up uFire_ise...");
13 
14  uint8_t version;
15  if (!this->read_byte(REGISTER_VERSION, &version) && version != 0xFF) {
16  this->mark_failed();
17  return;
18  }
19  ESP_LOGI(TAG, "Found uFire_ise board version 0x%02X", version);
20 
21  // Write option for temperature adjustments
22  uint8_t config;
23  this->read_byte(REGISTER_CONFIG, &config);
24  if (this->temperature_sensor_ == nullptr && this->temperature_sensor_external_ == nullptr) {
25  config &= ~CONFIG_TEMP_COMPENSATION;
26  } else {
27  config |= CONFIG_TEMP_COMPENSATION;
28  }
29  this->write_byte(REGISTER_CONFIG, config);
30 }
31 
33  int wait = 0;
34  if (this->temperature_sensor_ != nullptr) {
35  this->write_byte(REGISTER_TASK, COMMAND_MEASURE_TEMP);
36  wait += 750;
37  }
38  if (this->ph_sensor_ != nullptr) {
39  this->write_byte(REGISTER_TASK, COMMAND_MEASURE_MV);
40  wait += 750;
41  }
42 
43  // Wait until measurement are taken
44  this->set_timeout("data", wait, [this]() { this->update_internal_(); });
45 }
46 
48  float temperature = 0;
49 
50  // Read temperature internal and populate it
51  if (this->temperature_sensor_ != nullptr) {
52  temperature = this->measure_temperature_();
53  this->temperature_sensor_->publish_state(temperature);
54  }
55  // Get temperature from external only for adjustments
56  else if (this->temperature_sensor_external_ != nullptr) {
57  temperature = this->temperature_sensor_external_->state;
58  }
59 
60  if (this->ph_sensor_ != nullptr) {
61  this->ph_sensor_->publish_state(this->measure_ph_(temperature));
62  }
63 }
64 
65 float UFireISEComponent::measure_temperature_() { return this->read_data_(REGISTER_TEMP); }
66 
67 float UFireISEComponent::measure_mv_() { return this->read_data_(REGISTER_MV); }
68 
70  float mv, ph;
71 
72  mv = this->measure_mv_();
73  if (mv == -1)
74  return -1;
75 
76  ph = fabs(7.0 - (mv / PROBE_MV_TO_PH));
77 
78  // Determine the temperature correction
79  float distance_from_7 = std::abs(7 - roundf(ph));
80  float distance_from_25 = std::floor(std::abs(25 - roundf(temperature)) / 10);
81  float temp_multiplier = (distance_from_25 * distance_from_7) * PROBE_TMP_CORRECTION;
82  if ((ph >= 8.0) && (temperature >= 35))
83  temp_multiplier *= -1;
84  if ((ph <= 6.0) && (temperature <= 15))
85  temp_multiplier *= -1;
86 
87  ph += temp_multiplier;
88  if ((ph <= 0.0) || (ph > 14.0))
89  ph = -1;
90  if (std::isinf(ph))
91  ph = -1;
92  if (std::isnan(ph))
93  ph = -1;
94 
95  return ph;
96 }
97 
98 void UFireISEComponent::set_solution_(float solution) {
99  solution = (7 - solution) * PROBE_MV_TO_PH;
100  this->write_data_(REGISTER_SOLUTION, solution);
101 }
102 
104  this->set_solution_(solution);
105  this->write_byte(REGISTER_TASK, COMMAND_CALIBRATE_LOW);
106 }
107 
109  this->set_solution_(solution);
110  this->write_byte(REGISTER_TASK, COMMAND_CALIBRATE_HIGH);
111 }
112 
114  this->write_data_(REGISTER_REFHIGH, NAN);
115  this->write_data_(REGISTER_REFLOW, NAN);
116  this->write_data_(REGISTER_READHIGH, NAN);
117  this->write_data_(REGISTER_READLOW, NAN);
118 }
119 
121  float f;
122  uint8_t temp[4];
123 
124  this->write(&reg, 1);
125  delay(10);
126 
127  for (uint8_t i = 0; i < 4; i++) {
128  this->read_bytes_raw(temp + i, 1);
129  }
130  memcpy(&f, temp, sizeof(f));
131 
132  return f;
133 }
134 
135 void UFireISEComponent::write_data_(uint8_t reg, float data) {
136  uint8_t temp[4];
137 
138  memcpy(temp, &data, sizeof(data));
139  this->write_bytes(reg, temp, 4);
140  delay(10);
141 }
142 
144  ESP_LOGCONFIG(TAG, "uFire-ISE");
145  LOG_I2C_DEVICE(this)
146  LOG_UPDATE_INTERVAL(this)
147  LOG_SENSOR(" ", "PH Sensor", this->ph_sensor_)
148  LOG_SENSOR(" ", "Temperature Sensor", this->temperature_sensor_)
149  LOG_SENSOR(" ", "Temperature Sensor external", this->temperature_sensor_external_)
150 }
151 
152 } // namespace ufire_ise
153 } // namespace esphome
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
void write_data_(uint8_t reg, float data)
Definition: ufire_ise.cpp:135
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition: i2c.h:149
optional< std::array< uint8_t, N > > read_bytes_raw()
Definition: i2c.h:225
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition: component.cpp:69
float temperature
Definition: qmp6988.h:71
ErrorCode write(const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a device using an I2CBus
Definition: i2c.h:186
sensor::Sensor * temperature_sensor_external_
Definition: ufire_ise.h:58
float state
This member variable stores the last state that has passed through all filters.
Definition: sensor.h:131
void calibrate_probe_high(float solution)
Definition: ufire_ise.cpp:108
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
void calibrate_probe_low(float solution)
Definition: ufire_ise.cpp:103
float measure_ph_(float temperature)
Definition: ufire_ise.cpp:69
sensor::Sensor * temperature_sensor_
Definition: ufire_ise.h:57
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:113
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void set_solution_(float solution)
Definition: ufire_ise.cpp:98
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26
bool write_bytes(uint8_t a_register, const uint8_t *data, uint8_t len, bool stop=true)
Definition: i2c.h:248