What's a fast 16-bit ADC that I can use in a project?

I'm looking for a fast 16-bit ADC module that I can use in a project. The ADSxx15 chips will not work, their sample rates are far too slow.

I made a TCP-enabled streaming FM radio server with a Mega2560 + TEA5767 + W5500. I'm sampling the line out from the TEA (with a +2.5v bias added to center the signal in the ADC's voltage range) with the Arduino's onboard ADC on a timer interrupt. I buffer and send the audio in real-time through a small HTTP server I wrote. It can be played through VLC, etc on a client computer and the tuner frequency can be adjusted through a web interface.

It works well, I can sample the audio at 22 KHz mono with more than enough CPU headroom to stream live to multiple network clients. The only problem is the low resolution of the ADC, it sounds pretty decent but 16 bit would be a nice jump in quality.

Any good IC's out there that are reasonably easy to interface with an Arduino, and can sample at 22 KHz or better in a 16-bit resolution?

I'm probably going to post this project on here with code this weekend if anybody else is interested. It honestly works a lot better than I expected with just a simple AVR.

I guess 10 bits is a little low for HiFi audio.

Other Arduino variants, such as a Due or a Teensy 3.2, have higher resolution on the analog inputs.

Since this seems to be an audio-specific project, you should look at using an audio-specific CODEC chip, instead of a general-purpose ADC. The SGTL5000 is one specific example. You can get this on a shield with headphone jacks and a few other useful connectors too. See: https://www.pjrc.com/store/teensy3_audio.html This will get you to 44kHz 16-bit stereo relatively easy.

Thanks that looks good, I didn't know PJRC sold that. Although, I think I actually don't need one after all. Really stupid mistake on my part.

It turns out the voltage output by the TEA5767 is quite low and 5v was just too high of a reference. I was only outputting the low byte so the volume was still good as an 8-bit stream.

Made a voltage divider to drop the 5V way down and used that as an AREF and half of that as the positive bias.

Now the audio peaks around 80% to 90% of the reference range, and the sound is excellent! It doesn't sound audibly worse than just listening to FM radio directly. I'm happy. The AVR's ADC is actually doing a really good job. 10 bits is plenty, left shifted by 6 and output as a 16-bit PCM stream.

Great feedback thanks!

Would you mind sharing your code? I am interested in how you got that amount of throughput on the lowly 16MHz Arduino.

[I skipped reading the "FM radio" part. 10 bits is probably more than you need to exceed the fidelity of broadcast FM.]

Sure thing! I'm attaching it. Also attaching an audio sample at 30 KHz saved direct to wav from the Arduino with wget. It's just a random recording of a news broadcast that happened to be on. Quality is pretty good, IMO! :slight_smile:

The program is always sampling and filling a 2 KB buffer, even when no clients are connected. When the buffer position gets to 1024, it sends the first 1 KB to a netSendAudio function. When it wraps back around to zero it sends the last 1 KB.

netSendAudio looks for any connected clients that are currently in the correct state to receive audio. If any exist, they receive that 1 KB chunk.

Since the sampling is done in an ISR, it always preempts whatever else is going on so the sample timing remains constant and the audio is stable/smooth.

Pic of the circuit on a breadboard, not much to it really: https://i.imgur.com/wkkkikz.jpg

I still have a lot more I'd like to add to the web interface, but here's what I have so far.

More notes about it:

One thing I had to do to get reasonable sample rates was change the ADC clock prescaler.

I seem to be limited to a single streaming client at 30 KHz. At 24 KHz sample rate, it can support two.

Up at 30 KHz, I believe the interrupts where it reads the ADC are just eating up too much CPU time to handle more.

At 24 KHz, it seems to be more of a bandwidth limitation of the W5500 Ethernet shield. Doesn't want to send out more than 90-100 KB/s or so. If you have a low sample rate like 8 or 11 KHz, with mono 8-bit audio, I think it could probably handle quite a few clients at once!

This isn't my cleanest code ever. I tend to get sloppy when I'm just trying to make something work and then go back later and make it look nicer when I feel like it. Also, the TEA5767 code isn't mine. I adapted it a bit from a library I found. Mainly converting it from being a C++ class and just moving the bits I needed into my project as plain old global functions and variables.

16bit4.zip (1.04 MB)

radio.zip (3.48 KB)