# Data acquisition with Python on a Beaglebone Black - Increasing sample speed

This is my first foray into programming and using a BeagleBone Black. I have some limited experience in Python, and have used this within the provided Cloud9 IDE in order to capture data and write that data to a pandas dataframe, please see code below.

While the code works, I have tested using the Pins P9_32 and P9_34 with a pair of resistors to generate ~1.29 volts, then reading this voltage as an ADC input on pin P9_40. The sample rate is very slow, 113 - 116 samples per second. The minimum I need for the task I have at hand is approximately 400Hz per channel. While I can sequentially sample channels, I'd prefer to have 4 channels operational for a total of 1600Hz sample rate.

Is a significant increase in the sample rate possible by optimising or altering the Python Code I have? If not, what is the recommend method of data acquisition via the ADC on the beaglebone Black?

import Adafruit_BBIO.ADC as ADC
import pandas as pd
import numpy as np
import time
import matplotlib.pyplot as plt

voltage = value * 1.8 #1.8V

print(voltage)
print(value2)

df_ = pd.DataFrame()

timeout_start = time.time()
timeout = 5 #seconds
print(timeout_start)

def DAQ():
d = []
count = 0
while  time.time() < timeout_start + timeout:
voltage = value * 1.8
d.append((count, time.time(), voltage))
count = count+1
out1 = {'count': count, 'df': pd.DataFrame(d, columns=('count', 'Time', 'Signal Amplitude'))}
return out1

x = DAQ()
count = x['count']
df = x['df']

print('end loop')
print(count, 'number of iterations', count/(time.time()-timeout_start), 'samples per second')
print(df)

print(df['Time'])
print(df['Signal Amplitude'])

#plt.plot([df['Time']],[df['Signal Amplitude']])
#plt.show()

#plt.figure()
#for count in df:
#    plt.plot(n[0], n[1], label=n[2])
#    plt.axis([0,count,0,60])
#plt.legend(loc=0, frameon=False)


Thank you,

P.S. if anyone can provide guidance on plotting graphs on the BBB I would appreciate it.

• I haven't a clue, but I think you should add into your question your calculated acquisition time. That will determine the absolute max. – Transistor Jan 20 '18 at 10:43
• Hi Transistor, If I understand your question correctly; I've set the sample duration to 5 seconds for testing. In practice this may change depending on the sampling rate I can achieve. – chopboy Jan 20 '18 at 10:51
• No I mean how long does it take to acquire 1 ADC conversion. E.g. 150 us. – Transistor Jan 20 '18 at 10:53
• I think you need to check the library for a way to request blocks if data. Requesting individual values limits you to the speed of your loop - which will vary depending on what else the processor is doing. – JRE Jan 20 '18 at 10:58
• Not so sure if the installed operating system (non realtime) and python script is a way to do high speed real time processing. – Marko Buršič Jan 20 '18 at 11:15

The library you are using is not capable of doing what you want. It can only deliver single values as fast as your loop can read them.

You need a different library that can access the hardware better.

The beaglebone black has what is called a programmable real-time unit (PRU.) These can be programmed to do things that need to be done quickly - like sampling the ADC at high speed.

PyPRUSS gives access to all the PRU functions with a Python API. It may be overkill for what you need.

There's also beaglebone_pru_adc which wraps just access to the PRU ADC functions. It can deliver single values on request, but it also has what the developer calls "oscilloscope" mode, in which it takes a bunch of samples and delivers the them all back in one packet.

One or the other of those two ought to do the trick.

• An Interim update in case anyone else is looking for a similar solution: beaglebone_pru_adc seems to be dead as the last update was 2014, and last comments about 2016. It does not seem to function at present, as an ADC read on pin 0 influences the voltages on all downstream pins. github.com/pgmmpk/beaglebone_pru_adc/issues/8 – chopboy Jan 23 '18 at 21:46