# Tiva C launchpad FFT with real time plotting using pyQtGraph

### Circuit Diagram:

The biased signal generator signal is connected to AnalogIn 1 on the Tiva C which is pin PE_2. Signal Gen and Tiva C ground is common. The two 10k resistors from a voltage divider which will halve the 3v input to give a 1.5 v bias. The signal from the signal generator will be 3V peak to peak meaning that now the signal will vary from 0v to 3v using all of the ADCs available range. It’s probably a good idea to add a small capacitor in between the signal generator and the voltage divider to prevent the DC flowing through the signal gen. A 1Khz sample rate means that the highest frequency that we can reliably analyse is 500Hz. This comes from the the nyquist sampling theorem.

### Code:

The Energia IDE was used to write and compile the code which runs on the Tiva C. See below for the code:

```#include "fix_fft.h"

#define log2N     7
#define N         128     //number of sample points

void setup()
{
Serial.begin(115200);
delay(1000);             //give time for serial monitor to start up in Energia

}

int real[N];
int imag[N];
short i;

void loop()
{

for (i=0; i<N; i++) {            // read ADC pin 128 times at roughly 1KHz
delay(1);
}

for( i=0; i<N; i++) imag[i] = 0;   // clear imag array

fix_fft(real, imag, log2N, 0);   // perform fft on sampled points in real[i]

for ( i = 0; i < N/2; i++)         //get the power magnitude in each bin
{
real[i] =sqrt((long)real[i] * (long)real[i] + (long)imag[i] * (long)imag[i]);
}

Serial.print("*\n");      //send fft results over serial to PC
for (i=0; i<N/2; i++) {
Serial.print(real[i]);
Serial.print("\n");
}

}```

The reason the code is so short is because all of the fft code is contained in fix_fft.h which is a c implementation on the fft which has been around for over two decades. It was first written by a person called Tom Roberts in 1989 and a google search of “fix_fft.c” will return many mirrors of this code available for download. the fix in “fix_fft.c” refers to the fact that it uses fixed point short integers as opposed to floating point numbers which will result in a loss of accuracy in the fft but a faster execution time.

Here is the python script used to plot the fft data:

```#python script to read 64 bytes of data from tiva C and plot them
#using pyQtGraph on a loop. As soon as 64 bytes arrive plot is updated

from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import pyqtgraph.exporters
import numpy as np

import serial

ser = serial.Serial(
port='COM4',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)

ser.close()
ser.open()
print (ser.isOpen())

data = np.zeros(64)

app = QtGui.QApplication([])

p = pg.plot()
p.setWindowTitle('FFT')
p.setLabel('bottom', 'Index', units='B')
curve = p.plot()

def update():
global curve, data,
if(ser.readline() == b'*\n'):   # "*" indicates start of transmission from tiva c
for h in range(63):
try:
data[h] = int(ser.readline())  #get 64 bytes from tiva c and plot them
except:
pass
curve.setData(data)
app.processEvents()  ## force complete redraw for every plot

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)

## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
```

## 20 thoughts on “Tiva C launchpad FFT with real time plotting using pyQtGraph”

1. Wow, I love how simple the code is for this. I’ll definitely be trying out that pyqtgraph.

Perhaps you would consider adding a DC-blocking capacitor in between the signal source and the bias network with the two 10k resistors? It would mean you don’t need to worry about the DC offset for the input signal – you’d only need to keep the peak-to-peak amplitude of the input below 3V, because the DC level of the input wouldn’t matter any more.

This is such a useful little recipe!

Ted

1. wattnotions says:

Hey Ted, good idea with the capacitor, I added it to the diagram ๐
pyqtgraph is a really handy library for fast updating plots. It comes with loads of cool examples that can be easily modified which is always a good thing!

Shane

2. Nice work Shane. Did you measure the actual sample rate? Maybe consider using timer interrupts?

1. wattnotions says:

Hey Frank, just measured it there using an oscilloscope. It takes 129 – 129.5ms (the measurement flickers between the two values on the scope) to take 128 samples. This would give 1.0117ms between samples which means a sample rate of 988Hz. Timer interrupts would make this more accurate I’d say. I’ll be stealing your energia timer interrupt code from here in the near future ๐

3. Great work Shane. 2 comments: 1.Log mag would produce nice plot. 2.notice the aliasing of the fundamental and the harmonics as you increase the frequency.

1. wattnotions says:

Thanks for the log mag idea I’ll definitely try that out ๐

4. TFFT says:

Very interesting and useful!!
Thanks!

5. James H. says:

Great fft adc project! What sample rate and timing variance can you get by reducing or removing the delay? This could have some really cool applications where precice timing is not critical. Can you get to 100 ksps or more?

1. Hi james, apologies for the delay in getting back to you – I’ll be using this fft setup for another project pretty soon and when I have it all set up again I’ll see how fast it can go. If it helps I do know that the AnalogRead() function takes approximately 1us to run on the TivaC – so it should be able to do 100ksps without to much hassle ๐

6. sae june park says:

Thanks for this project. This is very helpful.
I have a question, in the code

global curve, data,

next to data,is there any words or blank?

1. wattnotions says:

Hi Sae June, Glad you found it useful. It should be global curve, data .That extra comma shouldn’t be there.

Shane

7. Rando says:

Sweet project, thanks so much for posting!

8. Rando says:

I’m just now seeing this error …

fft_tiva_c.cpp: In function ‘void loop()’:
fft_tiva_c.cpp:28:31: error: cannot convert ‘int*’ to ‘short int*’ for argument ‘1’ to ‘int fix_fft(short int*, short int*, short int, short int)’
delay(1);

So I did this change… all to short

short real[N];
short imag[N];
short i;

Compiled OK, but have not tested yet….

Binary sketch size: 13,700 bytes (of a 262,144 byte maximum)

9. I can’t open the graphic screen window

10. the error message appear:
“SyntaxError: multiple statements found while compiling a single statement”
in the pyqtgraph.

1. wattnotions says:

Cool! Thanks for letting me know ๐