ESPHome  2025.2.0
ads1115.cpp
Go to the documentation of this file.
1 #include "ads1115.h"
2 #include "esphome/core/hal.h"
3 #include "esphome/core/log.h"
4 
5 namespace esphome {
6 namespace ads1115 {
7 
8 static const char *const TAG = "ads1115";
9 static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00;
10 static const uint8_t ADS1115_REGISTER_CONFIG = 0x01;
11 
13  ESP_LOGCONFIG(TAG, "Setting up ADS1115...");
14  uint16_t value;
15  if (!this->read_byte_16(ADS1115_REGISTER_CONVERSION, &value)) {
16  this->mark_failed();
17  return;
18  }
19 
20  ESP_LOGCONFIG(TAG, "Configuring ADS1115...");
21 
22  uint16_t config = 0;
23  // Clear single-shot bit
24  // 0b0xxxxxxxxxxxxxxx
25  config |= 0b0000000000000000;
26  // Setup multiplexer
27  // 0bx000xxxxxxxxxxxx
28  config |= ADS1115_MULTIPLEXER_P0_N1 << 12;
29 
30  // Setup Gain
31  // 0bxxxx000xxxxxxxxx
32  config |= ADS1115_GAIN_6P144 << 9;
33 
34  if (this->continuous_mode_) {
35  // Set continuous mode
36  // 0bxxxxxxx0xxxxxxxx
37  config |= 0b0000000000000000;
38  } else {
39  // Set singleshot mode
40  // 0bxxxxxxx1xxxxxxxx
41  config |= 0b0000000100000000;
42  }
43 
44  // Set data rate - 860 samples per second
45  // 0bxxxxxxxx100xxxxx
46  config |= ADS1115_860SPS << 5;
47 
48  // Set comparator mode - hysteresis
49  // 0bxxxxxxxxxxx0xxxx
50  config |= 0b0000000000000000;
51 
52  // Set comparator polarity - active low
53  // 0bxxxxxxxxxxxx0xxx
54  config |= 0b0000000000000000;
55 
56  // Set comparator latch enabled - false
57  // 0bxxxxxxxxxxxxx0xx
58  config |= 0b0000000000000000;
59 
60  // Set comparator que mode - disabled
61  // 0bxxxxxxxxxxxxxx11
62  config |= 0b0000000000000011;
63 
64  if (!this->write_byte_16(ADS1115_REGISTER_CONFIG, config)) {
65  this->mark_failed();
66  return;
67  }
68  this->prev_config_ = config;
69 }
71  ESP_LOGCONFIG(TAG, "Setting up ADS1115...");
72  LOG_I2C_DEVICE(this);
73  if (this->is_failed()) {
74  ESP_LOGE(TAG, "Communication with ADS1115 failed!");
75  }
76 }
78  ADS1115Resolution resolution, ADS1115Samplerate samplerate) {
79  uint16_t config = this->prev_config_;
80  // Multiplexer
81  // 0bxBBBxxxxxxxxxxxx
82  config &= 0b1000111111111111;
83  config |= (multiplexer & 0b111) << 12;
84 
85  // Gain
86  // 0bxxxxBBBxxxxxxxxx
87  config &= 0b1111000111111111;
88  config |= (gain & 0b111) << 9;
89 
90  // Sample rate
91  // 0bxxxxxxxxBBBxxxxx
92  config &= 0b1111111100011111;
93  config |= (samplerate & 0b111) << 5;
94 
95  if (!this->continuous_mode_) {
96  // Start conversion
97  config |= 0b1000000000000000;
98  }
99 
100  if (!this->continuous_mode_ || this->prev_config_ != config) {
101  if (!this->write_byte_16(ADS1115_REGISTER_CONFIG, config)) {
102  this->status_set_warning();
103  return NAN;
104  }
105  this->prev_config_ = config;
106 
107  // Delay calculated as: ceil((1000/SPS)+.5)
108  if (resolution == ADS1015_12_BITS) {
109  switch (samplerate) {
110  case ADS1115_8SPS:
111  delay(9);
112  break;
113  case ADS1115_16SPS:
114  delay(5);
115  break;
116  case ADS1115_32SPS:
117  delay(3);
118  break;
119  case ADS1115_64SPS:
120  case ADS1115_128SPS:
121  delay(2);
122  break;
123  default:
124  delay(1);
125  break;
126  }
127  } else {
128  switch (samplerate) {
129  case ADS1115_8SPS:
130  delay(126); // NOLINT
131  break;
132  case ADS1115_16SPS:
133  delay(63); // NOLINT
134  break;
135  case ADS1115_32SPS:
136  delay(32);
137  break;
138  case ADS1115_64SPS:
139  delay(17);
140  break;
141  case ADS1115_128SPS:
142  delay(9);
143  break;
144  case ADS1115_250SPS:
145  delay(5);
146  break;
147  case ADS1115_475SPS:
148  delay(3);
149  break;
150  case ADS1115_860SPS:
151  delay(2);
152  break;
153  }
154  }
155 
156  // in continuous mode, conversion will always be running, rely on the delay
157  // to ensure conversion is taking place with the correct settings
158  // can we use the rdy pin to trigger when a conversion is done?
159  if (!this->continuous_mode_) {
160  uint32_t start = millis();
161  while (this->read_byte_16(ADS1115_REGISTER_CONFIG, &config) && (config >> 15) == 0) {
162  if (millis() - start > 100) {
163  ESP_LOGW(TAG, "Reading ADS1115 timed out");
164  this->status_set_warning();
165  return NAN;
166  }
167  yield();
168  }
169  }
170  }
171 
172  uint16_t raw_conversion;
173  if (!this->read_byte_16(ADS1115_REGISTER_CONVERSION, &raw_conversion)) {
174  this->status_set_warning();
175  return NAN;
176  }
177 
178  if (resolution == ADS1015_12_BITS) {
179  bool negative = (raw_conversion >> 15) == 1;
180 
181  // shift raw_conversion as it's only 12-bits, left justified
182  raw_conversion = raw_conversion >> (16 - ADS1015_12_BITS);
183 
184  // check if number was negative in order to keep the sign
185  if (negative) {
186  // the number was negative
187  // 1) set the negative bit back
188  raw_conversion |= 0x8000;
189  // 2) reset the former (shifted) negative bit
190  raw_conversion &= 0xF7FF;
191  }
192  }
193 
194  auto signed_conversion = static_cast<int16_t>(raw_conversion);
195 
196  float millivolts;
197  float divider = (resolution == ADS1115_16_BITS) ? 32768.0f : 2048.0f;
198  switch (gain) {
199  case ADS1115_GAIN_6P144:
200  millivolts = (signed_conversion * 6144) / divider;
201  break;
202  case ADS1115_GAIN_4P096:
203  millivolts = (signed_conversion * 4096) / divider;
204  break;
205  case ADS1115_GAIN_2P048:
206  millivolts = (signed_conversion * 2048) / divider;
207  break;
208  case ADS1115_GAIN_1P024:
209  millivolts = (signed_conversion * 1024) / divider;
210  break;
211  case ADS1115_GAIN_0P512:
212  millivolts = (signed_conversion * 512) / divider;
213  break;
214  case ADS1115_GAIN_0P256:
215  millivolts = (signed_conversion * 256) / divider;
216  break;
217  default:
218  millivolts = NAN;
219  }
220 
221  this->status_clear_warning();
222  return millivolts / 1e3f;
223 }
224 
225 } // namespace ads1115
226 } // namespace esphome
bool read_byte_16(uint8_t a_register, uint16_t *data)
Definition: i2c.h:246
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
bool is_failed() const
Definition: component.cpp:143
AlsGain501 gain
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
void status_clear_warning()
Definition: component.cpp:166
void IRAM_ATTR HOT yield()
Definition: core.cpp:24
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool write_byte_16(uint8_t a_register, uint16_t data)
Definition: i2c.h:266
float request_measurement(ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution, ADS1115Samplerate samplerate)
Helper method to request a measurement from a sensor.
Definition: ads1115.cpp:77
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26