Skip to content

2 simultaneous differential channels #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1nfinity-5starZ opened this issue Nov 6, 2019 · 9 comments
Closed

2 simultaneous differential channels #46

1nfinity-5starZ opened this issue Nov 6, 2019 · 9 comments
Assignees

Comments

@1nfinity-5starZ
Copy link

1nfinity-5starZ commented Nov 6, 2019

Hello, i've been trying to setup 2 differential channels at the same time but i'm not sure if the code I wrote is quite right, couldn't find in the docs either.

image
I plotted the graph of the readings and somehow they appear to be related even if i'm reading completely different sources.

Here is the code i built so far:

import time
import board
import busio
import json

import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.ads1x15 import Mode
from adafruit_ads1x15.analog_in import AnalogIn

# Data collection setup
RATE = 860
SAMPLES = 1720
GAIN = 1

# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000)

# Create the ADC object using the I2C bus
ads = ADS.ADS1115(i2c)
ads.gain = GAIN

# Create differential input between channel 0 and 1
chan = AnalogIn(ads, ADS.P0, ADS.P1)
chan2 = AnalogIn(ads, ADS.P2, ADS.P3)

# ADC Configuration
ads.mode = Mode.CONTINUOUS
ads.data_rate = RATE

while True:

  mx = 0
  mx2 = 0

  for i in range(SAMPLES):
    cur = chan.value
    if cur>mx:
      mx=cur

  mx = round(mx*potFactor)
  print("CH1: ", mx)

  for i in range(SAMPLES):
  cur = chan2.value
    if cur>mx2:
      mx2=cur

  mx2 = round(mx*potFactor)
  print("CH1: ", mx2)

  time.sleep(60*30);
@caternuson
Copy link
Contributor

Looks OK at a first glance. Do you really need continuous mode? It doesn't look like you are actually storing the values in your sampling loop. Just saving the max. Can you describe your use case.

@1nfinity-5starZ
Copy link
Author

Yeah sure, I should have given more details.
I need continuous mode because i'm reading an alternate current generator at 60Hz, so i grab the maximum value read at 860 samples per second in a 2 second interval and is probably safe to assume that the peak value will be stored.
I also skip calculating the actual Root Mean Square value because I know the wave is a sine function.

@caternuson
Copy link
Contributor

Is your hardware already embedded, or can you do some bread board testing of the ADS?

@1nfinity-5starZ
Copy link
Author

Great idea. I might plug in a potentiometer on each channel and simulate a random signal by turning the knobs and trying to log on screen if the changes make sense. I'll let you know when I'm done. Thanks !

@caternuson
Copy link
Contributor

Also just to make sure the basics works. Try that with single shot. Then try continuous. Etc.

Continuous is tricky and this library doesn't really support it well. Lot's of discussion here:
#27

@1nfinity-5starZ
Copy link
Author

1nfinity-5starZ commented Nov 8, 2019

Ok so a bit of testing and i came to some results:

First change was I decided to actually store all the values instead of the max.

Then, trying to read them in the same loop (simultaneously) didn't work at all:

Loop:

while True:
    data1 = [0]*SAMPLES
    data2 = [0]*SAMPLES
    
    for i in range(SAMPLES):
        data1[i] = chan1.value
        data2[i] = chan2.value

    mx = round(max(data1)*potFactor)
    mx2 = round(max(data2)*potFactor)
    print("CH1: ", mx)
    print("CH2: ", mx2)

Log:
CH1: 550
CH2: 558
CH1: 560
CH2: 561
CH1: 555
CH2: 564
CH1: 99
CH2: 98
CH1: 100
CH2: 99
CH2: 97
CH1: 92
CH2: 97
CH1: 578
CH2: 575
CH1: 564
CH2: 568
CH1: 564
CH2: 568
CH1: 93
CH2: 102

Here it's visible that the results are duplicated (I was turning a 500W load on and off which was connected to only one channel).

But if i read them in separate loops with a timeout in between, it came out way closer than the expected:

while True:
    data1 = [0]*SAMPLES
    data2 = [0]*SAMPLES
    
    for i in range(SAMPLES):
        data1[i] = chan1.value
    
    time.sleep(5);
        
    for i in range(SAMPLES):
        data2[i] = chan2.value

    mx = round(max(data1)*potFactor)
    mx2 = round(max(data2)*potFactor)
    print("CH1: ", mx)
    print("CH2: ", mx2)

CH1: 98
CH2: 17
CH1: 87
CH2: 19
CH1: 94
CH2: 19
CH1: 567
CH2: 18
CH1: 563
CH2: 21
CH1: 561
CH2: 18
CH1: 551
CH2: 17

The 500W peaks appear in only one channel.
Hope this helps somehow.

And by the way i did a bread board testing using a potentiometer, splitting 4V across the channels and the readings were accurate, so the inputs are working fine (for DC).

@caternuson caternuson self-assigned this Nov 8, 2019
@1nfinity-5starZ
Copy link
Author

@caternuson apparently the time.sleep(5) between reading the channels solved the issue. Here is the new plot and I'm way happier with the results:

image

@caternuson
Copy link
Contributor

Glad it's working a little better. It may not be the time.sleep, but just the separation of the channel readings. You can only do fast continuous readings on one channel (or differential channel) at a time, so should have only one read in the loop.
NO:

    for i in range(SAMPLES):
        data1[i] = chan1.value
        data2[i] = chan2.value

YES:

    for i in range(SAMPLES):
        data1[i] = chan1.value
    for i in range(SAMPLES):
        data2[i] = chan2.value

The way it works is it keeps track of the last channel read. If you read the same channel again, it bypasses a lot unnecessary setup and subsequent I2C traffic:
https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/master/adafruit_ads1x15/ads1x15.py#L153

But synchronizing the reads with ADC conversion completion is still an issue. The library currently has no mechanism for doing that.

@1nfinity-5starZ
Copy link
Author

Thanks, I think it's clear now what the problem was. Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants