ADS1115 sampling issues
Moderators: adafruit_support_bill, adafruit

ADS1115 sampling issues

by ashurbr on Mon Jan 21, 2013 4:11 pm

First, I think I have read all the relevant posts about the ADS1115, and I think this is a different issue (but maybe not). The background: I am trying to sample data at a fixed rate (256 samples per second exactly) on one channel. I set the ADS1115 config register to 0x40E3, which should cause it to sample at 860SPS, using AIN0 to GND, continuous mode with FS = 6.114 V. This seems to be fine. I send the config register once, and then start polling for data. At which point I have two problems, which may be related.

The problems:
1. Running the a python script (modified from the Adafruit example and based on SMBus) with a 1 second total sampling time results in anywhere between 230 and 260 samples being collected. I.e., running the same script over and over produces different effective sampling rates.
2. Samples are lost in the collection.

The evidence:

I observe SCL on a scope, and the missing data are commensurate with loss of the clock signal. I am using a 5 Vpp triangle waveform, cycling at 1 Hz with 2.5 VDC offset.

Some notes: Take a look at Image. Looks pretty good, right? I thought so, until I plotted the data with points: Image. Note the missing data around 0.8 sec, 4.5 sec, 5.5 sec and 9.5 sec. I need an explanation for this. And it's not just individual points. See Image. From about 118.5 to 119 seconds, there is no data.

Here is the core of the Python script I was using to collect the data:

Code: Select all | TOGGLE FULL SIZE
adc = ADS1115()
INTERVAL = 1/340.0
COLLECT_INTERVAL = 1000

counter = 0
time_last_read = time.time()
adc.configADCSingleEnded()

start_time = time.time()
while (time.time() - start_time < COLLECT_INTERVAL):
  etime = time.time() - time_last_read
  if (etime > INTERVAL):
    counter = counter + 1
    result = adc.readADCSingleEnded()
    print time.time() - start_time, "\t %.6f" % ((result * 0.1875) / 1000.0), "\t", counter, etime
    time_last_read = time.time()

#  print num, "\t", result
etime = time.time()
print etime - start_time


I know it is not elegant or following good coding practices. I have adjusted the I2C clock frequency (using 'baudrate' option in kernel module i2c_bcm2708), and used 100K, 400K and 1M Hz - no qualitative difference in the observations.

The request:

In summary, here are my questions:
1. Why does there appear to be dropped data?
2. How (or Can) the timing be controlled to sample exactly 256 times per second?

Thanks in advance for any/all the help.

PS - I buy lots of stuff from Adafruit, and as an educator, am delighted to see a business that also cares about education and is willing to help its customers. Thanks for all you do!
PPS - this is my first post, so I apologize in advance if I have done something wrong.
ashurbr
 
Posts: 16
Joined: Fri Jun 29, 2012 3:14 pm

Re: ADS1115 sampling issues

by adafruit_support_bill on Mon Jan 21, 2013 5:08 pm

I'm not an expert in Python internals, but it is an interpreted language with features like automatic garbage collection which make it nearly impossible to do deterministic real-time programming. On a fast enough processor it may do well most of the time, but when it decides to do some housekeeping, all bets are off.
User avatar
adafruit_support_bill
 
Posts: 30796
Joined: Sat Feb 07, 2009 10:11 am

Re: ADS1115 sampling issues

by ashurbr on Mon Jan 21, 2013 7:21 pm

OK - fair enough. I assume that C++ would be better - compile the executable and run it. That was my first choice, but my problem with that was finding the right I2C header and libraries (for C++) for the Raspberry Pi. If C++ would be better, can you point me to a resource?

Thanks in advance!
ashurbr
 
Posts: 16
Joined: Fri Jun 29, 2012 3:14 pm

Re: ADS1115 sampling issues

by ashurbr on Tue Jan 22, 2013 1:11 am

An update.

I wrote an data sampler in C/C++ instead of the Python script. Same effects. I pared the code down to nothing but the timing loop and that seems to be the issue. I let the timing code run for two minutes. When the Pi was quiescent, about 0.5% of the readings took too long. With moderate other activity, anywhere from 1% to 3% of the readings would take too long. With severe other activity (loading Midori, or Arduino, etc.,) upwards of 5% of the readings would take too long. Is there any way to get a handle on the Pi and make it pay more attention to the running code?

Thanks in advance.
ashurbr
 
Posts: 16
Joined: Fri Jun 29, 2012 3:14 pm

Re: ADS1115 sampling issues

by adafruit_support_bill on Tue Jan 22, 2013 6:55 am

Timing loops only work if you can guarantee there are no other threads in the system with significant CPU load. You can play with thread priorities to try to force yourself to the front of the pack. But the better approach for what you are attempting is to use timer interrupts to invoke your sensor readings.
User avatar
adafruit_support_bill
 
Posts: 30796
Joined: Sat Feb 07, 2009 10:11 am