You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

294 lines
8.7 KiB

  1. /*
  2. * ads1115.c:
  3. * Extend wiringPi with the ADS1115 I2C 16-bit ADC
  4. * Copyright (c) 2016 Gordon Henderson
  5. ***********************************************************************
  6. * This file is part of wiringPi:
  7. * https://github.com/WiringPi/WiringPi/
  8. *
  9. * wiringPi is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * wiringPi is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with wiringPi.
  21. * If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************
  23. */
  24. /*
  25. *********************************************************************************
  26. * We're going to work in a hybrid mode to fit in with the wiringPi way of
  27. * doing things, so there will be 4 analog pin which read the 4 single-ended
  28. * channels as usual, also some fake digitalOutputs - these are the control
  29. * registers that allow the user to put it into single/diff mode, set the
  30. * gain and data rates.
  31. *********************************************************************************
  32. */
  33. #include <byteswap.h>
  34. #include <stdio.h>
  35. #include <stdint.h>
  36. #include <wiringPi.h>
  37. #include <wiringPiI2C.h>
  38. #include "ads1115.h"
  39. // Bits in the config register (it's a 16-bit register)
  40. #define CONFIG_OS_MASK (0x8000) // Operational Status Register
  41. #define CONFIG_OS_SINGLE (0x8000) // Write - Starts a single-conversion
  42. // Read 1 = Conversion complete
  43. // The multiplexor
  44. #define CONFIG_MUX_MASK (0x7000)
  45. // Differential modes
  46. #define CONFIG_MUX_DIFF_0_1 (0x0000) // Pos = AIN0, Neg = AIN1 (default)
  47. #define CONFIG_MUX_DIFF_0_3 (0x1000) // Pos = AIN0, Neg = AIN3
  48. #define CONFIG_MUX_DIFF_1_3 (0x2000) // Pos = AIN1, Neg = AIN3
  49. #define CONFIG_MUX_DIFF_2_3 (0x3000) // Pos = AIN2, Neg = AIN3 (2nd differential channel)
  50. // Single-ended modes
  51. #define CONFIG_MUX_SINGLE_0 (0x4000) // AIN0
  52. #define CONFIG_MUX_SINGLE_1 (0x5000) // AIN1
  53. #define CONFIG_MUX_SINGLE_2 (0x6000) // AIN2
  54. #define CONFIG_MUX_SINGLE_3 (0x7000) // AIN3
  55. // Programmable Gain Amplifier
  56. #define CONFIG_PGA_MASK (0x0E00)
  57. #define CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3
  58. #define CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1
  59. #define CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default)
  60. #define CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4
  61. #define CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8
  62. #define CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16
  63. #define CONFIG_MODE (0x0100) // 0 is continuous, 1 is single-shot (default)
  64. // Data Rate
  65. #define CONFIG_DR_MASK (0x00E0)
  66. #define CONFIG_DR_8SPS (0x0000) // 8 samples per second
  67. #define CONFIG_DR_16SPS (0x0020) // 16 samples per second
  68. #define CONFIG_DR_32SPS (0x0040) // 32 samples per second
  69. #define CONFIG_DR_64SPS (0x0060) // 64 samples per second
  70. #define CONFIG_DR_128SPS (0x0080) // 128 samples per second (default)
  71. #define CONFIG_DR_475SPS (0x00A0) // 475 samples per second
  72. #define CONFIG_DR_860SPS (0x00C0) // 860 samples per second
  73. // Comparator mode
  74. #define CONFIG_CMODE_MASK (0x0010)
  75. #define CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
  76. #define CONFIG_CMODE_WINDOW (0x0010) // Window comparator
  77. // Comparator polarity - the polarity of the output alert/rdy pin
  78. #define CONFIG_CPOL_MASK (0x0008)
  79. #define CONFIG_CPOL_ACTVLOW (0x0000) // Active low (default)
  80. #define CONFIG_CPOL_ACTVHI (0x0008) // Active high
  81. // Latching comparator - does the alert/rdy pin latch
  82. #define CONFIG_CLAT_MASK (0x0004)
  83. #define CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default)
  84. #define CONFIG_CLAT_LATCH (0x0004) // Latching comparator
  85. // Comparitor queue
  86. #define CONFIG_CQUE_MASK (0x0003)
  87. #define CONFIG_CQUE_1CONV (0x0000) // Assert after one conversions
  88. #define CONFIG_CQUE_2CONV (0x0001) // Assert after two conversions
  89. #define CONFIG_CQUE_4CONV (0x0002) // Assert after four conversions
  90. #define CONFIG_CQUE_NONE (0x0003) // Disable the comparator (default)
  91. #define CONFIG_DEFAULT (0x8583) // From the datasheet
  92. static const uint16_t dataRates [8] =
  93. {
  94. CONFIG_DR_8SPS, CONFIG_DR_16SPS, CONFIG_DR_32SPS, CONFIG_DR_64SPS, CONFIG_DR_128SPS, CONFIG_DR_475SPS, CONFIG_DR_860SPS
  95. } ;
  96. static const uint16_t gains [6] =
  97. {
  98. CONFIG_PGA_6_144V, CONFIG_PGA_4_096V, CONFIG_PGA_2_048V, CONFIG_PGA_1_024V, CONFIG_PGA_0_512V, CONFIG_PGA_0_256V
  99. } ;
  100. /*
  101. * analogRead:
  102. * Pin is the channel to sample on the device.
  103. * Channels 0-3 are single ended inputs,
  104. * channels 4-7 are the various differential combinations.
  105. *********************************************************************************
  106. */
  107. static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
  108. {
  109. int chan = pin - node->pinBase ;
  110. int16_t result ;
  111. uint16_t config = CONFIG_DEFAULT ;
  112. chan &= 7 ;
  113. // Setup the configuration register
  114. // Set PGA/voltage range
  115. config &= ~CONFIG_PGA_MASK ;
  116. config |= node->data0 ;
  117. // Set sample speed
  118. config &= ~CONFIG_DR_MASK ;
  119. config |= node->data1 ;
  120. // Set single-ended channel or differential mode
  121. config &= ~CONFIG_MUX_MASK ;
  122. switch (chan)
  123. {
  124. case 0: config |= CONFIG_MUX_SINGLE_0 ; break ;
  125. case 1: config |= CONFIG_MUX_SINGLE_1 ; break ;
  126. case 2: config |= CONFIG_MUX_SINGLE_2 ; break ;
  127. case 3: config |= CONFIG_MUX_SINGLE_3 ; break ;
  128. case 4: config |= CONFIG_MUX_DIFF_0_1 ; break ;
  129. case 5: config |= CONFIG_MUX_DIFF_2_3 ; break ;
  130. case 6: config |= CONFIG_MUX_DIFF_0_3 ; break ;
  131. case 7: config |= CONFIG_MUX_DIFF_1_3 ; break ;
  132. }
  133. // Start a single conversion
  134. config |= CONFIG_OS_SINGLE ;
  135. config = __bswap_16 (config) ;
  136. wiringPiI2CWriteReg16 (node->fd, 1, config) ;
  137. // Wait for the conversion to complete
  138. for (;;)
  139. {
  140. result = wiringPiI2CReadReg16 (node->fd, 1) ;
  141. result = __bswap_16 (result) ;
  142. if ((result & CONFIG_OS_MASK) != 0)
  143. break ;
  144. delayMicroseconds (100) ;
  145. }
  146. result = wiringPiI2CReadReg16 (node->fd, 0) ;
  147. result = __bswap_16 (result) ;
  148. // Sometimes with a 0v input on a single-ended channel the internal 0v reference
  149. // can be higher than the input, so you get a negative result...
  150. if ( (chan < 4) && (result < 0) )
  151. return 0 ;
  152. else
  153. return (int)result ;
  154. }
  155. /*
  156. * digitalWrite:
  157. * It may seem odd to have a digital write here, but it's the best way
  158. * to pass paramters into the chip in the wiringPi way of things.
  159. * We have 2 digital registers:
  160. * 0 is the gain control
  161. * 1 is the data rate control
  162. *********************************************************************************
  163. */
  164. static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int data)
  165. {
  166. int chan = pin - node->pinBase ;
  167. chan &= 3 ;
  168. if (chan == 0) // Gain Control
  169. {
  170. if ( (data < 0) || (data > 6) ) // Use default if out of range
  171. data = 2 ;
  172. node->data0 = gains [data] ;
  173. }
  174. else // Data rate control
  175. {
  176. if ( (data < 0) || (data > 7) ) // Use default if out of range
  177. data = 4 ;
  178. node->data1 = dataRates [data] ; // Bugfix 0-1 by "Eric de jong (gm)" <ericdejong@gmx.net> - Thanks.
  179. }
  180. }
  181. /*
  182. * analogWrite:
  183. * We're using this to write to the 2 comparitor threshold registers.
  184. * We could use a digitalWrite here but as it's an analog comparison
  185. * then it feels better to do it this way.
  186. *********************************************************************************
  187. */
  188. static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int data)
  189. {
  190. int chan = pin - node->pinBase ;
  191. int reg ;
  192. int16_t ndata ;
  193. chan &= 3 ;
  194. reg = chan + 2 ;
  195. /**/ if (data < -32767)
  196. ndata = -32767 ;
  197. else if (data > 32767)
  198. ndata = 32767 ;
  199. else
  200. ndata = (int16_t)data ;
  201. ndata = __bswap_16 (ndata) ;
  202. wiringPiI2CWriteReg16 (node->fd, reg, data) ;
  203. }
  204. /*
  205. * ads1115Setup:
  206. * Create a new wiringPi device node for an ads1115 on the Pi's
  207. * I2C interface.
  208. *********************************************************************************
  209. */
  210. int ads1115Setup (const int pinBase, int i2cAddr)
  211. {
  212. struct wiringPiNodeStruct *node ;
  213. int fd ;
  214. if ((fd = wiringPiI2CSetup (i2cAddr)) < 0)
  215. return FALSE ;
  216. node = wiringPiNewNode (pinBase, 8) ;
  217. node->fd = fd ;
  218. node->data0 = CONFIG_PGA_4_096V ; // Gain in data0
  219. node->data1 = CONFIG_DR_128SPS ; // Samples/sec in data1
  220. node->analogRead = myAnalogRead ;
  221. node->analogWrite = myAnalogWrite ;
  222. node->digitalWrite = myDigitalWrite ;
  223. return TRUE ;
  224. }