This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using ADS1115 in differential mode
#1
Hi, 
I have set up a configuration using ADS 1115 in differential mode.
This is suggested for some applications by the well known American
company Adafruit. They also supply a nice library for Pi (and Arduino
if you are not satisfied with 10 bits). 

My application is current measurement using Hall effect sensor (often referred 
to as current transformer, commonly used for AC) and measurement of 12V using a 
ladder which isolate both high amp +12V and GND (12V) system from the low voltage 
system on the Pi yacht server. See: 
https://sites.google.com/site/olewsaa/ya...ry-monitor
I plan to use several Hall effect sensors to keep track of current flowing and 
monitor the batteries. I do not want to bring in neither 12V nor GND from the 
high amp service 12V supply into the computer system / Pi. 
 
For background and overview of my project see:
https://sites.google.com/site/olewsaa/ya...-raspberry


So far I have interfaced this setup into openplotter  by writing an extra file:
differential_ads1115.py which is referenced from the setup file like this in 
the openplotter.conf :
[TOOLS]
py = [['Differential ads1115', 'put analog values to SignalK', 'differential_ads1115.py', '1'],['Analog ads1115', 'put analog values to SignalK', 'analog_ads1115.py', '0'], ['Analog Firmata', 'put analog values to SignalK', 'oppymata.py', '0'], ['SignalK Simulator', 'change values with sliders and send values to SignalK', 'SK-simulator.py', '0'], ['Auto Setup', 'configure basic system', 'autosetup_tty.py', '1']]

It shows up with an extra button.
In addition I have introduced two new entries in the 
tools/openplotter_analog.conf file :
[ADS1115_4]
active = 1
gain = 0
samples = 6
sk_name = electrical.batteries.current

[ADS1115_5]
active = 1
gain = 4
samples = 6
sk_name = electrical.batteries.voltage


So far none of the values are included and read into the differential_ads1115.py. 
This differential_ads1115.py file still have the things coded in the file 
and it's functions. Some relevant parts look like:


#
# Quick and dirty hack for differential measurements using ADS1115        
# Put the settings here before moving them  to config files.
GAIN_0 = 4 # 1 = +/-4.096V 2 = +/-2.048V 4 = +/-1.024V
GAIN_3 = 1 #
#
# Note you can change the differential value to the following:
#  - 0 = Channel 0 minus channel 1
#  - 1 = Channel 0 minus channel 3
#  - 2 = Channel 1 minus channel 3
#  - 3 = Channel 2 minus channel 3
#
#        


# Define functions to get the current i and voltage u.
# Eventually the settings parameters will be read from the
# config file.

def get_i():
    offset_0=200
    val=adc.read_adc_difference(0, gain=GAIN_0, data_rate=8)

#  Large Hall element, http://www.yhdc.com/en/product/379/ 50A version.
#  Pins from edge Vref Vout 0V Vdd
#  Linear regression, cal using multimeter.
#  y (current) = -0.52372 + 0.0024236 * x (counts)

    i = -0.52061 + 0.0024236 * val
    return i

def get_u():
    offset_3=1
    val=adc.read_adc_difference(3, gain=GAIN_3, data_rate=8)

    val=val-offset_3
    # 10k/54k=0.185185 ; rounded to 0.1841 after cal with voltmeter.
    u=(((float(val)/float(32768))*4.096)/0.1841) 
    return u

<snip>


else:
index+=1
if index>5: index=4

                        if index == 4:
                                a_value[index]=get_i()
                        else:
                                a_value[index]=get_u()                           
#                        print(index,a_value[4],a_value[5])

It all works fine and I and U display nicely on the instrumentpanel on 
the web page at port 3000.


There is a potential problem by setting the 
[ADS1115_4]
active = 1

and the [ADS1115_5 entry ad the normal ads1115 file will try to process it. 
I could us 2 as the code for active in the differential file and it would 
be taken as not 1 within the analog ads1115 file. Not a very clean way. 

This brings me to the question of the best way of setting this up and how the 
openplotter developers thinks this should be addressed ?

In due time the differential functions with it's parameters in the  
openplotter_analog.conf would be forwarded to the relevant processing scripts.

I would like to get some guidelines on how I should proceed in order
for the differential code should be written in order to get it included in the repository.


Regards,
Ole W. Saastad
https://sites.google.com/site/olewsaa/home
Reply
#2
It sounds intresting and we can try to put it into the repository. (At the moment I have not enough time to completly understand the prog and the problem)
Have you got a circuit diagram?

You have understood how to easily integrate own modules in OpenPlotter!
Regards,
E-Sailing
Reply
#3
(2017-05-03, 11:17 PM)e-sailing Wrote: It sounds intresting and we can try to put it into the repository. (At the moment I have not enough time to completly understand the prog and the problem)
Have you got a circuit diagram?

You have understood how to easily integrate own modules in OpenPlotter!
Regards,
E-Sailing

Cool,
I am still writing on the code, it should be some more streamlined before I forward the code to you. I'll try to prepare a diagram and documentation on how I wire up the ADS1115 for differential measurement for both Hall current sensors and voltage measurement.

I am still not sure if it should be merged into the original ADS1115 code (using only one entry in the GUI) or as I have made it now with an extra entry in the GUI. It is easier to use an extra python script for the differential mode, but keeping the config file as before. I use active=2 in the config file for the entries that apply to the differential case, while the single ended are assigned 1, still not active is 0.

I still have not figured out how I should deal with more than one ADS1115 in differential mode, there can be up to 4 ADS1115 on the I2C bus.

Regards,
Ole
Reply
#4
We haven't used the python library from adafruit.

If you change line 149 in file ads1115.py
config = 0x8103 + 32*self.samples[channel] + 512*self.gain[channel] + (channel+4)*4096
into
config = 0x8103 + 32*self.samples[channel] + 512*self.gain[channel] + (channel)*4096
then you are in differential mode.
Everytihng else should work the same.

At the moment we calculate the address and the channel
to simplify this we could use two arrays
ADS1115_address = [0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x4A,0x4A,0x4A,0x4A,0x4B,0x4B,0x4B,0x4B]
channel = [0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3]

Value of Input 11 (of 0-15) is on third ads1115 with the address 0x4A and the channel 3

In differential mode the channel have the follwing meaning as you already wrote
# Note you can change the differential value to the following:
# 0 = Channel 0 minus channel 1
# 1 = Channel 0 minus channel 3
# 2 = Channel 1 minus channel 3
# 3 = Channel 2 minus channel 3

everything should be fine
Reply
#5
Thanks for the update, the lines setting the config word configure the ADS1115 into single ended and differential, I am not familiar with the control word written to the ads1115. I have just used the Adafruit lib where this hidden behind the scenes. While it's simple to set the control word to the ads 1115 is single ended or differential, one might want to keep a single Ads1115 class in the ads1115.py file.

The choice to use single  ended or differential could be selected in the config file. and not as I'm doing make an extra file  differential_ads1115.py and an extra box in the GUI. A line in the config file, something like  active =  N where N is 1 for single ended and 2 for differential, or a bit more intuitive by introducing a new line like differential=0 for single ended and 1 for differential.  The the config word could be set as above.  Some check should be performed so that each ads1115 only can be put in the mode once, like
[ADS1115_1]
differential=0
[ADS1115_2]
differential=1
or things like
[ADS1115_4]
differential=1 # impossible as there are only two inputs in differential mode.

For the different addresses your proposal is fine, it's quite easy to follow for users. It just need to be documented as users need to know which address they need to set on the ads1115 when deviating from the default. I'm not sure if jumping over a range by going from 0,1,2,3 to 12,13,14,15 if the user set up two ads1115 at 0x48 and 0x4b.

I have used linear regression and supply an offset (added to the value from ads1115) and an intercept and a offset. The adjust_points  and adjust cover this as is, the only suggestion is that adjust_points might make polynomial or spline function to interpolate (maybe this a overkill ?).
Reply
#6
Code:
[ADS1115_4]
differential=1 # impossible as there are only two inputs in differential mode.

No it isn't impossible. There are 4 differential modes!!!
# 0 = Channel 0 minus channel 1        [ADS1115_1]
# 1 = Channel 0 minus channel 3        [ADS1115_2]
# 2 = Channel 1 minus channel 3        [ADS1115_3]
# 3 = Channel 2 minus channel 3        [ADS1115_4]

(you can measure up to 3 differentials not only 2!)


[quote pid='1612' dateline='1494447747']
I have used linear regression and supply an offset (added to the value from ads1115) and an intercept and a offset. The adjust_points  and adjust cover this as is, the only suggestion is that adjust_points might make polynomial or spline function to interpolate (maybe this a overkill ?).
[/quote]

Well if you use adjust_points, you don't need the offset.
The gui input of the adjust_points is only done for mcp3008 under the tab SPI. It can show you a graph of your adjust_points.
You can enter the adjust_points there and copy the line adjust_points = [...] from openplotter.conf to openplotter_analog.conf

In future we should add "differential=1" to the conf file. Thanks.
Reply
#7
(2017-05-10, 11:20 PM)e-sailing Wrote:
Code:
[ADS1115_4]
differential=1 # impossible as there are only two inputs in differential mode.

No it isn't impossible. There are 4 differential modes!!!
# 0 = Channel 0 minus channel 1        [ADS1115_1]
# 1 = Channel 0 minus channel 3        [ADS1115_2]
# 2 = Channel 1 minus channel 3        [ADS1115_3]
# 3 = Channel 2 minus channel 3        [ADS1115_4]

(you can measure up to 3 differentials not only 2!)


[quote pid='1612' dateline='1494447747']
I have used linear regression and supply an offset (added to the value from ads1115) and an intercept and a offset. The adjust_points  and adjust cover this as is, the only suggestion is that adjust_points might make polynomial or spline function to interpolate (maybe this a overkill ?).

Well if you use adjust_points, you don't need the offset.
The gui input of the adjust_points is only done for mcp3008 under the tab SPI. It can show you a graph of your adjust_points.
You can enter the adjust_points there and copy the line adjust_points = [...] from openplotter.conf to openplotter_analog.conf

In future we should add "differential=1" to the conf file. Thanks.
[/quote]


It's correct that both offset and adjust are essential the same, it's just that the linear regression produce a constant term even after trying to set the ADC count to zero for zero signal. Only one of them are needed, the offset can incorporate any offset in the ADS count. I'm still thinking about times when a linear fit would not be enough, a polynomial fit or a spline function. The adjust_points = [[100.0,0.0],[5000.0,90.0],[9000.0,100.0]] array is an easy way to provide input to a spline function that uses an x and y array and provide a function y=f(x) for any x in the given interval regardless of linearity or not for the x,y values. I'll be happy to write the spline function code.

Using the ADS in differential mode provides only two inputs, I review the documentation today.

https://cdn-shop.adafruit.com/datasheets/ads1115.pdf
Under features the datasheet states : "FOUR SINGLE-ENDED OR TWO DIFFERENTIAL INPUTS (ADS1115)" .

https://learn.adafruit.com/adafruit-4-ch...onnections
"Differential Connections:
Differential measurements use a pair of input pins, either A0&A1 or A2&A3." 

The comments in the source code above is misleading as it can be read as it is possible to have 4 differential inputs.

Should the differential code be merged into the classes in tools or as I have it now as a separate file ? The latter is already working and very simple to include, but not very elegant. It's the same chip just different ways of electrical connections and usage. I can supply the differential_ads1115.py file is needed.

I plan to set up several ADS1115s so addressing the individual chips in the config file as proposed is a good plan.


Ole
Reply
#8
Using the ADS1115 with Hall effect current sensors and to measure voltage practically isolated from the live 12/24V system.

I have make short addition to my documentation about my Yacht computer project, https://sites.google.com/site/olewsaa/ya...-raspberry about using a Hall effect current sensor with the ADS1115 in differential mode : https://sites.google.com/site/olewsaa/ya...all-sensor

Specially when using a sensor that yield the output as a voltage difference, zero voltage for zero signal end negative for one direction and positive for the opposite direction. This is exact what one want to monitor the battery bank. A nice benefit is that there is no danger in overloading a Hall effect sensor. The current only go through it's normal wire. The sensor will just be saturated.


As for voltage, I have updated a page that show how I suggest doing to to minise the problems in case of some short circuit or other stray currents.
See this web page for details: https://sites.google.com/site/olewsaa/ya...measuremet



Ole
Reply
#9
I am very interested in using the ads1115 in differential mode. I don't see that this has been implemented in 0.17. Does anyone have working code?

Tom
Reply
#10
Hi,
I have been working on this for some time. I did implement the differential mode in OpenPlotter. I also submitted the code.
However, I have now switched to an Internet of Things on Board (IoToB) approach. I will try to avoid running cables around the boat
if I can avoid it. Most of my work is documented and all source code are available. ESP32 together with SignalK is a revolution, it's
so easy to implement IoToB devices. OpenPlotter happily accept the data and display nicely.

Please see: https://sites.google.com/site/olewsaa/ya...-raspberry and for differential mode :
https://sites.google.com/site/olewsaa/ya...all-sensor

Source code : https://github.com/olewsaa/Yacht-computer

All the best,
Ole
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)