0
\$\begingroup\$

Hello I am using an ADS1115 to read a current on a SCT-013-030 based on an example setup by the manufacturer.

I have followed the setup where i have to use differential mode, and connected to the end of the transducer to A0 and A1.

What I am expecting is a graph that is a sine wave ( or relatively close to looking one), basing from the analogy that since the SCT-13-030 is a current transducer the voltage reading i should get from it should relatively look like a since wave, since the current of Mains line is a sine wave too.

Here is my code, I am using Python in MU on a Raspberry Pi 4

import board
import busio
i2c = busio.I2C(board.SCL, board.SDA)

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

ads = ADS.ADS1115(i2c,data_rate=475,mode=256)


chan = AnalogIn(ads, ADS.P0, ADS.P1)

import time
arrays = []
arrays2 = []

t_end = time.time() + 1

while time.time()<t_end:
    arrays.append(chan.value)
    arrays2.append(chan.voltage)

for x in arrays:
    print((arrays2[x]*1000,0))

and here is my output graph

enter image description here

I could not tell if this is the actual reading off a current from the transducer ( unfortunately i have no access to an oscilloscope ) or noise or even my programming.

The load i am using is a soldering iron.

I have tried running the program with no load and i am getting a reading of 0volts with some noise spikes here and there that are less than 0.1 which is acceptable, which led me to believe that those value are actual readings.

\$\endgroup\$
3
  • \$\begingroup\$ Not sure how sensitive the compiler is, but shouldn't import AnalogIn be on a new line? \$\endgroup\$
    – Huisman
    Oct 26, 2019 at 5:08
  • \$\begingroup\$ Try to make a reading from a battery voltage first. It's an easier test your circuit works as the voltage should be stable and having way less noise. \$\endgroup\$
    – Huisman
    Oct 26, 2019 at 5:14
  • \$\begingroup\$ from - import is a thing in python, also that code is from adafruits official guide. For the battery voltage test, it actually read the correct voltage. I actually thought up of another test i can do while i was writing this, im going to hook it up to my arduino analog pins \$\endgroup\$
    – Jake quin
    Oct 26, 2019 at 5:34

1 Answer 1

2
\$\begingroup\$

I like Python, and I use it in my own projects.

I wouldn't depend on a Python loop that reads an ADC value through who knows how many layers of libraries and operating system drivers to deliver anything like a consistent sampling rate, let alone a fast rate.

If you check the adafruit_ads1x15 github repository, you'll find a "fast read" example.

That example shows how to set your ADC to continuous mode and how to get fast communication with the ADC.

It also shows how to rearrange your Python code to get a bit of a speed boost.

The code of the example is fairly short so I'll post it here:

    import time
    import board
    import busio
    import adafruit_ads1x15.ads1015 as ADS
    from adafruit_ads1x15.ads1x15 import Mode
    from adafruit_ads1x15.analog_in import AnalogIn
    
    # Data collection setup
    RATE = 3300
    SAMPLES = 1000
    
    # Create the I2C bus with a fast frequency
    i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000)
    
    # Create the ADC object using the I2C bus
    ads = ADS.ADS1015(i2c)
    
    # Create single-ended input on channel 0
    chan0 = AnalogIn(ads, ADS.P0)
    
    # ADC Configuration
    ads.mode = Mode.CONTINUOUS
    ads.data_rate = RATE
    
    data = [None]*SAMPLES
    
    start = time.monotonic()
    
    # Read the same channel over and over
    for i in range(SAMPLES):
        data[i] = chan0.value
    
    end = time.monotonic()
    total_time = end - start
    
    print("Time of capture: {}s".format(total_time))
    print("Sample rate requested={} actual={}".format(RATE, SAMPLES / total_time))

The primary "tricks" are:

  1. The high I2C clock rate
  2. Setting the ADC to continuous mode
  3. Preallocating an array for the data rather than appending to lists.

Note that you'll need check the sampling rates and such if you use that example.

I originally checked the github source because I had hoped the library would have a method to request blocks of data from the ADC. Such a method could be implemented in the drivers, and deliver large blocks sampled at a high, consistent rate.

The "fast read" example seems to be about all the consideration that was given to speed, though.


Even if you get it operating fast enough and consistently enough, you may be disappointed with the appearance of your sine wave.

50 Hz works out to 10 data points per cycle at the sampling rate (475 samples per second) you are using.

Even at the maximum sampling rate of 860 samples per second you will only get 17 samples for each cycle of your 50 Hz sine wave.

It might be enough for whatever math you need to do with it, but it will look all rough and zig-zaggy in an oscilloscope style view like you posted in your question.


I often use Python to do real time stuff with audio. The difference is that the drivers for the sound cards deliver the data in blocks rather than being collected in a python loop, and all actual processing is done using numpy rather than in straight python.

Done that way, the bottleneck is the display rather than the collecting and processing of the audio.

\$\endgroup\$
1
  • \$\begingroup\$ Hello, I apologies for the late reply but i actually read your answer in my email, with the code you gave me i actually was able now to get a relatively close to a sine wave signal thank you very much. I did not see this example, i had to modify it with ads1115 and change it to differential mode which was easy now \$\endgroup\$
    – Jake quin
    Oct 29, 2019 at 4:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.