Electrical – python – Data acquisition with Python on a Beaglebone Black – Increasing sample speed

adcbeaglebonepython

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

ADC.setup()
value = ADC.read("P9_40")
voltage = value * 1.8 #1.8V
value2 = ADC.read_raw("P9_40")

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:
        value = ADC.read("P9_40")
        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.

Best Answer

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.