I wanted to measure voltage with command chan =
and write the voltage value to array which has dimensions 128x128 and contains 16384 voltage values. I set ADS1115 sample rate to 128 samples per second. The time of data acquisition should be 128 seconds x 128 samples = 16384 total samples.
The problem is that the program is not working for 128 seconds and it stops much earlier. I suppose, there are some problems elsewhere.
The code look like this:
import numpy as np
import time
from matplotlib import pyplot as plt
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
from timeit import default_timer as timer
i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
ads.gain = 8
ads.mode = ADS.Mode.CONTINUOUS
ads.data_rate = 128
chan = AnalogIn(ads, ADS.P0, ADS.P1)
trig = AnalogIn(ads, ADS.P2, ADS.P3)
level = 192 # trigger level
totalElapsed = 0
buffer = []
while True:
if (trig.value > level):
start = timer()
thisTime = timer() - start
while(len(buffer) < 16384):
buffer.append(chan.value)
totalElapsed += thisTime
print(">>>>>>>>>>>> Total Elapsed: " + str(totalElapsed) + "s")
# Make into numpy array and reshape to (128,128)
a = np.array(buffer).reshape((128,128))
# Reverse alternate rows
for r in range(1,128,2):
a[r] = a[r][::-1]
#Generate image
plt.imsave('/home/rpi/Downloads/mystm_pic.tiff', a, cmap='afmhot') # file location
plt.imshow(a, cmap='afmhot')
plt.show()
To sum up, I want to measure voltage and write its value to array until the array is fully filled, i. e. 16384 written measured voltages in time 128 seconds, assuming speed of 128 samples/second.
Thank you very much for help and your suggestions.
Edit:
The correct code should like this?
import numpy as np
import time
from matplotlib import pyplot as plt
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
from timeit import default_timer as timer
RATE = 128
SAMPLES = 16384
i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
ads.gain = 8
ads.mode = ADS.Mode.CONTINUOUS
ads.data_rate = RATE
chan = AnalogIn(ads, ADS.P0, ADS.P1)
trig = AnalogIn(ads, ADS.P2, ADS.P3)
level = 192 # trigger level
sample_interval = 1.0 / ads.data_rate
repeats = 0
skips = 0
data = [None] * SAMPLES
start = time.monotonic()
time_next_sample = start + sample_interval
if (trig.value > level):
for i in range(SAMPLES):
while time.monotonic() < (time_next_sample):
pass
data[i] = chan.value
# Loop timing
time_last_sample = time.monotonic()
time_next_sample = time_next_sample + sample_interval
if time_last_sample > (time_next_sample + sample_interval):
skips += 1
time_next_sample = time.monotonic() + sample_interval
# Detect repeated values due to over polling
if data[i] == data[i - 1]:
repeats += 1
end = time.monotonic()
total_time = end - start
# Make into numpy array and reshape to (128,128)
a = np.array(data).reshape((128,128))
# Reverse alternate rows
for r in range(1,128,2):
a[r] = a[r][::-1]
print(">>>>>>>>>>>> Total Elapsed: " + str(total_time) + "s")
#Generate image
plt.imsave('/home/rpi/Downloads/mystm_pic.tiff', a, cmap='afmhot') # file location
plt.imshow(a, cmap='afmhot')
plt.show()
When you request AnalogIn.value
, you’ll get the latest measured value. If you call this in quick succession, you’ll simply repeatedly get the same measurement - it does not automatically wait for the ADC to finish reading. Thus, by calling it in a loop, you’re just going to fill the buffer as quickly as the Pi can perform 16384 I2C reads to your ADC.
As far as I can tell, the AdaFruit drivers don’t have any mechanism to properly synchronize with the ADC. Thus, you’ll have to implement your own timing setup: in each loop, you will want to delay for 1/128 seconds before the next read. You can do this by checking time.monotonic() in a loop; that will be more reliable than using time.sleep().
See https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/main/examples/ads1x15_fast_read.py for a complete example of the timing loop in action.