How can I plot a spectrogram in real time by reading data from an ADC such as the "MCP3008" connected to the Raspberry GPIO?

Asked

Viewed 734 times

0

My idea will be to read data from an ADC such as the MCP3008 connected to Rasperry’s GPIO, from the readings plot a real-time graphics of the signal processed by a FFT(fast Fourrier transform) or STFT (short Fourrier transformation)

Example STFT

Thank you

Used Codes: Real-Time Graph Generation

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

dt = 0.01
Fs = 44000.0              # sample rate
timestep = 1.0/Fs         # sample spacing (1/sample rate)
t = np.arange(0, 10, dt)  # t range
n = 256                   # size of the array data
w = 10000                 # frequency of the input

data = np.sin(2*np.pi*w*t)



def update(data):
    # update the curves with the incoming data
    line.set_ydata(data)
    #line2.set_ydata(magnitude)

    return line,

def generateData():
    # simulate new data coming in
    while True:
        nse = np.random.randn(len(t))
        r = np.exp(-t/0.05)
        cnse = np.convolve(nse, r)*dt
        cnse = cnse[:len(t)]
        data =  np.sin(2*np.pi*w*(t)) + cnse
        magnitude = np.fft.fft(data)/n
        magnitude = np.abs(magnitude[range(n//2)])
        yield data

fig = plt.figure()

# plot time graph axis
timeGraph = plt.subplot(2, 1, 1)
timeGraph.set_ylim(-0.2, 0.2)
timeGraph.set_xlabel('Time')
timeGraph.set_ylabel('Amplitude')

# plot frequency graph axis
freqGraph = plt.subplot(2, 1, 2)
freqGraph.set_xlabel('Freq (Hz)')
freqGraph.set_ylabel('|Y(freq)|')

# get frequency range
n = len(data) # length of the signal
print(len(data))
k = np.arange(n)
T = n/Fs
freq = k/T # two sides frequency range
freq = freq[range(n//2)] # one side frequency range

# fft computing and normalization
magnitude = np.fft.fft(data)/n
magnitude = np.abs(magnitude[range(n//2)])


line, = timeGraph.plot(np.linspace(0, 1, len(t)), 'b')
line2, = freqGraph.plot(freq, magnitude, 'g')


# animate the curves
ani = animation.FuncAnimation(fig, update, generateData,
                              interval=10, blit=True)

plt.show() # open window

leitura do ADC:

        while True:
    # Read all the ADC channel values in a list.
    values = [0]*8
    for i in range(8):
        # The read_adc function will get the value of the specified channel (0-7).
        values[i] = mcp.read_adc(i)
    # Print the ADC values.
    print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values))
    # Pause for half a second.
time.sleep(0.5)
  • 1

    Now that you have translated, what is the problem in question? You just described what you intend to do but didn’t say what you have done so far and what the problem was found.

  • Hi Anderson I used to study and as an example the code below: https://stackoverflow.com/questions/41009258/how-to-plot-2-animated-graphics-with-x-axis-fixed-in-matplotlib-with-subplots I can read the sensors connected to MCP3008 # SPI hardware Configuration: SPI_PORT = 0 SPI_DEVICE = 0 Mcp = Adafruit_mcp3008.MCP3008(spi=SPI.Spidev(SPI_PORT, SPI_DEVICE)) to insert sensor reading in graph and FFT calculation.

  • Edit the question and add any code you’re using directly to it.

  • easier to ask a simplified question as I am using MCP3008 so and this error.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.