ADS1115 Multi-channel A/D Converter
The ADS1115 device is an I2C-compatible 16-bit high-precision low-power analog-to-digital converter (ADC) in an ultra-small leadless X2QFN-10 package and VSSOP-10 package. The ADS111x devices employ a low-drift voltage reference and an oscillator. The ADS1114 and ADS1115 also feature a programmable gain amplifier (PGA) and a digital comparator. These features, combined with a wide power supply voltage range, make the ADS1115 well suited for power- and space-constrained sensor measurements. The ADS111x can perform conversions at data rates up to 860 samples per second (SPS). The PGA offers input ranges from ±256mV to ±6.144V, enabling precise measurements of both large and small signals. The ADS1115 has an input multiplexer (MUX) that enables two differential input measurements or four single-ended input measurements. A digital comparator can be used in the ADS1115 for under-voltage and over-voltage detection. The ADS1115 can operate either in continuous conversion mode or in single-shot mode. In single-shot mode, these devices automatically power down after one conversion; therefore, the power consumption during idle periods is significantly reduced.
Module Source
Purchase link: https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-24706531953.13.41746a4bt0fSOS&id=522572645353 Materials download: see file 2.9.2-1 Product Specification
Specifications
Operating voltage: 2.0-5.5V Operating current: 150uA Acquisition precision: 16-bit Acquisition channels: 4 channels Control method: IIC Number of pins: 10 Pin (2.54mm pitch header)
Principle Analysis
The ADS1115 uses IIC communication, so first we need to understand the IIC address and timing, then determine the register settings. (1) Device Address The device address settings are shown in the table below.
Note: When the ADDR pin on the module is connected to GND, its device address is 1001000, and the last bit is the read/write bit.
When the ADDR pin on the module is connected to VDD, its device address is 1001001, and the last bit is the read/write bit.
In this document, GND is used as the address. That is, the subsequent address is 0X90. (2) Timing The figure below shows the read timing. The steps are: IIC start signal -> send device address + 0 (write) -> wait for module acknowledgment -> after acknowledgment, send register address -> wait for module acknowledgment -> resend start signal -> send device address + 1 (read) -> wait for module acknowledgment -> after acknowledgment, read the upper 8 bits of data -> after reading is complete, the host sends an acknowledgment signal -> read the lower 8 bits of data -> after reading is complete, the host sends an acknowledgment signal -> send IIC stop signal.
The figure below shows the write timing. The steps are: IIC start signal -> send device address + 0 (write) -> wait for module acknowledgment -> after acknowledgment, send register address -> wait for module acknowledgment -> after acknowledgment, write the upper 8 bits of data -> wait for module acknowledgment -> write the lower 8 bits of data -> wait for module acknowledgment -> send IIC stop signal.
(3) Register Description The ADS1115 has four registers, which can be accessed through the IIC interface using the address pointer.
- Address 0X00 is the conversion register, which contains the result of the last conversion.
- Address 0X01 is the configuration register, used to change the operating mode of the ADS1115 and query the device status.
- The other two registers, Lo_thresh and Hi_thresh, set the thresholds used for the comparator function, which we do not use.
Configuration Register Description The configuration register is 16 bits and is used to control the operating mode, input selection, data rate, full-scale range, comparator mode.
Bit 15: OS. During a read operation, it indicates the current working status of the device; during a write operation, it can set a single conversion. In this document, it is configured as 1 (must be in power-down mode; when OS is written as 1, the device will enter power-up mode and complete one data conversion, then automatically set OS to 0).
Bits 14-12: MUX is the input multiplexer, which selects the input mode. As shown in the figure below, there are eight input modes: four differential and four single-ended. In this document, it is configured as A0 single-ended input (0x04). (Single-ended input means the measured data has two pins: one output and one ground. Connect the measured output to the A0 pin, and the measured ground shares a common ground with the ADS1115.)
Bits 11-9: PGA is the programmable gain amplifier, which sets the FSR (full-scale range). In this document, it is configured as ±4.096V (0x01). The subsequent voltage calculation formula is related to this.
Bit 8: MODE selects continuous conversion mode or single-shot conversion mode (single-shot conversion mode requires the OS bit to trigger). In this document, it is configured as continuous conversion mode (0x00).
Bits 7-5: DR configures the data rate. In this document, it is configured as 128SPS (0x04).
Bits 4-2: Configuration for the comparator, which we do not use; the default of 0 is sufficient (0x00).
Bits 1-0: This is configured to disable the comparator and set the ALERT/RDY pin to high-impedance mode (0x03).
The final configuration result is 1100_0010_1000_0011 (0xC283).
The pin currently configured is A0, and we will also read data from the A0 pin subsequently.
Conversion Register Description The 16-bit conversion register stores the result of the last conversion in binary two's complement format. Note that after power-up, the conversion register is cleared to 0 and remains 0 until the first conversion is completed.
(4) Implementation Code Description How to convert the read ADC value into voltage? Take the PGA setting of 4.096V as an example. Voltage = acquired ADC value * resolution Resolution = measurement voltage range / (2^AD bits - 1) = 4.096 / 2 to the 15th power = 0.000125V The resolution can also be viewed in the data sheet, as shown in the figure on the right. Where 125uV = 0.125mV = 0.000125V.
/******************************************************************
* Function Name: WriteADS1115
* Function Description: Write dat data to address add of ADS1115
* Function Parameters: add register address to write
* dat_H upper 8 bits of data to write
* dat_L lower 8 bits of data to write
* Function Return: 0 write successful
* 1 no acknowledgment for device address write
* 2 no acknowledgment for register address write
* Author: LC
* Notes: Device address = 0X90
******************************************************************/
uint8_t WriteADS1115(uint8_t add,uint8_t dat_H,
uint8_t dat_L)
{
IIC_Start();//Start signal
IIC_Write(0x90);//Device address
if( IIC_Wait_Ack() == 1 )
return 1;
IIC_Write(add);//Register address
if( IIC_Wait_Ack() == 1 )
return 2;
IIC_Write(dat_H);//Write upper 8 bits
IIC_Wait_Ack();//Wait for acknowledgment
IIC_Write(dat_L);//Write lower 8 bits
IIC_Wait_Ack();//Wait for acknowledgment
IIC_Stop();//Stop signal
return (0);
}
/******************************************************************
* Function Name: ReadADS1115
* Function Description: Read data from ADS1115
* Function Parameters: add register address to read
* Function Return: -1 read failed other read successful
* Author: LC
* Notes: None
******************************************************************/
float ReadADS1115(unsigned char add)
{
int i =0;
unsigned char dat[2]={0};
unsigned int num = 0;
float ret=0;
IIC_Start();//Start signal
IIC_Write(0x90);//Device address + write
if( IIC_Wait_Ack() == 1 )
return -1;
IIC_Write(add);//Register address
if( IIC_Wait_Ack() == 1 )
return -1;
do{
//Timeout check
i++;
if( i > 20 ) return -1;
delay_1ms(1);
IIC_Start();//Resend start signal
IIC_Write(0x91);//Device address + read
}while(IIC_Wait_Ack() == 1);
dat[0]=IIC_Read();//Read upper 8 bits of data
IIC_Send_Ack(0);//Acknowledgment
dat[1]=IIC_Read();//Read lower 8 bits of data
IIC_Send_Ack(1);//Non-acknowledgment
IIC_Stop();//Send stop signal
//Data integration
num = ((dat[0]<<8) | (dat[1]));
//Resolution calculation: measurement voltage range / (2^AD bits - 1)
// Resolution = 4.096/2^15 = 0.000125
// Voltage = acquired ADC value * resolution
if(num>32768)
ret=(65535-num)*0.000125;
else
ret=num*0.000125;
return ret;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Porting Process
Pin Selection
Port to Project
Our goal is to port the example to the ESP32-S3 dev board. Complete driver code has been provided for you. Follow the steps below to complete the porting. For detailed instructions on creating folders and new .c and .h files, refer to section 1.4.2 in the [DHT11 Temperature and Humidity Sensor] chapter; we will not repeat it here. Just note that here we change the file names bsp_dht11.c and bsp_dht11.h to bsp_ads1115.c and bsp_ads1115.h, and the folder name to ADS1115.
Write Code
Write the following in the bsp_ads1115.c file:
#include "bsp_ads1115.h"
#include "stdio.h"
void delay_ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void delay_us(unsigned int us)
{
ets_delay_us(us);
}
/******************************************************************
* Function Name: ADS1115_GPIO_Init
* Function Description: Initialize IIC pins
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: 1100_0010_1000_0011 WriteADS1115(0x01,0xc2,0x83);
******************************************************************/
void ADS1115_GPIO_Init(void)
{
gpio_config_t ads_config = {
.pin_bit_mask = (1ULL<<ADS1115_PIN_SCL)|(1ULL<<ADS1115_PIN_SDA), //Configure pins
.mode =GPIO_MODE_OUTPUT_OD, //Output mode
.pull_up_en = GPIO_PULLUP_ENABLE, //Enable pull-up
.pull_down_en = GPIO_PULLDOWN_DISABLE, //Disable pull-down
.intr_type = GPIO_INTR_DISABLE //Disable pin interrupt
};
gpio_config(&ads_config);
//Write configuration parameters
WriteADS1115(0x01,0xC2,0x83);
}
/******************************************************************
* Function Name: IIC_Start
* Function Description: IIC start signal
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Start(void)
{
SDA_OUT();
SDA(1);
delay_us(5);
SCL(1);
delay_us(5);
SDA(0);
delay_us(5);
SCL(0);
delay_us(5);
}
/******************************************************************
* Function Name: IIC_Stop
* Function Description: IIC stop signal
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Stop(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_us(5);
SDA(1);
delay_us(5);
}
/******************************************************************
* Function Name: IIC_Send_Ack
* Function Description: Host sends acknowledgment
* Function Parameters: 0 acknowledgment 1 non-acknowledgment
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Send_Ack(unsigned char ack)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
if(!ack) SDA(0);
else SDA(1);
SCL(1);
delay_us(5);
SCL(0);
SDA(1);
}
/******************************************************************
* Function Name: IIC_Wait_Ack
* Function Description: Wait for slave acknowledgment
* Function Parameters: None
* Function Return: 1=no acknowledgment 0=acknowledgment received
* Author: LC
* Notes: None
******************************************************************/
unsigned char IIC_Wait_Ack(void)
{
char ack = 0;
unsigned char ack_flag = 10;
SDA_IN();
SDA(1);
delay_us(5);
SCL(1);
delay_us(5);
while( (GETSDA()==1) && ( ack_flag ) )
{
ack_flag--;
delay_us(5);
}
if( ack_flag <= 0 )
{
IIC_Stop();
return 1;
}
else
{
SCL(0);
SDA_OUT();
}
return ack;
}
/******************************************************************
* Function Name: IIC_Write
* Function Description: IIC write one byte
* Function Parameters: dat data to write
* Function Return: None
* Author: LC
* Notes: None
******************************************************************/
void IIC_Write(unsigned char dat)
{
int i = 0;
SDA_OUT();
SCL(0);//Pull clock low to start data transfer
for( i = 0; i < 8; i++ )
{
SDA( (dat & 0x80) >> 7 );
delay_us(2);
dat<<=1;
delay_us(6);
SCL(1);
delay_us(4);
SCL(0);
delay_us(4);
}
}
/******************************************************************
* Function Name: IIC_Read
* Function Description: IIC read 1 byte
* Function Parameters: None
* Function Return: 1 byte of read data
* Author: LC
* Notes: None
******************************************************************/
unsigned char IIC_Read(void)
{
unsigned char i,receive=0;
SDA_IN();//Set SDA as input
for(i=0;i<8;i++ )
{
SCL(0);
delay_us(5);
SCL(1);
delay_us(5);
receive<<=1;
if( GETSDA() )
{
receive|=1;
}
delay_us(5);
}
return receive;
}
/******************************************************************
* Function Name: WriteADS1115
* Function Description: Write dat data to address add of ADS1115
* Function Parameters: add register address to write dat_H upper 8 bits of data to write dat_L lower 8 bits of data to write
* Function Return: 0 write successful 1 no acknowledgment for device address write 2 no acknowledgment for register address write
* 3 no acknowledgment for upper 8 bits data write 4 no acknowledgment for lower 8 bits data write
* Author: LC
* Notes: Device address = 0X90
******************************************************************/
uint8_t WriteADS1115(uint8_t add,uint8_t dat_H,uint8_t dat_L)
{
IIC_Start();
IIC_Write(0x90);
if( IIC_Wait_Ack() == 1 )
{
printf("error 1\r\n");
return 1;
}
IIC_Write(add);
if( IIC_Wait_Ack() == 1 )
{
printf("error 2\r\n");
return 2;
}
IIC_Write(dat_H);
IIC_Wait_Ack();
IIC_Write(dat_L);
IIC_Wait_Ack();
IIC_Stop();
return (0);
}
/******************************************************************
* Function Name: ReadADS1115
* Function Description: Read data from ADS1115
* Function Parameters: add register address to read
* Function Return: -1 read failed other read successful
* Author: LC
* Notes: None
******************************************************************/
float ReadADS1115(unsigned char add)
{
int i =0;
unsigned char dat[2]={0};
unsigned int num = 0;
float ret=0;
IIC_Start();//Start signal
IIC_Write(0x90);//Device address + write
if( IIC_Wait_Ack() == 1 )
return -1;
IIC_Write(add);//Register address
if( IIC_Wait_Ack() == 1 )
return -1;
do{
//Timeout check
i++;
if( i > 20 ) return -1;
delay_ms(1);
IIC_Start();//Resend start signal
IIC_Write(0x91);//Device address + read
}while(IIC_Wait_Ack() == 1);
dat[0]=IIC_Read();//Read upper 8 bits of data
IIC_Send_Ack(0);//Acknowledgment
dat[1]=IIC_Read();//Read lower 8 bits of data
IIC_Send_Ack(1);//Non-acknowledgment
IIC_Stop();//Send stop signal
//Data integration
num = ((dat[0]<<8) | (dat[1]));
//Numerical calculation depends on the PGA configuration
//2 to the 15th power = 32768
//Maximum range set to 4.096
// if(num>32768)
// ret=((float)(65535-num)/32768.0)*4.096;
// else
// ret=((float)num/32768.0)*4.096;
//Resolution calculation: measurement voltage range / (2^AD bits - 1)
// Resolution = 4.096/2^15 = 0.000125
// Voltage = acquired ADC value * resolution
if(num>32768)
ret=(65535-num)*0.000125;
else
ret=num*0.000125;
return ret;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
Write the following in the bsp_ads1115.h file:
#ifndef _BSP_ADS1115_H_
#define _BSP_ADS1115_H_
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_rom_sys.h"
#include "esp_timer.h"
#include "driver/uart.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "driver/gptimer.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include "driver/spi_master.h"
#include "nvs_flash.h"
#define ADS1115_PIN_SCL 1
#define ADS1115_PIN_SDA 2
#define SDA_IN() {gpio_set_direction(ADS1115_PIN_SDA, GPIO_MODE_INPUT);} //SDA input mode
#define SDA_OUT() {gpio_set_direction(ADS1115_PIN_SDA, GPIO_MODE_OUTPUT);} //SDA output mode
#define SCL(BIT) gpio_set_level( ADS1115_PIN_SCL, BIT?1:0 )
#define SDA(BIT) gpio_set_level( ADS1115_PIN_SDA, BIT?1:0 )
#define GETSDA() gpio_get_level( ADS1115_PIN_SDA )
void delay_us(unsigned int us);
void delay_ms(unsigned int ms);
void ADS1115_GPIO_Init(void);
unsigned char WriteADS1115(unsigned char add,unsigned char dat_H,unsigned char dat_L);
float ReadADS1115(unsigned char add);
#endif2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Porting Verification
Enter the following code in main.c:
#include <stdio.h>
#include "bsp_ads1115.h"
void app_main(void)
{
ADS1115_GPIO_Init();
delay_ms(200);
printf("ADS1115 Start....\n");
while(1)
{
//The current maximum range is set to 4.096V
printf("A0 = %.4f\r\n", ReadADS1115(0x00) );//Read the value of A0
delay_ms(300);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
Power-on effect:
Driver code:
File Download
📌 Materials Download Center (click to jump)
📌 In the Materials Download Center -> Module Porting Materials Download, inside the compressed package of this chapter.