Quick guide: ADS1115 on Raspberry Pi

Note that I'm specifically using this device (Well, the 12bit version, but that's a different/Amazon story), ADS1115 16 Bits 4 Channel Analog-to-Digital ADC PGA Converter with Programmable Gain Amplifier High Precision I2C 



First thing is to solder all the pins (Note that if you're only sampling one analog input, you could ignore A1->A3). I soldered male breadboard jumper wires on, rather than the pin header, as that adds even more bulk. 



Next is to connect to the Raspberry Pi. 

ADC (Analog to Digital Converter) to RPi connections:

VDD to 3.3v           - Pin1
GND to GND            - Pin 6
SCL to I2C 1 Clock    - Pin 5
SDA to I2C 1 Data     - Pin 3
ADDR to GPIO<any>     - For me Pin 13, GPIO2/27
ALRT to GPIO<any>     - For me Pin 11, GPIO0/17 


SDA/SCL are the data and clock for i2c.
ADDR is to "address" the ADC device - active high.
ALRT is an alert that something has changed. Input from the ADC. Default: Active Low.

Use 'gpio' or equivalent to set the GPIOs as needed. Pin 13 is OUT and HIGH(1) - which means ADDR is active.

 | BCM | wPi |   Name  | Mode | V | Pin#
 |  17 |   0 | GPIO. 0 |   IN | 1 | 11 |
 |  27 |   2 | GPIO. 2 |  OUT | 1 | 13 |

We should now be able to talk to the device (ensure that you have i2c enabled - using raspi-config, interface options, i2c)

sudo i2cdetect -y 1

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00:          -- -- -- -- -- -- -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: -- -- -- -- -- -- -- -- -- 49 -- -- -- -- -- --

50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

70: -- -- -- -- -- -- -- --


My device shows up at address 49.

Next, we want to read the control register - this is at offset 0x01

sudo i2cget -y 1 0x49 0x01 w
0x8385

After a reset, we *should* see 0x8583h - but due to the endianess, the bytes are swapped. Not a biggie, just need to ensure that we swap when reading/writing.

We need to configure the device to work. Looking at the ADS1115 spec from Texas Instruments, we see the following:

Bit        Value    Notes
15           0      No effect
14->12     100      A0 is all we're using
11->09     010      Default range of +/-2v. May want a larger range
08           0      Continuous-conversion. Make this guy work.

07->05     000      8 samples per second is enough for me
04           0      Traditional
03           0      ALRT is active low
02           0      Do not latch the ALRT pin.
01->00      11      Disable ALRT


So, 0100 0100 = 0x44 and 0000 0011 = 0x03. We want to write 0x4403 to the control register, but due to the endianness, we write 0x0344

sudo i2cset -y 1 0x49 0x01 0x0344 w

We now have the ADC configured, and now we just need to read values:

i2cget -y 1 0x49 0x00 w
0xf07f

As I only have a 12 bit ADC, masquerading as a 16Bit, I'm reading 0x7ff0. But if you've a popper 16 bit, then you should be able to see the complete signed number (as the value can be negative). Also note the endianness requires us to swap the bytes.

To kick off a periodic sample - you can use the following - which is nice enough to re-order the bytes and print out a (unsigned) decimal value.

while true;do v=$(i2cget -y 1 0x49 0x00 w);echo $((0x${v:4:2}${v:2:2}));done

What's A0?


Connected to my A0 input - I've a flame sensor. Just because.




The sensor has Vcc(+)/Gnd and and Analog output. I connect the power to the RPi and the Analog output to the A0 of the ADC ADS1115 device.


+ to 3.3v             - Pin 17
GND to GND            - Pin 39
A0 to A0 on ADC


The complete set of connections on the RPi look like this:




(Note the red wire is the ground on Pin 6, on this picture it's looking suspiciously close to one of the 5v pins - don't do that.)

Scripts

Here's something that can help manage your bits (your control bits). It also set the high/low thresholds. The last section waits for the LOW threshold and reads until it has returned from the LOW threshold.

#!/bin/bash

#1 operational status
OS=0
#3 multiplexer
MUX=111
#3 amplifier
PGA=001
#1 device mode - continuous
MODE=0
#3 sample Rate
SR=000
#1 comparator mode(window)
COMP=1
#1 ALERT pin polarity
POL=0
#1 Latch or not
LAT=1
#2 When to assert
QUEUE=00

# thresholds
LOW=5800
HIGH=7FFF

BYTE1=$(( 2#$OS$MUX$PGA$MODE ))
BYTE1=$( printf "%02x" $BYTE1 )

BYTE2=$(( 2#$SR$COMP$POL$LAT$QUEUE ))
BYTE2=$( printf "%02x" $BYTE2 )
CONFIG=0x$BYTE2$BYTE1

LOW=0x${LOW:2:2}${LOW:0:2}
HIGH=0x${HIGH:2:2}${HIGH:0:2}

i2cset -y 1 0x49 0x02 $LOW w
i2cset -y 1 0x49 0x03 $HIGH w
i2cset -y 1 0x49 0x01 $CONFIG w

#in Window mode - wait for the ALERT when value falls below LOW
p=$(i2cget -y 1 0x49 0x00 w)
while true
do
       gpio wfi 6 falling
       v=$(gpio read 6)
       echo -n $v:
       p=$(i2cget -y 1 0x49 0x00 w)
       echo -n $p:
       while [[ $(gpio read 6) == 0 ]]
       do
               p=$( i2cget -y 1 0x49 0x00 w )
               echo -n "($p)"
       done
       echo
done

Some test scripts - to get status


while true;do gpio wfi 2 both;v=$(gpio read 6);echo -n $v:; p=$(i2cget -y 1 0x49 0x00 w);echo -n $p:;done


i2cget -y 1 0x49 0x00 w;i2cget -y 1 0x49 0x01 w;i2cget -y 1 0x49 0x02 w;i2cget -y 1 0x49 0x03 w




Comments

Popular posts from this blog

Configuring Email on Rasbian Buster (Not Sending Email)

Bash Garage Door Monitor on Raspberry Pi