xsns_12_ads1115_i2cdev.ino 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. xsns_12_ads1115.ino - ADS1x15 A/D Converter support for Sonoff-Tasmota
  3. Copyright (C) 2018 Stefan Bode and Theo Arends
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifdef USE_I2C
  16. #ifdef USE_ADS1115_I2CDEV
  17. /*********************************************************************************************\
  18. * ADS1115 - 4 channel 16BIT A/D converter
  19. *
  20. * Required library: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/ADS1115
  21. *
  22. * I2C Address: 0x48, 0x49, 0x4A or 0x4B
  23. *
  24. * The ADC input range (or gain) can be changed via the following
  25. * functions, but be careful never to exceed VDD +0.3V max, or to
  26. * exceed the upper and lower limits if you adjust the input range!
  27. * Setting these values incorrectly may destroy your ADC!
  28. * ADS1015 ADS1115
  29. * ------- -------
  30. * ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
  31. * ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
  32. * ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV
  33. * ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV
  34. * ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV
  35. * ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV
  36. \*********************************************************************************************/
  37. #define XSNS_12 12
  38. #include <ADS1115.h>
  39. ADS1115 adc0;
  40. uint8_t ads1115_type = 0;
  41. uint8_t ads1115_address;
  42. uint8_t ads1115_addresses[] = {
  43. ADS1115_ADDRESS_ADDR_GND, // address pin low (GND)
  44. ADS1115_ADDRESS_ADDR_VDD, // address pin high (VCC)
  45. ADS1115_ADDRESS_ADDR_SDA, // address pin tied to SDA pin
  46. ADS1115_ADDRESS_ADDR_SCL // address pin tied to SCL pin
  47. };
  48. int16_t Ads1115GetConversion(byte channel)
  49. {
  50. switch (channel) {
  51. case 0:
  52. adc0.getConversionP0GND();
  53. break;
  54. case 1:
  55. adc0.getConversionP1GND();
  56. break;
  57. case 2:
  58. adc0.getConversionP2GND();
  59. break;
  60. case 3:
  61. adc0.getConversionP3GND();
  62. break;
  63. }
  64. }
  65. /********************************************************************************************/
  66. void Ads1115Detect(void)
  67. {
  68. if (ads1115_type) {
  69. return;
  70. }
  71. for (byte i = 0; i < sizeof(ads1115_addresses); i++) {
  72. ads1115_address = ads1115_addresses[i];
  73. ADS1115 adc0(ads1115_address);
  74. if (adc0.testConnection()) {
  75. adc0.initialize();
  76. adc0.setGain(ADS1115_PGA_6P144); // Set the gain (PGA) +/-6.144V
  77. adc0.setRate(ADS1115_RATE_860);
  78. adc0.setMode(ADS1115_MODE_CONTINUOUS);
  79. ads1115_type = 1;
  80. snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "ADS1115", ads1115_address);
  81. AddLog(LOG_LEVEL_DEBUG);
  82. break;
  83. }
  84. }
  85. }
  86. void Ads1115Show(boolean json)
  87. {
  88. if (ads1115_type) {
  89. char stemp[10];
  90. byte dsxflg = 0;
  91. for (byte i = 0; i < 4; i++) {
  92. int16_t adc_value = Ads1115GetConversion(i);
  93. if (json) {
  94. if (!dsxflg ) {
  95. snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"ADS1115\":{"), mqtt_data);
  96. stemp[0] = '\0';
  97. }
  98. dsxflg++;
  99. snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value);
  100. strlcpy(stemp, ",", sizeof(stemp));
  101. #ifdef USE_WEBSERVER
  102. } else {
  103. snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);
  104. #endif // USE_WEBSERVER
  105. }
  106. }
  107. if (json) {
  108. if (dsxflg) {
  109. snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
  110. }
  111. }
  112. }
  113. }
  114. /*********************************************************************************************\
  115. * Interface
  116. \*********************************************************************************************/
  117. boolean Xsns12(byte function)
  118. {
  119. boolean result = false;
  120. if (i2c_flg) {
  121. switch (function) {
  122. case FUNC_PREP_BEFORE_TELEPERIOD:
  123. Ads1115Detect();
  124. break;
  125. case FUNC_JSON_APPEND:
  126. Ads1115Show(1);
  127. break;
  128. #ifdef USE_WEBSERVER
  129. case FUNC_WEB_APPEND:
  130. Ads1115Show(0);
  131. break;
  132. #endif // USE_WEBSERVER
  133. }
  134. }
  135. return result;
  136. }
  137. #endif // USE_ADS1115_I2CDEV
  138. #endif // USE_I2C