Problems in reading a sine wave from an ADS1115
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:


The high I2C clock rate
Setting the ADC to continuous mode
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.