├── Adafruit_ADS1015.cpp ├── Adafruit_ADS1015.h ├── README.md ├── examples ├── comparator │ └── comparator.pde ├── continuous │ └── continuous.ino ├── differential │ └── differential.pde ├── singleended │ └── singleended.pde └── test_ADS1115 │ └── test_ADS1115.ino ├── keywords.txt ├── library.properties └── license.txt /Adafruit_ADS1015.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_ADS1015.cpp 4 | @author K.Townsend (Adafruit Industries) 5 | @license BSD (see license.txt) 6 | 7 | Driver for the ADS1015/ADS1115 ADC 8 | 9 | This is a library for the Adafruit MPL115A2 breakout 10 | ----> https://www.adafruit.com/products/??? 11 | 12 | Adafruit invests time and resources providing this open source code, 13 | please support Adafruit and open-source hardware by purchasing 14 | products from Adafruit! 15 | 16 | @section HISTORY 17 | 18 | v1.0 - First release 19 | v1.1 - Added ADS1115 support - W. Earl 20 | v1.2 - Modified by soligen2010 - consolidation of pull requests and other stuff 21 | Moved conversion delay out of getLastConversionResults into startComparator_SingleEnded so the method can be used more generically. 22 | Re-factored out duplicated code in differential reads 23 | Re-factored out duplicated code for single ended MUX bit settings 24 | Added support for differential reads between pins 0,3 and 1,3 (was also done by ycheneval in pull request #6) 25 | Added voltsPerBit() as a convenience 26 | Added keywords.txt (Pull request #8 from dhhagen) 27 | Fix for single ended int overflow (Pull request #9 from jamesfowkes) 28 | Added include guard (Pull request #11 from Ivan-Perez) 29 | Added begin method for ESP8266 systems (from Pontus Oldberg) 30 | Ability to configure Samples per Second and set corresponding Conversion Delay (Adapted from romainreignier) 31 | In startComparator_SingleEnded explicitly set the low threshold to the default. 32 | Added methods that return actual voltage as a float. 33 | Renamed constants that were common to both chips to ADS1X15.... 34 | v1.2.1 Modified by soligen2010. Removed explicit conversion delays and instead poll the config 35 | register by 1 ms intervals to check when conversion is complete 36 | 37 | */ 38 | /**************************************************************************/ 39 | #if ARDUINO >= 100 40 | #include "Arduino.h" 41 | #else 42 | #include "WProgram.h" 43 | #endif 44 | 45 | #include 46 | 47 | #include "Adafruit_ADS1015.h" 48 | 49 | /**************************************************************************/ 50 | /*! 51 | @brief Abstract away platform differences in Arduino wire library 52 | */ 53 | /**************************************************************************/ 54 | static uint8_t i2cread(void) { 55 | #if ARDUINO >= 100 56 | return Wire.read(); 57 | #else 58 | return Wire.receive(); 59 | #endif 60 | } 61 | 62 | /**************************************************************************/ 63 | /*! 64 | @brief Abstract away platform differences in Arduino wire library 65 | */ 66 | /**************************************************************************/ 67 | static void i2cwrite(uint8_t x) { 68 | #if ARDUINO >= 100 69 | Wire.write((uint8_t)x); 70 | #else 71 | Wire.send(x); 72 | #endif 73 | } 74 | 75 | /**************************************************************************/ 76 | /*! 77 | @brief Writes 16-bits to the specified destination register 78 | */ 79 | /**************************************************************************/ 80 | static void writeRegister(uint8_t i2cAddress, uint8_t reg, uint16_t value) { 81 | Wire.beginTransmission(i2cAddress); 82 | i2cwrite((uint8_t)reg); 83 | i2cwrite((uint8_t)(value>>8)); 84 | i2cwrite((uint8_t)(value & 0xFF)); 85 | Wire.endTransmission(); 86 | } 87 | 88 | /**************************************************************************/ 89 | /*! 90 | @brief Reads 16-bits to the specified destination register 91 | */ 92 | /**************************************************************************/ 93 | static uint16_t readRegister(uint8_t i2cAddress, uint8_t reg) { 94 | Wire.beginTransmission(i2cAddress); 95 | i2cwrite(reg); 96 | Wire.endTransmission(); 97 | Wire.requestFrom(i2cAddress, (uint8_t)2); 98 | return ((i2cread() << 8) | i2cread()); 99 | } 100 | 101 | /**************************************************************************/ 102 | /*! 103 | @brief Instantiates a new ADS1015 class w/appropriate properties 104 | */ 105 | /**************************************************************************/ 106 | Adafruit_ADS1015::Adafruit_ADS1015(uint8_t i2cAddress) 107 | { 108 | m_i2cAddress = i2cAddress; 109 | m_bitShift = ADS1015_CONV_REG_BIT_SHIFT_4; 110 | } 111 | 112 | /**************************************************************************/ 113 | /*! 114 | @brief Instantiates a new ADS1115 class w/appropriate properties 115 | */ 116 | /**************************************************************************/ 117 | Adafruit_ADS1115::Adafruit_ADS1115(uint8_t i2cAddress) 118 | { 119 | m_i2cAddress = i2cAddress; 120 | m_bitShift = ADS1115_CONV_REG_BIT_SHIFT_0; 121 | } 122 | 123 | /**************************************************************************/ 124 | /*! 125 | @brief Sets up the HW (reads coefficients values, etc.) 126 | */ 127 | /**************************************************************************/ 128 | void Adafruit_ADS1015::begin() { 129 | Wire.begin(); 130 | } 131 | 132 | #if defined(ARDUINO_ARCH_ESP8266) 133 | /**************************************************************************/ 134 | /*! 135 | @brief Sets up the HW (reads coefficients values, etc.) 136 | This function should be called if you are using an ESP8266 and 137 | have the SDA and SCL pins other than 4 and 5. 138 | */ 139 | /**************************************************************************/ 140 | void Adafruit_ADS1015::begin(uint8_t sda, uint8_t scl) { 141 | Wire.begin(sda, scl); 142 | } 143 | #endif 144 | 145 | /**************************************************************************/ 146 | /*! 147 | @brief Sets the gain and input voltage range 148 | */ 149 | /**************************************************************************/ 150 | void Adafruit_ADS1015::setGain(adsGain_t gain) 151 | { 152 | m_gain = gain; 153 | } 154 | 155 | /**************************************************************************/ 156 | /*! 157 | @brief Gets a gain and input voltage range 158 | */ 159 | /**************************************************************************/ 160 | adsGain_t Adafruit_ADS1015::getGain() 161 | { 162 | return m_gain; 163 | } 164 | 165 | /**************************************************************************/ 166 | /*! 167 | @brief Sets the Samples per Second setting 168 | */ 169 | /**************************************************************************/ 170 | void Adafruit_ADS1015::setSPS(adsSPS_t SPS) 171 | { 172 | m_SPS = SPS; 173 | } 174 | 175 | /**************************************************************************/ 176 | /*! 177 | @brief Gets the Samples per Second setting 178 | */ 179 | /**************************************************************************/ 180 | adsSPS_t Adafruit_ADS1015::getSPS() 181 | { 182 | return m_SPS; 183 | } 184 | 185 | /**************************************************************************/ 186 | /*! 187 | @brief Given the input pin (channel) Determines the MUX bits in the config 188 | register for single ended operations 189 | */ 190 | /**************************************************************************/ 191 | uint16_t getSingleEndedConfigBitsForMUX(uint8_t channel) { 192 | uint16_t c = 0; 193 | switch (channel) 194 | { 195 | case (0): 196 | c = ADS1X15_REG_CONFIG_MUX_SINGLE_0; 197 | break; 198 | case (1): 199 | c = ADS1X15_REG_CONFIG_MUX_SINGLE_1; 200 | break; 201 | case (2): 202 | c = ADS1X15_REG_CONFIG_MUX_SINGLE_2; 203 | break; 204 | case (3): 205 | c = ADS1X15_REG_CONFIG_MUX_SINGLE_3; 206 | break; 207 | } 208 | return c; 209 | } 210 | 211 | /**************************************************************************/ 212 | /*! 213 | @brief Gets a single-ended ADC reading from the specified channel in Volts 214 | */ 215 | /**************************************************************************/ 216 | float Adafruit_ADS1015::readADC_SingleEnded_V(uint8_t channel) { 217 | return (float)readADC_SingleEnded(channel) * voltsPerBit(); 218 | } 219 | 220 | /**************************************************************************/ 221 | /*! 222 | @brief Gets a single-ended ADC reading from the specified channel 223 | */ 224 | /**************************************************************************/ 225 | int16_t Adafruit_ADS1015::readADC_SingleEnded(uint8_t channel) { 226 | if (channel > 3) 227 | { 228 | return 0; 229 | } 230 | 231 | // Start with default values 232 | uint16_t config = ADS1X15_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val) 233 | ADS1X15_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val) 234 | ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) 235 | ADS1X15_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val) 236 | ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default) 237 | 238 | // Set PGA/voltage range 239 | config |= m_gain; 240 | 241 | // Set Samples per Second 242 | config |= m_SPS; 243 | 244 | // Set single-ended input channel 245 | config |= getSingleEndedConfigBitsForMUX(channel); 246 | 247 | // Set 'start single-conversion' bit 248 | config |= ADS1X15_REG_CONFIG_OS_SINGLE; 249 | 250 | // Write config register to the ADC 251 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG, config); 252 | 253 | // Wait for the conversion to complete 254 | waitForConversion(); 255 | 256 | return getLastConversionResults(); // conversion delay is included in this method 257 | } 258 | 259 | /**************************************************************************/ 260 | /*! 261 | @brief Reads the conversion results, measuring the voltage 262 | difference between the P (AIN0) and N (AIN1) input. Generates 263 | a signed value since the difference can be either 264 | positive or negative. 265 | */ 266 | /**************************************************************************/ 267 | int16_t Adafruit_ADS1015::readADC_Differential(adsDiffMux_t regConfigDiffMUX) { 268 | // Start with default values 269 | uint16_t config = ADS1X15_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val) 270 | ADS1X15_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val) 271 | ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) 272 | ADS1X15_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val) 273 | ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default) 274 | 275 | // Set PGA/voltage range 276 | config |= m_gain; 277 | 278 | // Set Samples per Second 279 | config |= m_SPS; 280 | 281 | // Set channels 282 | config |= regConfigDiffMUX; // set P and N inputs for differential 283 | 284 | // Set 'start single-conversion' bit 285 | config |= ADS1X15_REG_CONFIG_OS_SINGLE; 286 | 287 | // Write config register to the ADC 288 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG, config); 289 | 290 | // Wait for the conversion to complete 291 | waitForConversion(); 292 | 293 | return getLastConversionResults(); // conversion delay is included in this method 294 | } 295 | 296 | /**************************************************************************/ 297 | /*! 298 | @brief Reads the conversion results, measuring the voltage 299 | difference between the P (AIN0) and N (AIN1) input. Generates 300 | a signed value since the difference can be either 301 | positive or negative. 302 | */ 303 | /**************************************************************************/ 304 | int16_t Adafruit_ADS1015::readADC_Differential_0_1() { 305 | return readADC_Differential(DIFF_MUX_0_1); // AIN0 = P, AIN1 = N 306 | } 307 | 308 | /**************************************************************************/ 309 | /*! 310 | @brief Reads the conversion results, measuring the voltage 311 | difference between the P (AIN1) and N (AIN3) input. Generates 312 | a signed value since the difference can be either 313 | positive or negative. 314 | */ 315 | /**************************************************************************/ 316 | int16_t Adafruit_ADS1015::readADC_Differential_0_3() { 317 | return readADC_Differential(DIFF_MUX_0_3); // AIN0 = P, AIN3 = N 318 | } 319 | 320 | /**************************************************************************/ 321 | /*! 322 | @brief Reads the conversion results, measuring the voltage 323 | difference between the P (AIN1) and N (AIN3) input. Generates 324 | a signed value since the difference can be either 325 | positive or negative. 326 | */ 327 | /**************************************************************************/ 328 | int16_t Adafruit_ADS1015::readADC_Differential_1_3() { 329 | return readADC_Differential(DIFF_MUX_1_3); // AIN1 = P, AIN3 = N 330 | } 331 | 332 | /**************************************************************************/ 333 | /*! 334 | @brief Reads the conversion results, measuring the voltage 335 | difference between the P (AIN2) and N (AIN3) input. Generates 336 | a signed value since the difference can be either 337 | positive or negative. 338 | */ 339 | /**************************************************************************/ 340 | int16_t Adafruit_ADS1015::readADC_Differential_2_3() { 341 | return readADC_Differential(DIFF_MUX_2_3); // AIN2 = P, AIN3 = N 342 | } 343 | 344 | /**************************************************************************/ 345 | /*! 346 | @brief Reads the conversion results, measuring the voltage 347 | difference between the P (AIN0) and N (AIN1) input. Generates 348 | a signed value since the difference can be either 349 | positive or negative. 350 | Applies the Volts per bit to return actual voltage 351 | */ 352 | /**************************************************************************/ 353 | float Adafruit_ADS1015::readADC_Differential_0_1_V() { 354 | return (float) readADC_Differential(DIFF_MUX_0_1) * voltsPerBit(); // AIN0 = P, AIN1 = N 355 | } 356 | 357 | /**************************************************************************/ 358 | /*! 359 | @brief Reads the conversion results, measuring the voltage 360 | difference between the P (AIN0) and N (AIN3) input. Generates 361 | a signed value since the difference can be either 362 | positive or negative. 363 | Applies the Volts per bit to return actual voltage 364 | */ 365 | /**************************************************************************/ 366 | float Adafruit_ADS1015::readADC_Differential_0_3_V() { 367 | return (float) readADC_Differential(DIFF_MUX_0_3) * voltsPerBit(); // AIN0 = P, AIN1 = N 368 | } 369 | 370 | /**************************************************************************/ 371 | /*! 372 | @brief Reads the conversion results, measuring the voltage 373 | difference between the P (AIN1) and N (AIN3) input. Generates 374 | a signed value since the difference can be either 375 | positive or negative. 376 | Applies the Volts per bit to return actual voltage 377 | */ 378 | /**************************************************************************/ 379 | float Adafruit_ADS1015::readADC_Differential_1_3_V() { 380 | return (float) readADC_Differential(DIFF_MUX_1_3) * voltsPerBit(); // AIN0 = P, AIN1 = N 381 | } 382 | 383 | /**************************************************************************/ 384 | /*! 385 | @brief Reads the conversion results, measuring the voltage 386 | difference between the P (AIN2) and N (AIN3) input. Generates 387 | a signed value since the difference can be either 388 | positive or negative. 389 | Applies the Volts per bit to return actual voltage 390 | */ 391 | /**************************************************************************/ 392 | float Adafruit_ADS1015::readADC_Differential_2_3_V() { 393 | return (float) readADC_Differential(DIFF_MUX_2_3) * voltsPerBit(); // AIN0 = P, AIN1 = N 394 | } 395 | 396 | /**************************************************************************/ 397 | /*! 398 | @brief Sets up the comparator to operate in basic mode, causing the 399 | ALERT/RDY pin to assert (go from high to low) when the ADC 400 | value exceeds the specified threshold. 401 | The pin latches, call getLastConversionResults() to clear the latch. 402 | 403 | This will also set the ADC in continuous conversion mode. 404 | */ 405 | /**************************************************************************/ 406 | void Adafruit_ADS1015::startComparator_SingleEnded(uint8_t channel, int16_t highThreshold) 407 | { 408 | // Start with default values 409 | uint16_t config = ADS1X15_REG_CONFIG_CQUE_1CONV | // Comparator enabled and asserts on 1 match 410 | ADS1X15_REG_CONFIG_CLAT_LATCH | // Latching mode 411 | ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) 412 | ADS1X15_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val) 413 | ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous conversion mode 414 | 415 | // Set PGA/voltage range 416 | config |= m_gain; 417 | 418 | // Set Samples per Second 419 | config |= m_SPS; 420 | 421 | // Set single-ended input channel 422 | config |= getSingleEndedConfigBitsForMUX(channel); 423 | 424 | // Set the high threshold register 425 | // Shift 12-bit results left 4 bits for the ADS1015 426 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_HITHRESH, highThreshold << m_bitShift); 427 | 428 | // Set the high threshold register to the default 429 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_LOWTHRESH, ADS1X15_LOW_THRESHOLD_DEFAULT); 430 | 431 | // Write config register to the ADC 432 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG, config); 433 | 434 | } 435 | 436 | 437 | /**************************************************************************/ 438 | /*! 439 | @brief Sets up the comparator to operate in window mode, causing the 440 | ALERT/RDY pin to assert (go from high to low) when the ADC 441 | value exceeds the high threshold or drops below the low threshold. 442 | The pin latches, call getLastConversionResults() to clear the latch. 443 | 444 | This will also set the ADC in continuous conversion mode. 445 | */ 446 | /**************************************************************************/ 447 | void Adafruit_ADS1015::startWindowComparator_SingleEnded(uint8_t channel, int16_t lowThreshold, int16_t highThreshold) 448 | { 449 | // Start with default values 450 | uint16_t config = ADS1X15_REG_CONFIG_CQUE_1CONV | // Comparator enabled and asserts on 1 match 451 | ADS1X15_REG_CONFIG_CLAT_LATCH | // Latching mode 452 | ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) 453 | ADS1X15_REG_CONFIG_CMODE_WINDOW | // Window comparator 454 | ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous conversion mode 455 | 456 | // Set PGA/voltage range 457 | config |= m_gain; 458 | 459 | // Set Samples per Second 460 | config |= m_SPS; 461 | 462 | // Set single-ended input channel 463 | config |= getSingleEndedConfigBitsForMUX(channel); 464 | 465 | // Set the high threshold register 466 | // Shift 12-bit results left 4 bits for the ADS1015 467 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_HITHRESH, highThreshold << m_bitShift); 468 | 469 | // Set the high threshold register to the default 470 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_LOWTHRESH, lowThreshold << m_bitShift); 471 | 472 | // Write config register to the ADC 473 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG, config); 474 | 475 | } 476 | 477 | 478 | /**************************************************************************/ 479 | /*! 480 | @brief Sets up continous coversion operatoin, causing the 481 | ALERT/RDY pin to assert (go from high to low) each time a conversion 482 | completes. Pin stays low for 8 micro seconds (per the datasheet) 483 | */ 484 | /**************************************************************************/ 485 | void Adafruit_ADS1015::startContinuous_SingleEnded(uint8_t channel) 486 | { 487 | // Initial single ended non-contunuous read primes the conversion buffer with a valid reading 488 | // so that the initial interrupts produced a correct result instead of a left over 489 | // conversion result from previous operations. 490 | readADC_SingleEnded(channel); 491 | 492 | // Start with default values 493 | uint16_t config = ADS1X15_REG_CONFIG_CQUE_1CONV | // Comparator enabled and asserts on 1 match 494 | ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) 495 | ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous conversion mode 496 | 497 | // Set PGA/voltage range 498 | config |= m_gain; 499 | 500 | // Set Samples per Second 501 | config |= m_SPS; 502 | 503 | // Set single-ended input channel 504 | config |= getSingleEndedConfigBitsForMUX(channel); 505 | 506 | // Continuous mode is set by setting the most signigicant bit for the HIGH threshold to 1 507 | // and for the LOW threshold to 0. This is accomlished by setting the HIGH threshold to the 508 | // low default (a negative number) and the LOW threshold to the HIGH default (a positive number) 509 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_HITHRESH, ADS1X15_LOW_THRESHOLD_DEFAULT); 510 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_LOWTHRESH, ADS1X15_HIGH_THRESHOLD_DEFAULT); 511 | 512 | // Write config register to the ADC 513 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG, config); 514 | 515 | } 516 | 517 | /**************************************************************************/ 518 | /*! 519 | @brief Sets up Differential continous coversion operatoin, causing the 520 | ALERT/RDY pin to assert (go from high to low) each time a conversion 521 | completes. Pin stays low for 8 micro seconds (per the datasheet) 522 | */ 523 | /**************************************************************************/ 524 | void Adafruit_ADS1015::startContinuous_Differential(adsDiffMux_t regConfigDiffMUX) 525 | { 526 | // Initial Differential non-contunuous read primes the conversion buffer with a valid reading 527 | // so that the initial interrupts produced a correct result instead of a left over 528 | // conversion result from previous operations. 529 | readADC_Differential(regConfigDiffMUX); 530 | 531 | // Start with default values 532 | uint16_t config = ADS1X15_REG_CONFIG_CQUE_1CONV | // Comparator enabled and asserts on 1 match 533 | ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) 534 | ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous conversion mode 535 | 536 | // Set PGA/voltage range 537 | config |= m_gain; 538 | 539 | // Set Samples per Second 540 | config |= m_SPS; 541 | 542 | // Set channels 543 | config |= regConfigDiffMUX; // set P and N inputs for differential 544 | 545 | // Continuous mode is set by setting the most signigicant bit for the HIGH threshold to 1 546 | // and for the LOW threshold to 0. This is accomlished by setting the HIGH threshold to the 547 | // low default (a negative number) and the LOW threshold to the HIGH default (a positive number) 548 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_HITHRESH, ADS1X15_LOW_THRESHOLD_DEFAULT); 549 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_LOWTHRESH, ADS1X15_HIGH_THRESHOLD_DEFAULT); 550 | 551 | // Write config register to the ADC 552 | writeRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG, config); 553 | 554 | } 555 | 556 | /**************************************************************************/ 557 | /*! 558 | @brief Sets up Differential continous coversion operation between the 559 | P (AIN1) and N (AIN3) input, causing the 560 | ALERT/RDY pin to assert (go from high to low) each time a conversion 561 | completes. Pin stays low for 8 micro seconds (per the datasheet) 562 | */ 563 | /**************************************************************************/ 564 | void Adafruit_ADS1015::startContinuous_Differential_0_1() { 565 | startContinuous_Differential(DIFF_MUX_0_1); // AIN0 = P, AIN1 = N 566 | } 567 | 568 | /**************************************************************************/ 569 | /*! 570 | @brief Sets up Differential continous coversion operation between the 571 | P (AIN1) and N (AIN3) input, causing the 572 | ALERT/RDY pin to assert (go from high to low) each time a conversion 573 | completes. Pin stays low for 8 micro seconds (per the datasheet) 574 | */ 575 | /**************************************************************************/ 576 | void Adafruit_ADS1015::startContinuous_Differential_0_3() { 577 | startContinuous_Differential(DIFF_MUX_0_3); // AIN0 = P, AIN1 = N 578 | } 579 | 580 | /**************************************************************************/ 581 | /*! 582 | @brief Sets up Differential continous coversion operation between the 583 | P (AIN1) and N (AIN3) input, causing the 584 | ALERT/RDY pin to assert (go from high to low) each time a conversion 585 | completes. Pin stays low for 8 micro seconds (per the datasheet) 586 | */ 587 | /**************************************************************************/ 588 | void Adafruit_ADS1015::startContinuous_Differential_1_3() { 589 | startContinuous_Differential(DIFF_MUX_1_3); // AIN0 = P, AIN1 = N 590 | } 591 | 592 | /**************************************************************************/ 593 | /*! 594 | @brief Sets up Differential continous coversion operation between the 595 | P (AIN1) and N (AIN3) input, causing the 596 | ALERT/RDY pin to assert (go from high to low) each time a conversion 597 | completes. Pin stays low for 8 micro seconds (per the datasheet) 598 | */ 599 | /**************************************************************************/ 600 | void Adafruit_ADS1015::startContinuous_Differential_2_3() { 601 | startContinuous_Differential(DIFF_MUX_2_3); // AIN0 = P, AIN1 = N 602 | } 603 | 604 | /**************************************************************************/ 605 | /*! 606 | @brief Poll the device each millisecond until the conversion is done. 607 | Using delay is important for an ESP8266 becasue it yeilds to the 608 | allow network operations to run. 609 | */ 610 | /**************************************************************************/ 611 | void Adafruit_ADS1015::waitForConversion() 612 | { 613 | delay(0); // delay(0) causes a yeild for ESP8266 614 | delayMicroseconds(10); // Slight delay to ensure converstion started. Probably not needed, but for safety 615 | do { 616 | delay(0); // delay(0) causes a yeild for ESP8266 617 | } 618 | while (ADS1X15_REG_CONFIG_OS_BUSY == (readRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONFIG) & ADS1X15_REG_CONFIG_OS_MASK)); 619 | // Stop when the config register OS bit changes to 1 620 | } 621 | 622 | /**************************************************************************/ 623 | /*! 624 | @brief This function reads the last conversion 625 | results without changing the config value. 626 | 627 | After the comparator triggers, in order to clear the comparator, 628 | we need to read the conversion results. 629 | */ 630 | /**************************************************************************/ 631 | int16_t Adafruit_ADS1015::getLastConversionResults() 632 | { 633 | // Read the conversion results 634 | uint16_t res = readRegister(m_i2cAddress, ADS1X15_REG_POINTER_CONVERT) >> m_bitShift; 635 | if (m_bitShift == ADS1115_CONV_REG_BIT_SHIFT_0) // for ADS1115 636 | { 637 | return (int16_t)res; 638 | } 639 | else 640 | { 641 | // Shift 12-bit results right 4 bits for the ADS1015, 642 | // making sure we keep the sign bit intact 643 | if (res > 0x07FF) 644 | { 645 | // negative number - extend the sign to 16th bit 646 | res |= 0xF000; 647 | } 648 | return (int16_t)res; 649 | } 650 | } 651 | 652 | /**************************************************************************/ 653 | /*! 654 | @brief Return the volts per bit for based on gain. Multiply the adc 655 | reading by the value returned here to get actual volts. 656 | */ 657 | /**************************************************************************/ 658 | float Adafruit_ADS1015::voltsPerBit() 659 | { 660 | float v = 0; 661 | if (m_bitShift == ADS1015_CONV_REG_BIT_SHIFT_4) { // for ADS1015 662 | switch (m_gain) 663 | { 664 | case (GAIN_TWOTHIRDS): 665 | v = ADS1015_VOLTS_PER_BIT_GAIN_TWOTHIRDS; 666 | break; 667 | case (GAIN_ONE): 668 | v = ADS1015_VOLTS_PER_BIT_GAIN_ONE; 669 | break; 670 | case (GAIN_TWO): 671 | v = ADS1015_VOLTS_PER_BIT_GAIN_TWO; 672 | break; 673 | case (GAIN_FOUR): 674 | v = ADS1015_VOLTS_PER_BIT_GAIN_FOUR; 675 | break; 676 | case (GAIN_EIGHT): 677 | v = ADS1015_VOLTS_PER_BIT_GAIN_EIGHT; 678 | break; 679 | case (GAIN_SIXTEEN): 680 | v = ADS1015_VOLTS_PER_BIT_GAIN_SIXTEEN; 681 | break; 682 | } 683 | } else // for ADS1115 684 | { 685 | switch (m_gain) 686 | { 687 | case (GAIN_TWOTHIRDS): 688 | v = ADS1115_VOLTS_PER_BIT_GAIN_TWOTHIRDS; 689 | break; 690 | case (GAIN_ONE): 691 | v = ADS1115_VOLTS_PER_BIT_GAIN_ONE; 692 | break; 693 | case (GAIN_TWO): 694 | v = ADS1115_VOLTS_PER_BIT_GAIN_TWO; 695 | break; 696 | case (GAIN_FOUR): 697 | v = ADS1115_VOLTS_PER_BIT_GAIN_FOUR; 698 | break; 699 | case (GAIN_EIGHT): 700 | v = ADS1115_VOLTS_PER_BIT_GAIN_EIGHT; 701 | break; 702 | case (GAIN_SIXTEEN): 703 | v = ADS1115_VOLTS_PER_BIT_GAIN_SIXTEEN; 704 | break; 705 | } 706 | } 707 | return v; 708 | } 709 | 710 | -------------------------------------------------------------------------------- /Adafruit_ADS1015.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_ADS1015.h 4 | @author K. Townsend (Adafruit Industries) 5 | @license BSD (see license.txt) 6 | 7 | This is a library for the Adafruit ADS1015 breakout board 8 | ----> https://www.adafruit.com/products/??? 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | @section HISTORY 15 | 16 | v1.0 - First release 17 | v1.1 - Added ADS1115 support - W. Earl 18 | v1.2 - Modified by Dennis Cabell. See details in ccp file. 19 | */ 20 | /**************************************************************************/ 21 | 22 | #ifndef _ADAFRUIT_ADS1X15_H 23 | #define _ADAFRUIT_ADS1X15_H 24 | 25 | #if ARDUINO >= 100 26 | #include "Arduino.h" 27 | #else 28 | #include "WProgram.h" 29 | #endif 30 | 31 | #include 32 | 33 | /*========================================================================= 34 | I2C ADDRESS/BITS 35 | -----------------------------------------------------------------------*/ 36 | #define ADS1X15_ADDRESS (0x48) // 1001 000 (ADDR = GND) 37 | /*=========================================================================*/ 38 | 39 | /*========================================================================= 40 | Default thresholds for comparator 41 | -----------------------------------------------------------------------*/ 42 | #define ADS1X15_LOW_THRESHOLD_DEFAULT (0x8000) 43 | #define ADS1X15_HIGH_THRESHOLD_DEFAULT (0x7FFF) 44 | /*=========================================================================*/ 45 | 46 | /*========================================================================= 47 | POINTER REGISTER 48 | -----------------------------------------------------------------------*/ 49 | #define ADS1X15_REG_POINTER_MASK (0x03) 50 | #define ADS1X15_REG_POINTER_CONVERT (0x00) 51 | #define ADS1X15_REG_POINTER_CONFIG (0x01) 52 | #define ADS1X15_REG_POINTER_LOWTHRESH (0x02) 53 | #define ADS1X15_REG_POINTER_HITHRESH (0x03) 54 | /*=========================================================================*/ 55 | 56 | /*========================================================================= 57 | CONFIG REGISTER 58 | -----------------------------------------------------------------------*/ 59 | #define ADS1X15_REG_CONFIG_OS_MASK (0x8000) 60 | #define ADS1X15_REG_CONFIG_OS_SINGLE (0x8000) // Write: Set to start a single-conversion 61 | #define ADS1X15_REG_CONFIG_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress 62 | #define ADS1X15_REG_CONFIG_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion 63 | 64 | #define ADS1X15_REG_CONFIG_MUX_MASK (0x7000) 65 | #define ADS1X15_REG_CONFIG_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default) 66 | #define ADS1X15_REG_CONFIG_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3 67 | #define ADS1X15_REG_CONFIG_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3 68 | #define ADS1X15_REG_CONFIG_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3 69 | #define ADS1X15_REG_CONFIG_MUX_SINGLE_0 (0x4000) // Single-ended AIN0 70 | #define ADS1X15_REG_CONFIG_MUX_SINGLE_1 (0x5000) // Single-ended AIN1 71 | #define ADS1X15_REG_CONFIG_MUX_SINGLE_2 (0x6000) // Single-ended AIN2 72 | #define ADS1X15_REG_CONFIG_MUX_SINGLE_3 (0x7000) // Single-ended AIN3 73 | 74 | #define ADS1X15_REG_CONFIG_PGA_MASK (0x0E00) 75 | #define ADS1X15_REG_CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3 76 | #define ADS1X15_REG_CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1 77 | #define ADS1X15_REG_CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default) 78 | #define ADS1X15_REG_CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4 79 | #define ADS1X15_REG_CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8 80 | #define ADS1X15_REG_CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16 81 | 82 | #define ADS1X15_REG_CONFIG_MODE_MASK (0x0100) 83 | #define ADS1X15_REG_CONFIG_MODE_CONTIN (0x0000) // Continuous conversion mode 84 | #define ADS1X15_REG_CONFIG_MODE_SINGLE (0x0100) // Power-down single-shot mode (default) 85 | 86 | #define ADS1015_REG_CONFIG_DR_MASK (0x00E0) 87 | #define ADS1015_REG_CONFIG_DR_128SPS (0x0000) // 128 samples per second 88 | #define ADS1015_REG_CONFIG_DR_250SPS (0x0020) // 250 samples per second 89 | #define ADS1015_REG_CONFIG_DR_490SPS (0x0040) // 490 samples per second 90 | #define ADS1015_REG_CONFIG_DR_920SPS (0x0060) // 920 samples per second 91 | #define ADS1015_REG_CONFIG_DR_1600SPS (0x0080) // 1600 samples per second (default) 92 | #define ADS1015_REG_CONFIG_DR_2400SPS (0x00A0) // 2400 samples per second 93 | #define ADS1015_REG_CONFIG_DR_3300SPS (0x00C0) // 3300 samples per second 94 | 95 | #define ADS1115_REG_CONFIG_DR_8SPS (0x0000) // 8 samples per second 96 | #define ADS1115_REG_CONFIG_DR_16SPS (0x0020) // 16 samples per second 97 | #define ADS1115_REG_CONFIG_DR_32SPS (0x0040) // 32 samples per second 98 | #define ADS1115_REG_CONFIG_DR_64SPS (0x0060) // 64 samples per second 99 | #define ADS1115_REG_CONFIG_DR_128SPS (0x0080) // 128 samples per second (default) 100 | #define ADS1115_REG_CONFIG_DR_250SPS (0x00A0) // 250 samples per second 101 | #define ADS1115_REG_CONFIG_DR_475SPS (0x00C0) // 475 samples per second 102 | #define ADS1115_REG_CONFIG_DR_860SPS (0x00E0) // 860 samples per second 103 | 104 | #define ADS1X15_REG_CONFIG_CMODE_MASK (0x0010) 105 | #define ADS1X15_REG_CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default) 106 | #define ADS1X15_REG_CONFIG_CMODE_WINDOW (0x0010) // Window comparator 107 | 108 | #define ADS1X15_REG_CONFIG_CPOL_MASK (0x0008) 109 | #define ADS1X15_REG_CONFIG_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default) 110 | #define ADS1X15_REG_CONFIG_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active 111 | 112 | #define ADS1X15_REG_CONFIG_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted 113 | #define ADS1X15_REG_CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default) 114 | #define ADS1X15_REG_CONFIG_CLAT_LATCH (0x0004) // Latching comparator 115 | 116 | #define ADS1X15_REG_CONFIG_CQUE_MASK (0x0003) 117 | #define ADS1X15_REG_CONFIG_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions 118 | #define ADS1X15_REG_CONFIG_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions 119 | #define ADS1X15_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions 120 | #define ADS1X15_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) 121 | /*=========================================================================*/ 122 | 123 | /*========================================================================= 124 | GAIN VOLTAGES 125 | -----------------------------------------------------------------------*/ 126 | #define ADS1115_VOLTS_PER_BIT_GAIN_TWOTHIRDS 0.0001875F 127 | #define ADS1115_VOLTS_PER_BIT_GAIN_ONE 0.000125F 128 | #define ADS1115_VOLTS_PER_BIT_GAIN_TWO 0.0000625F 129 | #define ADS1115_VOLTS_PER_BIT_GAIN_FOUR 0.00003125F 130 | #define ADS1115_VOLTS_PER_BIT_GAIN_EIGHT 0.000015625F 131 | #define ADS1115_VOLTS_PER_BIT_GAIN_SIXTEEN 0.0000078125F 132 | 133 | #define ADS1015_VOLTS_PER_BIT_GAIN_TWOTHIRDS 0.003F 134 | #define ADS1015_VOLTS_PER_BIT_GAIN_ONE 0.002F 135 | #define ADS1015_VOLTS_PER_BIT_GAIN_TWO 0.001F 136 | #define ADS1015_VOLTS_PER_BIT_GAIN_FOUR 0.0005F 137 | #define ADS1015_VOLTS_PER_BIT_GAIN_EIGHT 0.00025F 138 | #define ADS1015_VOLTS_PER_BIT_GAIN_SIXTEEN 0.000125F 139 | /*=========================================================================*/ 140 | 141 | /*========================================================================= 142 | CHIP BASED BIT SHIFT 143 | -----------------------------------------------------------------------*/ 144 | #define ADS1015_CONV_REG_BIT_SHIFT_4 4 145 | #define ADS1115_CONV_REG_BIT_SHIFT_0 0 146 | 147 | /*=========================================================================*/ 148 | 149 | typedef enum : uint16_t 150 | { 151 | DIFF_MUX_0_1 = ADS1X15_REG_CONFIG_MUX_DIFF_0_1, 152 | DIFF_MUX_0_3 = ADS1X15_REG_CONFIG_MUX_DIFF_0_3, 153 | DIFF_MUX_1_3 = ADS1X15_REG_CONFIG_MUX_DIFF_1_3, 154 | DIFF_MUX_2_3 = ADS1X15_REG_CONFIG_MUX_DIFF_2_3 155 | } adsDiffMux_t; 156 | 157 | typedef enum : uint16_t 158 | { 159 | GAIN_TWOTHIRDS = ADS1X15_REG_CONFIG_PGA_6_144V, 160 | GAIN_ONE = ADS1X15_REG_CONFIG_PGA_4_096V, 161 | GAIN_TWO = ADS1X15_REG_CONFIG_PGA_2_048V, 162 | GAIN_FOUR = ADS1X15_REG_CONFIG_PGA_1_024V, 163 | GAIN_EIGHT = ADS1X15_REG_CONFIG_PGA_0_512V, 164 | GAIN_SIXTEEN = ADS1X15_REG_CONFIG_PGA_0_256V, 165 | GAIN_DEFAULT = ADS1X15_REG_CONFIG_PGA_6_144V 166 | } adsGain_t; 167 | 168 | typedef enum : uint16_t 169 | { 170 | ADS1015_DR_128SPS = ADS1015_REG_CONFIG_DR_128SPS, 171 | ADS1015_DR_250SPS = ADS1015_REG_CONFIG_DR_250SPS, 172 | ADS1015_DR_490SPS = ADS1015_REG_CONFIG_DR_490SPS, 173 | ADS1015_DR_920SPS = ADS1015_REG_CONFIG_DR_920SPS, 174 | ADS1015_DR_1600SPS = ADS1015_REG_CONFIG_DR_1600SPS, // default for ADS1015 175 | ADS1015_DR_2400SPS = ADS1015_REG_CONFIG_DR_2400SPS, 176 | ADS1015_DR_3300SPS = ADS1015_REG_CONFIG_DR_3300SPS, 177 | 178 | ADS1115_DR_8SPS = ADS1115_REG_CONFIG_DR_8SPS, 179 | ADS1115_DR_16SPS = ADS1115_REG_CONFIG_DR_16SPS, 180 | ADS1115_DR_32SPS = ADS1115_REG_CONFIG_DR_32SPS, 181 | ADS1115_DR_64SPS = ADS1115_REG_CONFIG_DR_64SPS, 182 | ADS1115_DR_128SPS = ADS1115_REG_CONFIG_DR_128SPS, // default for ADS1115 183 | ADS1115_DR_250SPS = ADS1115_REG_CONFIG_DR_250SPS, 184 | ADS1115_DR_475SPS = ADS1115_REG_CONFIG_DR_475SPS, 185 | ADS1115_DR_860SPS = ADS1115_REG_CONFIG_DR_860SPS, 186 | 187 | DR_DEFAULT_SPS = (0x0080) // 1600 for ADS1015, 128 for ADS1115 188 | } adsSPS_t; 189 | 190 | class Adafruit_ADS1015 191 | { 192 | protected: 193 | // Instance-specific properties 194 | uint8_t m_i2cAddress; 195 | uint8_t m_bitShift; 196 | adsGain_t m_gain = GAIN_DEFAULT; /* +/- 6.144V range (limited to VDD +0.3V max!) */ 197 | adsSPS_t m_SPS = DR_DEFAULT_SPS; 198 | 199 | public: 200 | Adafruit_ADS1015(uint8_t i2cAddress = ADS1X15_ADDRESS); 201 | void begin(void); 202 | #if defined(ARDUINO_ARCH_ESP8266) 203 | void begin(uint8_t sda, uint8_t scl); 204 | #endif 205 | int16_t readADC_SingleEnded(uint8_t channel); 206 | int16_t readADC_Differential(adsDiffMux_t); 207 | int16_t readADC_Differential_0_1(void); 208 | int16_t readADC_Differential_0_3(void); 209 | int16_t readADC_Differential_1_3(void); 210 | int16_t readADC_Differential_2_3(void); 211 | void startComparator_SingleEnded(uint8_t channel, int16_t highThreshold); 212 | void startWindowComparator_SingleEnded(uint8_t channel, int16_t lowThreshold, int16_t highThreshold); 213 | void startContinuous_SingleEnded(uint8_t channel); 214 | void startContinuous_Differential(adsDiffMux_t); 215 | int16_t getLastConversionResults(void); 216 | void setGain(adsGain_t gain); 217 | adsGain_t getGain(void); 218 | void setSPS(adsSPS_t gain); 219 | adsSPS_t getSPS(void); 220 | float voltsPerBit(void); 221 | float readADC_SingleEnded_V(uint8_t); 222 | float readADC_Differential_0_1_V(void); 223 | float readADC_Differential_0_3_V(void); 224 | float readADC_Differential_1_3_V(void); 225 | float readADC_Differential_2_3_V(void); 226 | void startContinuous_Differential_0_1(void); 227 | void startContinuous_Differential_0_3(void); 228 | void startContinuous_Differential_1_3(void); 229 | void startContinuous_Differential_2_3(void); 230 | void waitForConversion(); 231 | 232 | private: 233 | 234 | }; 235 | 236 | // Derive from ADS1015 & override construction to set properties 237 | class Adafruit_ADS1115 : public Adafruit_ADS1015 238 | { 239 | public: 240 | Adafruit_ADS1115(uint8_t i2cAddress = ADS1X15_ADDRESS); 241 | 242 | private: 243 | }; 244 | #endif 245 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Adafruit_ADS1015 2 | ================ 3 | 4 | Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator 5 | 6 | 7 | ## Compatibility 8 | 9 | MCU | Tested Works | Doesn't Work | Not Tested | Notes 10 | ----------------- | :----------: | :----------: | :---------: | ----- 11 | Atmega328 @ 16MHz | X | | | 12 | Atmega328 @ 12MHz | X | | | 13 | Atmega32u4 @ 16MHz | X | | | Use SDA/SCL on pins D2 & D3 14 | Atmega32u4 @ 8MHz | X | | | Use SDA/SCL on pins D2 & D3 15 | ESP8266 | X | | | SDA/SCL default to pins 4 & 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL) 16 | Atmega2560 @ 16MHz | X | | | Use SDA/SCL on pins 20 & 21 17 | ATSAM3X8E | X | | | Use SDA/SCL on pins 20 & 21 18 | ATSAM21D | X | | | 19 | ATtiny85 @ 16MHz | X | | | Use 0 for SDA, 2 for SCL 20 | ATtiny85 @ 8MHz | X | | | Use 0 for SDA, 2 for SCL 21 | 22 | * ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini 23 | * ATmega328 @ 12MHz : Adafruit Pro Trinket 3V 24 | * ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0 25 | * ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro 26 | * ESP8266 : Adafruit Huzzah 27 | * ATmega2560 @ 16MHz : Arduino Mega 28 | * ATSAM3X8E : Arduino Due 29 | * ATSAM21D : Arduino Zero, M0 Pro 30 | * ATtiny85 @ 16MHz : Adafruit Trinket 5V 31 | * ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/comparator/comparator.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //Adafruit_ADS1115 ads; /* Use this for the 16-bit version */ 5 | Adafruit_ADS1015 ads; /* Use this for the 12-bit version */ 6 | 7 | void setup(void) 8 | { 9 | Serial.begin(9600); 10 | Serial.println("Hello!"); 11 | 12 | Serial.println("Single-ended readings from AIN0 with >3.0V comparator"); 13 | Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)"); 14 | Serial.println("Comparator Threshold: 1000 (3.000V)"); 15 | 16 | // The ADC input range (or gain) can be changed via the following 17 | // functions, but be careful never to exceed VDD +0.3V max, or to 18 | // exceed the upper and lower limits if you adjust the input range! 19 | // Setting these values incorrectly may destroy your ADC! 20 | // ADS1015 ADS1115 21 | // ------- ------- 22 | // ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default) 23 | // ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV 24 | // ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV 25 | // ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV 26 | // ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV 27 | // ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV 28 | 29 | ads.begin(); 30 | 31 | // Setup 3V comparator on channel 0 32 | ads.startComparator_SingleEnded(0, 1000); 33 | } 34 | 35 | void loop(void) 36 | { 37 | int16_t adc0; 38 | 39 | // Comparator will only de-assert after a read 40 | adc0 = ads.getLastConversionResults(); 41 | Serial.print("AIN0: "); Serial.println(adc0); 42 | 43 | delay(100); 44 | } -------------------------------------------------------------------------------- /examples/continuous/continuous.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //Adafruit_ADS1115 ads; // Use this for the 16-bit version 5 | Adafruit_ADS1015 ads; // Use this for the 12-bit version 6 | 7 | const int alertPin = 2; 8 | 9 | volatile bool continuousConversionReady = false; 10 | 11 | void setup(void) 12 | { 13 | pinMode(alertPin,INPUT); 14 | 15 | Serial.begin(9600); 16 | Serial.println("Hello!"); 17 | 18 | // The ADC input range (or gain) can be changed via the following 19 | // functions, but be careful never to exceed VDD +0.3V max, or to 20 | // exceed the upper and lower limits if you adjust the input range! 21 | // Setting these values incorrectly may destroy your ADC! 22 | // ADS1015 ADS1115 23 | // ------- ------- 24 | ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default) 25 | // ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV 26 | // ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV 27 | // ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV 28 | // ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV 29 | // ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV 30 | 31 | //ads.begin(1,0); // for ESP8266 SDA, SCL can be specified 32 | ads.begin(); 33 | 34 | 35 | Serial.println("Starting continous mode on A0 at 8 SPS"); 36 | ads.setSPS(ADS1115_DR_8SPS); 37 | ads.startContinuous_SingleEnded(0); 38 | //ads.startContinuous_SingleEnded(1); 39 | //ads.startContinuous_SingleEnded(2); 40 | //ads.startContinuous_SingleEnded(3); 41 | //ads.startContinuous_Differential_0_1(); 42 | //ads.startContinuous_Differential_0_3(); 43 | //ads.startContinuous_Differential_1_3(); 44 | //ads.startContinuous_Differential_2_3(); 45 | 46 | attachInterrupt(digitalPinToInterrupt(alertPin), continuousAlert, FALLING); 47 | } 48 | 49 | void continuousAlert() { 50 | 51 | // Do not call getLastConversionResults from ISR because it uses I2C library that needs interrupts 52 | // to make it work, interrupts would need to be re-enabled in the ISR, which is not a very good practice. 53 | 54 | continuousConversionReady = true; 55 | } 56 | 57 | void loop(void) 58 | { 59 | if (continuousConversionReady) { 60 | float result = ((float) ads.getLastConversionResults()) * ads.voltsPerBit(); 61 | continuousConversionReady = false; 62 | Serial.print ("In interrupt routine. Reading is "); 63 | Serial.print (result,7); 64 | Serial.print (" at millisecond "); 65 | Serial.println(millis()); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /examples/differential/differential.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Adafruit_ADS1115 ads; /* Use this for the 16-bit version */ 5 | Adafruit_ADS1015 ads; /* Use this for the 12-bit version */ 6 | 7 | float multiplier; 8 | 9 | void setup(void) 10 | { 11 | Serial.begin(9600); 12 | Serial.println("Hello!"); 13 | 14 | Serial.println("Getting differential reading from AIN0 (P) and AIN1 (N)"); 15 | Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)"); 16 | 17 | // The ADC input range (or gain) can be changed via the following 18 | // functions, but be careful never to exceed VDD +0.3V max, or to 19 | // exceed the upper and lower limits if you adjust the input range! 20 | // Setting these values incorrectly may destroy your ADC! 21 | // ADS1015 ADS1115 22 | // ------- ------- 23 | // ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default) 24 | // ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV 25 | // ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV 26 | // ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV 27 | // ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV 28 | // ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV 29 | 30 | ads.begin(); 31 | 32 | multiplier = ads.voltsPerBit()*1000.0F; /* Sets the millivolts per bit */ 33 | 34 | /* Use this to set data rate for the 12-bit version (optional)*/ 35 | ads.setSPS(ADS1015_DR_3300SPS); // for ADS1015 fastest samples per second is 3300 (default is 1600) 36 | 37 | /* Use this to set data rate for the 16-bit version (optional)*/ 38 | //ads.setSPS(ADS1115_DR_860SPS); // for ADS1115 fastest samples per second is 860 (default is 128) 39 | 40 | } 41 | 42 | void loop(void) 43 | { 44 | int16_t results0_1, results0_3, results1_3, results2_3; 45 | 46 | 47 | results0_1 = ads.readADC_Differential_0_1(); 48 | Serial.print("Differential 0-1: "); Serial.print(results0_1); Serial.print("("); Serial.print(results0_1 * multiplier); Serial.println("mV)"); 49 | 50 | results0_3 = ads.readADC_Differential_0_3(); 51 | Serial.print("Differential 0-3: "); Serial.print(results0_3); Serial.print("("); Serial.print(results0_3 * multiplier); Serial.println("mV)"); 52 | 53 | results1_3 = ads.readADC_Differential_1_3(); 54 | Serial.print("Differential 1-3: "); Serial.print(results1_3); Serial.print("("); Serial.print(results1_3 * multiplier); Serial.println("mV)"); 55 | 56 | results2_3 = ads.readADC_Differential_2_3(); 57 | Serial.print("Differential 2-3: "); Serial.print(results2_3); Serial.print("("); Serial.print(results2_3 * multiplier); Serial.println("mV)"); 58 | 59 | 60 | delay(1000); 61 | } 62 | -------------------------------------------------------------------------------- /examples/singleended/singleended.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Adafruit_ADS1115 ads; /* Use this for the 16-bit version */ 5 | Adafruit_ADS1015 ads; /* Use this for the 12-bit version */ 6 | 7 | void setup(void) 8 | { 9 | Serial.begin(9600); 10 | Serial.println("Hello!"); 11 | 12 | Serial.println("Getting single-ended readings from AIN0..3"); 13 | Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)"); 14 | 15 | // The ADC input range (or gain) can be changed via the following 16 | // functions, but be careful never to exceed VDD +0.3V max, or to 17 | // exceed the upper and lower limits if you adjust the input range! 18 | // Setting these values incorrectly may destroy your ADC! 19 | // ADS1015 ADS1115 20 | // ------- ------- 21 | // ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default) 22 | // ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV 23 | // ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV 24 | // ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV 25 | // ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV 26 | // ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV 27 | 28 | ads.begin(); 29 | } 30 | 31 | void loop(void) 32 | { 33 | int16_t adc0, adc1, adc2, adc3; 34 | 35 | adc0 = ads.readADC_SingleEnded(0); 36 | adc1 = ads.readADC_SingleEnded(1); 37 | adc2 = ads.readADC_SingleEnded(2); 38 | adc3 = ads.readADC_SingleEnded(3); 39 | Serial.print("AIN0: "); Serial.println(adc0); 40 | Serial.print("AIN1: "); Serial.println(adc1); 41 | Serial.print("AIN2: "); Serial.println(adc2); 42 | Serial.print("AIN3: "); Serial.println(adc3); 43 | Serial.println(" "); 44 | 45 | delay(1000); 46 | } 47 | -------------------------------------------------------------------------------- /examples/test_ADS1115/test_ADS1115.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This sketch tests the library, outputting the values ready to Serial. 3 | Only one gain setting is tested at a time. If the gain is changed to 4 | GAIN_SIXTEEN then some of the read voltagees exceed the gain range and should 5 | read as the max value. With the resistors below all other gains should 6 | produce correct results (within a reasonable tolerance). Note that reading 7 | A0 (GND) may produce a slightly negative voltage 8 | 9 | Sketch and circuit by soligen2010, Feb 12, 2016 10 | 11 | Below are the components and connections for the test circuit for the test: 12 | 13 | Components: 14 | 15 | ADS1115 16 | D1 1N4004 (Cathode to AIN0, Anode to Pin 3 for arduino - choose different pin for ESP8266) 17 | R1 3k3 (VDD to AIN0) 18 | R2 240R (AIN0 to AIN1) 19 | R3 1K (AIN1 to AIN2) 20 | R4 1K (AIN2 to AIN3) 21 | 22 | Connections: 23 | 24 | VDD ---- +5, R1 (VDD to AIN0) 25 | GND ---- Gound 26 | SCL ---- Arduino Uno A5 or ESP8266 Pin 5 27 | SDA ---- Arduino Uno A4 or ESP8266 Pin 4 28 | ADDR --- GND 29 | ALRT --- Digital Pin 2 30 | AIN0 ----- R1, D1(Cathode to AIN0, Anode to Pin 3), R2 31 | AIN1 ----- R2, R3 32 | AIN2 ----- R3, R4 33 | AIN3 ----- R4, GND 34 | 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | //Adafruit_ADS1115 ads; // Use this for the 16-bit version 41 | Adafruit_ADS1015 ads; // Use this for the 12-bit version 42 | 43 | float multiplier; 44 | 45 | const int alertPin = 2; 46 | const int raiseVoltagePin = 3; 47 | 48 | volatile bool continuousConversionReady = false; 49 | 50 | void setup(void) 51 | { 52 | pinMode(alertPin,INPUT); 53 | pinMode(raiseVoltagePin,OUTPUT); 54 | digitalWrite(raiseVoltagePin,LOW); 55 | 56 | Serial.begin(9600); 57 | Serial.println("Hello!"); 58 | 59 | // The ADC input range (or gain) can be changed via the following 60 | // functions, but be careful never to exceed VDD +0.3V max, or to 61 | // exceed the upper and lower limits if you adjust the input range! 62 | // Setting these values incorrectly may destroy your ADC! 63 | // ADS1015 ADS1115 64 | // ------- ------- 65 | ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default) 66 | // ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV 67 | // ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV 68 | // ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV 69 | // ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV 70 | // ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV 71 | 72 | //ads.begin(1,0); // for ESP8266 SDA, SCL can be specified 73 | ads.begin(); 74 | 75 | multiplier = ads.voltsPerBit()*1000.0F; // Gets the millivolts per bit 76 | 77 | /* Use this to set data rate for the 12-bit version (optional)*/ 78 | //ads.setSPS(ADS1015_DR_3300SPS); // for ADS1015 fastest samples per second is 3300 (default is 1600) 79 | 80 | /* Use this to set data rate for the 16-bit version (optional)*/ 81 | ads.setSPS(ADS1115_DR_8SPS); // for ADS1115 fastest samples per second is 860 (default is 128) 82 | 83 | ads.readADC_Differential_0_1(); // in case chip was previously in contuous mode, take out of continuous 84 | ads.waitForConversion(); // delay to ensure any last remaining conversion completes 85 | // needed becasue if formerly was in continuous, 2 conversions need to complete 86 | 87 | // Run test for each SPS 88 | 89 | Serial.println("********* 8 SPS ************"); 90 | ads.setSPS(ADS1115_DR_8SPS); 91 | runTest(); 92 | 93 | Serial.println("********* 16 SPS ************"); 94 | ads.setSPS(ADS1115_DR_16SPS); 95 | runTest(); 96 | 97 | Serial.println("********* 32 SPS ************"); 98 | ads.setSPS(ADS1115_DR_32SPS); 99 | runTest(); 100 | 101 | Serial.println("********* 64 SPS ************"); 102 | ads.setSPS(ADS1115_DR_64SPS); 103 | runTest(); 104 | 105 | Serial.println("********* 128 SPS ************"); 106 | ads.setSPS(ADS1115_DR_128SPS); 107 | runTest(); 108 | 109 | Serial.println("********* 250 SPS ************"); 110 | ads.setSPS(ADS1115_DR_250SPS); 111 | runTest(); 112 | 113 | Serial.println("********* 475 SPS ************"); 114 | ads.setSPS(ADS1115_DR_475SPS); 115 | runTest(); 116 | 117 | Serial.println("********* 860 SPS ************"); 118 | ads.setSPS(ADS1115_DR_860SPS); 119 | runTest(); 120 | 121 | //Configure interrupt on alert pin for continuous mode; 122 | Serial.println(); 123 | 124 | Serial.println("Starting continous mode on A0 at 8 SPS"); 125 | ads.setSPS(ADS1115_DR_8SPS); 126 | ads.startContinuous_SingleEnded(0); 127 | //ads.startContinuous_SingleEnded(1); 128 | //ads.startContinuous_SingleEnded(2); 129 | //ads.startContinuous_SingleEnded(3); 130 | //ads.startContinuous_Differential_0_1(); 131 | //ads.startContinuous_Differential_0_3(); 132 | //ads.startContinuous_Differential_1_3(); 133 | //ads.startContinuous_Differential_2_3(); 134 | 135 | pinMode(alertPin, INPUT); 136 | attachInterrupt(digitalPinToInterrupt(alertPin), continuousAlert, FALLING); 137 | } 138 | 139 | void continuousAlert() { 140 | 141 | // Do not call getLastConversionResults from ISR because it uses I2C library that needs interrupts 142 | // to make it work, interrupts would need to be re-enabled in the ISR, which is not a very good practice. 143 | 144 | continuousConversionReady = true; 145 | } 146 | 147 | void loop(void) 148 | { 149 | if (continuousConversionReady) { 150 | float result = ((float) ads.getLastConversionResults()) * ads.voltsPerBit(); 151 | continuousConversionReady = false; 152 | Serial.print ("In interrupt routine. Reading is "); 153 | Serial.print (result,7); 154 | Serial.print (" at millisecond "); 155 | Serial.println(millis()); 156 | } 157 | 158 | } 159 | 160 | void runTest() 161 | { 162 | int16_t results0_1, results0_3, results1_3, results2_3; 163 | 164 | results0_1 = ads.readADC_Differential_0_1(); 165 | Serial.print("Differential 0-1: "); Serial.print(results0_1); Serial.print("("); Serial.print(results0_1 * multiplier); Serial.println("mV)"); 166 | Serial.println(1000.0F*ads.readADC_Differential_0_1_V()); 167 | 168 | results0_3 = ads.readADC_Differential_0_3(); 169 | Serial.print("Differential 0-3: "); Serial.print(results0_3); Serial.print("("); Serial.print(results0_3 * multiplier); Serial.println("mV)"); 170 | Serial.println(1000.0F*ads.readADC_Differential_0_3_V()); 171 | 172 | results1_3 = ads.readADC_Differential_1_3(); 173 | Serial.print("Differential 1-3: "); Serial.print(results1_3); Serial.print("("); Serial.print(results1_3 * multiplier); Serial.println("mV)"); 174 | Serial.println(1000.0F*ads.readADC_Differential_1_3_V()); 175 | 176 | results2_3 = ads.readADC_Differential_2_3(); 177 | Serial.print("Differential 2-3: "); Serial.print(results2_3); Serial.print("("); Serial.print(results2_3 * multiplier); Serial.println("mV)"); 178 | Serial.println(1000.0F*ads.readADC_Differential_2_3_V()); 179 | 180 | results0_1 = ads.readADC_SingleEnded(0); 181 | Serial.print("Single 0: "); Serial.print(results0_1); Serial.print("("); Serial.print(results0_1 * multiplier); Serial.println("mV)"); 182 | Serial.println(1000.0F*ads.readADC_SingleEnded_V(0)); 183 | 184 | results0_3 = ads.readADC_SingleEnded(1); 185 | Serial.print("Single 1: "); Serial.print(results0_3); Serial.print("("); Serial.print(results0_3 * multiplier); Serial.println("mV)"); 186 | Serial.println(1000.0F*ads.readADC_SingleEnded_V(1)); 187 | 188 | results1_3 = ads.readADC_SingleEnded(2); 189 | Serial.print("Single 2: "); Serial.print(results1_3); Serial.print("("); Serial.print(results1_3 * multiplier); Serial.println("mV)"); 190 | Serial.println(1000.0F*ads.readADC_SingleEnded_V(2)); 191 | 192 | results2_3 = ads.readADC_SingleEnded(3); 193 | Serial.print("Single 3: "); Serial.print(results2_3); Serial.print("("); Serial.print(results2_3 * multiplier); Serial.println("mV)"); 194 | Serial.println(1000.0F*ads.readADC_SingleEnded_V(3)); 195 | 196 | Serial.print("Read Time Microseconds: "); 197 | uint32_t sampleTime = micros(); 198 | results2_3 = ads.readADC_SingleEnded(3); 199 | Serial.println(micros() - sampleTime); 200 | 201 | // Test comparator mode 202 | 203 | int16_t compThresh = ads.readADC_SingleEnded(0) + 200; // Set the threshold slighly above A0 204 | 205 | ads.startComparator_SingleEnded(0,compThresh); 206 | Serial.print("Comparator started. Alert Pin (should be 1) = ");Serial.println(digitalRead(alertPin)); 207 | digitalWrite(raiseVoltagePin,HIGH); // raise the voltage. This feeds 5V via D1 into A0, bypassing R1 208 | do {delay(0);} while (digitalRead(alertPin) == HIGH); // Wait until alert signaled 209 | Serial.print("Comparator triggered. Alert Pin (should be 0) = ");Serial.println(digitalRead(alertPin)); 210 | digitalWrite(raiseVoltagePin,LOW); // lower voltage back down 211 | delay(1); 212 | results0_3 = ads.getLastConversionResults(); // reading conversion clears the latch 213 | results0_1 = ads.readADC_SingleEnded(0); // stops the contuous reading of the comparator mode 214 | ads.waitForConversion(); // delay to be sure last conversion ends. changing 215 | // from continuous to single the read may pick up the last continuous 216 | // instead of the newly initiated single read 217 | 218 | Serial.println(); 219 | 220 | delay(2000); 221 | } 222 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | Adafruit_ADS1015 KEYWORD1 2 | Adafruit_ADS1115 KEYWORD1 3 | begin KEYWORD2 4 | readADC_SingleEnded KEYWORD2 5 | readADC_Differential_0_1 KEYWORD2 6 | readADC_Differential_0_3 KEYWORD2 7 | readADC_Differential_1_3 KEYWORD2 8 | readADC_Differential_2_3 KEYWORD2 9 | readADC_SingleEnded_V KEYWORD2 10 | readADC_Differential_0_1_V KEYWORD2 11 | readADC_Differential_0_3_V KEYWORD2 12 | readADC_Differential_1_3_V KEYWORD2 13 | readADC_Differential_2_3_V KEYWORD2 14 | startComparator_SingleEnded KEYWORD2 15 | getLastConversionResults KEYWORD2 16 | getConversionDelay KEYWORD2 17 | setGain KEYWORD2 18 | getGain KEYWORD2 19 | setSPS KEYWORD2 20 | getSPS KEYWORD2 21 | voltsPerBit KEYWORD2 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit ADS1X15 2 | version=1.2.0 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator 6 | paragraph=Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator 7 | category=Signal Input/Output 8 | url=https://github.com/adafruit/Adafruit_ADS1X15 9 | architectures=* -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Software License Agreement (BSD License) 2 | 3 | Copyright (c) 2012, Adafruit Industries 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the copyright holders nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | --------------------------------------------------------------------------------