I made a simple 4 bit flash ADC on a breadboard, and I want to run an fft on the output. Is it possible to do an FFT on data that is only 4 bits in resolution.
Yes, it is possible to perform FFT (or even the Discrete Fourier Transform) on data that has 4-bit resolution, but there are some important considerations:
FFT can be performed in real time if the system has enough signal processing throughput, or FFT can be performed offline in batches (like in matlab or Excel). If you want real-time display, you can grab a batch of sample data, run the FFT, and then update the graph. If you want to keep it simple just for evaluation, all you really need is something that captures a batch of samples at a steady rate. There will be a trade-off between update rate and amount of visible detail.
There are some data acquisition factors that limit how much you can "see" with the FFT.
Quantization noise limits the best possible signal-to-noise ratio to just 25.84dB (1.76dB + 4 x 6.02dB/bit). There's no way to push the noise floor down further without adding more resolution. Yes, you could average together every 2 samples or every 4 samples or every 8 samples, that would improve the resolution at the cost of slower effective sample rate. There will also be other analog parts of the system that also affect the noise floor, but at this low resolution, they're not so important.
Usually when we do an FFT test of an ADC's performance, we apply a test tone at nearly full-scale and try to capture a few cycles of the test tone. For example if the ADC sample rate was 1000kHz (so Nyquist limit of 500kHz) then a test tone of 10kHz would get 100 sample points per cycle of the test tone. Since each cycle is 360 degrees, then the test tone would be advancing by 3.6 degrees with each sample. We want a lot of points on that test tone (i.e. high ratio of sample rate to test tone) otherwise there will be significant distortion: if the test tone was 250kHz then there would be only 4 points per test tone cycle, and each sample would advance the test tone by 90 degrees, so amplitude error would be significant. And at Nyquist limit, the amplitude error reaches 100%. So we try to keep the test tone relatively low frequency, using a low-distortion sinewave generator.
When we do the nice FFT graphs for datasheets (the graphs that look like a nice tall tree for the fundamental, shorter trees for the harmonics, and then very low grass for the noise floor) -- there's some special tricks that we applications engineers use to get those graphs looking nice: the test tone has a special relationship to the sampling frequency. The FFT algorithm assumes that the data is repeating forever, so if the first data point was at 0 degrees and the last data point was at 270 degrees, the FFT will see that sharp discontinuity as if it was another tone. This causes the frequency bins to "smear". What we want is for the test tone to have an integer number of complete cycles, like say 7 cycles, that way the FFT bins are clean.
If the test tone is not an exact multiple of the sampling frequency, the FFT frequency bins will smear quite a lot. Using a windowing function helps (by gradually reducing the amplitude of the samples at the start and end of the data record), but doesn't completely cure this smearing. So if the test tone is not accurately synchronized with the sampling rate clock, or if there is sample aperture jitter, that will limit how much meaningful information can be seen in that FFT. The frequency spectrum will look less like neat "tall trees" but more like "tents".