# Confusion with ADC resolution FFT and programming tools

I have a signed 16 bit ADC which means it maps -10V to +10V range to 16 bit. So the max voltage +10V is 2^15-1 = 32767; zero is 0; and -10V is -2^15 = -32768.

My confusion is that when I perform data-acquisition with such 16 bit hardware and do the FFT with MATLAB or Python tool I dont know how the program know the resolution of the data(like 16-bit). And if I create my own array in MATLAB by coding what would be the bit resolution when it does the FFT.

I don't know if I could articulate where I am stuck at. Basically as I have written before imagine you have a have a signed 16 bit ADC which means it maps -10V to +10V range to 16 bit. So the max voltage +10V is 2^15-1 = 32767; zero is 0; and -10V is -2^15 = -32768. And imagine you have a binary file file full of 16-bit samples recorded by this ADC hardware. Now if you perform FFT in MATLAB or Python these tools will read 16 bit file and convert these unsigned bits to voltage and perform FFT.

But imagine you want to do/mimic the same thing with coding not by using FFT. How would you make such array in MATLAB or Python?

Here is an example: Let's say I want to create/plot a sinusoid in MATLAB or Python where I can mimic exactly that 16 bit ADC which samples a 1V 100Hz sinusoid input for 1 seconds which is sampled with 512Hz sampling rate. At the end I want to obtain the same FFT plot where I would obtain after a real ADC sampling. How can that sort of array be obtained? How does the FFT function know the resolution of the ADC when it calculates the FFT?

• Good FFT results require 10 log (samples per wavelength) and high SNR [dB] from resolution . You only have 10log(512/100) and 10 log (1V/10V *32767) so your FFT result will have noise and low Q frequency response (<10) but the peaks can give some indication but >-70dB of of noise below peaks. Jul 23, 2018 at 19:37
• Related question Jul 24, 2018 at 10:01
• It looks like your question is about how Mathlab/Phyton converts signed 16-bit integer array into floating point array. What is the issue here? Or is it about how to generate a 16-bit signed data out of a floating-point SIN(t) subroutine? It is very unclear what are you asking about. Jul 31, 2018 at 19:59

Here is an example: Let's say I want to create/plot a sinusoid in MATLAB or Python where I can mimic exactly that 16 bit ADC which samples a 1V 100Hz sinusoid input for 1 seconds which is sampled with 512Hz sampling rate. At the end I want to obtain the same FFT plot where I would obtain after a real ADC sampling. How can that sort of array be obtained?

It seems like your overall goal is to look at the effect of quantizing your signal in the frequency domain. Here's some example code for Python which could easily be ported to MATLAB

for n in range(num_samples):
# Input signal (1/10th of FSR)
Input_Signal[n] = 0.1*math.sin(2*math.pi*100*n/num_samples)

# ADC Output scaled to represent voltage

# FFT of input and output signals
Input_Signal_FFT = np.fft.fft(Input_Signal,axis=0)
Scaled_Output_FFT = np.fft.fft(Scaled_Output,axis=0)
Input_Mag = abs(Input_Signal_FFT[:,0])
Quantized_Mag = abs(Scaled_Output_FFT[:,0])


Here's the FFT of the input signal

Here's the FFT of the quantized signal

There is no noticeable difference between the two. This is a useful exercise in learning the noise considerations of an ADC system design. The noise in a 16-bit ADC might very well be dominated by factors other than quantization noise. This would not be true for a 4-bit ADC (FFT shown below)

Let's say I want to create/plot a sinusoid in MATLAB or Python where I can mimic exactly that 16 bit ADC which samples a 1V 100Hz sinusoid input for 1 seconds which is sampled with 512Hz sampling rate.

First, you need to write some code to increment the phase of an angle. You want to create 512 points. If the frequency were 1 Hz, you'd sweep through 2pi radians over the course of 512 samples, but your frequency is 100 Hz so you should increment 100 times as fast.

Then you need the right amplitude. You say 1v (let's assume you mean peak, if not correct accordingly). Full scale on your ADC is 10v, so you want a tenth of that. Full scale output of your ADC is 32767, so you want a tenth of that. The maximum value of the sine function is one. So basically multiply the output of your sine function (evaluated at the angles calculated above) by 32767/10 and then round.

Of course this fake signal will be unrealistically clean - for a more realistic model you could add some noise, etc.