Arduino Serial PCM Recorder

by HelpfullDoggo in Circuits > Arduino

508 Views, 1 Favorites, 0 Comments

Arduino Serial PCM Recorder

mic_thumb.png

Have you ever wanted to record audio from a Arduino, but without a SD card?

Then this is it. This can record approximately 8 bit audio at around 6.5Khz or 6500 Hz sampling rate depending on baud rate maybe other tests I've done I have not managed to get anything higher, even with maximum baud rates, might depend on the specific Arduino you may have.

Supplies

You will need:

  • Arduino, any kind should work (UNO,Nano,etc)
  • Mic module

My module is powered by 3.3V (Don't know if 5V is fine, stay at 3.3v to be on the safe side) and it has a pre-amplifier, a regular mic might work but voltage output could be very low and the Arduino already introduces a lot of noise into the signal.

Hookup

arduino_recorder.png

I'm using this powered mic module and connected as follows:

Connect the A0 Pin of the mic module to any of the available analog pins on your Arduino, In the code the mic pin is set to A5. and simply connect VCC (3.3V) and GND (it's connected wrong in the picture).

The Code (Plus a Little Explanation of It)

code_for_rec.png

The code is very simple. It reads a analog voltage and writes it to the serial port, however by default the Arduino will only produce values from 0 to 1023. in order to decode sound we will use 8 bit PCM (Pulse Code Modulation)

a 8 bit value ranges from 0 to 255. Now to turn it into our desired range we will use the map() function, it simply takes a variable, enter it's range and your desired range in our case:


Now how do we actually reproduce the sound?, Unfortunately the Arduino has only 2KB of SRAM Which is far from enough to store audio, which in size it could range around ~100 KB. If you do want to play it back directly on the Arduino you could connect a SD card module.

In my case we want to record without a SD card module. So instead We simply send the data over serial and play it back in audacity.

In order to correctly send the data over serial using Serial.print() will not work as it prints the ASCII values so that will only print us numbers from 0 to 225. instead we'll use Serial.write(), which will print us the raw data in bytes. Which when converted back to ascii will simply be random ASCII values.

Downloads

Open the Serial Port With PuTTY

putty.png

In order to play back the audio I'll be using audacity and PuTTY and HxD.

Links:

Audacity ® | Free, open source, cross-platform audio software for multi-track recording and editing. (audacityteam.org)

Download PuTTY - a free SSH and telnet client for Windows

HxD - Freeware Hex Editor and Disk Editor | mh-nexus


Open PuTTY, choose the COM port for your Arduino, in my case COM10 and make sure to match the baud rate set in the code (115200) changing the baud rate both in the code and in PuTTY could significantly improve sample rate, but setting very high values could make your computer lag.

Now press Open and a window should appear with a bunch of random text. Now you're ready to record. Once you have recorded your sound just unplug the Arduino as I don't have a another way to stop the recording currently, I could implement a push buttons in the future...


Saving

HxD.png

Now simply select everything by either dragging down from the top or from the bottom. Make sure keep that text safe either in notepad or whatever. Now open up HxD and make a new file (Ctrl-N) and paste the data, make sure to paste it in the Decoded text area or else it will give you an error. Now save the file, (you don't need an file extension for it.)

Import to Audacity

Audacity.png
encoding.png
normalize.png

We can't simply play back the audio in any audio player. Every file format including audio has some sort of header that tells the program what kind of file it is independently on the file extension it has. No matter what file extension you change it to it will still have same header.

Now to import it to audacity go to File > Import > Raw Data.

Select your file you saved with HxD. Once opened you will be prompted with a dialog to select the audio configuration. Choose Unsigned 8-bit for your encoding and a sample rate of 6000 Hz you will need to type it manually as it's no available in the drop down menu leave everything else how it is. ; The higher you set your baud rate before the higher the sample rate of the audio. Now press import. You then have now successfully imported the audio.

There is one last step you need to do to the audio. For some reason the audio ends up having it's phase offset, You can technically play it back but I don't recommended as it could damage your speakers. By default when there is no audio going trough the speakers, the speakers are in the rest position staying in the center. But when the phase is offset the speakers will constantly be higher than the rest position even though when is silence in the audio, making speaker vibrate in the offset state which will make it sound quieter. To correct it Simply double click your audio to select it all go to Effect > Volume and Compression > Normalize and make sure to set the peak amplitude to -0.0 dB press OK, now the phase is centered. You can play back your audio now.

Mic Calibration (Optional)

In my mic module it has a gain control, and I left uncommented part at the end, it will help you calibrate the sensitivity by showing dBm values. Simply comment out the rest of the code and enable the calibration code. Open your serial monitor and watch the values, adjust the potentiometer on the mic module while making some sort of noise until it's reactive enough.

Make some test recordings and if there is too much noise keep reducing the dBm Values until there is a good enough volume and not a lot of noise.

Once done simply revert your changes and enable the main code.

Conclusion and Results...

For some reason audacity seems to not import the entire audio a quick fix I devised was to

add a delayMicroseconds(100); right after the Serial.write().

Because we are using a very high baud rate sometimes things can get messy and data can get lost, adding that delay makes sure that all data is sent correctly allowing the buffer to have enough time to send all data via serial , however the drawback is that it lowers the sample rate down to 4000 Hz, it is still not too bad....


Hope you enjoyed this tutorial! Feel free to share or edit my code... I won't judge :)

You can take a listen of some audio recordings I did: