2

For a chemistry research project at my school, we are using the ADS8320 data sheet found: here, to take in volatage readings from a potentiometer at a very fast rate. We are working off of a raspberry Pi 3 and are trying to take the data in through the GPIO and SPI pins on the Pi. I was able to do this using this code in python:

import time
import os
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

start = time.time()

PIN_CLK = 11
PIN_DO = 9
PIN_DI = 10
PIN_CS = 8

GPIO.setup(PIN_DI, GPIO.OUT)
GPIO.setup(PIN_DO, GPIO.IN)
GPIO.setup(PIN_CLK, GPIO.OUT)
GPIO.setup(PIN_CS, GPIO.OUT)

def getADC(channel):
    GPIO.output(PIN_CS, True) #used to clear last transmission
    GPIO.output(PIN_CS, False) #Bringing cs to low

    GPIO.output(PIN_CLK, False) #starting the clock

    for i in [1,1,channel]: #start of a new bit assignment
        if (i==1):
            GPIO.output(PIN_DI, True)
        else:
            GPIO.output(PIN_DI,True)

        GPIO.output(PIN_CLK, True)
        GPIO.output(PIN_CLK, False)

    ad = 0
    for i in range (18):
        GPIO.output(PIN_CLK, True)
        GPIO>output(PIN_CLK, False)
        ad <<= 1
        if (GPIO.input(PIN_DO)):
            ad |= 0x1

    GPIO.output(PIN_CS, True) #reset

    return ad

if __name__ == "__main__":
    while True:
        bitReading = getADC(0)
        Data = float(bitReading/65535.0*3.3)
        getTime = float(time.time() - start)
        print ("%.5f" % getTime + "," + "%.5f" % Data)
        time.sleep(0)

The main issue with this code is that while I am able to take in data, it is much slower than what I would expect. From the data sheet it says that it runs at around 100Khz, but the issue is that currently it is taking in in milliseconds. How would I speed up this code? I am a complete beginner to coding and most of the working code I have is taken from sites I found from googling. I've seen things about spidev, but I'm not sure how to implement them. Any help on this would be great, as I'm a chem major not a comp sci major so I am wayyyyyyy out in the deep end for this problem. If you have any questions or if I'm missing any crucial information please let me know!

Samsanit
  • 25
  • 4
  • Briefly checked out the spec, under 7.1 it states "The external clock can vary between 24 kHz (1-kHz throughput) and 2.4 MHz (100-kHz throughput).". Do you know what you're using? If it's at 1 kHz throughput because it's lacking a fast enough external clock, that might explain it – Avantol13 Nov 03 '17 at 19:11
  • Hi Avantol, I can post a picture of my setup if that would help. I think that I am using the Raspberry Pi as an external clock. I used the schematic shown on page 11 of the data sheet with the Pi as my micro controller. If it isn't the raspberry Pi, let me know and I will try and find the external clock. Thanks a million for the help!! – Samsanit Nov 03 '17 at 19:19

1 Answers1

1

For the most part, looks like you had the right idea. I changed your getADC function based on my understanding of the spec, I wasn't sure what you were doing with the "start of a new bit assignment" section.

I don't have anything to test with, so I'm not sure that this works but it saves a few clock cycles removing that and cleaning up some more of the function to read the data.

Another thing you can do, shown below, is wait to convert the raw ADC reading to float (float math typically takes a lot of time/processing power). So just read for some amount of time, store the data off, then format and output it later. I'm not sure if that will work for your application, but it's an idea.

Hopefully this helps a little, at a minimum you should try waiting to convert to float and output.

import time
import os
import RPi.GPIO as GPIO

PIN_CLK = 11
PIN_DO = 9
PIN_DI = 10
PIN_CS = 8


def init_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    GPIO.setup(PIN_DI, GPIO.OUT)
    GPIO.setup(PIN_DO, GPIO.IN)
    GPIO.setup(PIN_CLK, GPIO.OUT)
    GPIO.setup(PIN_CS, GPIO.OUT)


def getADC(channel):
    # A falling CS signal initiates the conversion and data transfer
    GPIO.output(PIN_CS, False)

    # After the fifth falling DCLOCK edge
    # DOUT is enabled and outputs a LOW value for one clock period
    # So after 6 clock periods, we have data
    for i in range(0, 6):
        GPIO.output(PIN_CLK, True)
        GPIO.output(PIN_CLK, False)

    # For the next 16 DCLOCK periods,
    # DOUT outputs the conversion result, most significant bit first
    ad = 0
    for i in range(0, 16):
        # Get next data bit
        ad <<= 1

        # Get to next bit by advancing clock
        GPIO.output(PIN_CLK, True)
        GPIO.output(PIN_CLK, False)

    GPIO.output(PIN_CS, True)  # reset

    return ad

if __name__ == "__main__":
    init_gpio()
    start = time.time()

    results = []
    # Run for 60 seconds
    while ((time.time() - start) < 60):
        results.append(getADC(0))

    for result in results:
        # This was slowing you down
        # You could capture data and then output it like this
        Data = float(result / 65535.0 * 3.3)
        getTime = float(time.time() - start)
        print("%.5f" % getTime + "," + "%.5f" % Data)
Avantol13
  • 1,009
  • 11
  • 21
  • Thank you so much!! I just left my lab for today, but I will go in first thing tomorrow and tell you how this works! I can see how the float conversions would slow it down so I will definitely remove those. For the start of the new bit section I was very confused on that too, but I saw the code from somewhere else so I went with it lol – Samsanit Nov 03 '17 at 21:08
  • This is much faster thank you! I am getting only 0.0 for my results so I need to figure it out, most likely some faulty wiring but the idea itself has sped things up a great deal. Thank you very much!! – Samsanit Nov 06 '17 at 18:06
  • as an update when running it, we were about to get 10049 readings in 1 second. so this is much much faster than a point every millisecond like before. Thanks again! – Samsanit Nov 06 '17 at 18:43
  • No problem! Glad I could help! – Avantol13 Nov 07 '17 at 18:58