This project makes a PIC microcontroller play audio PCM sounds using PWM modulation! It is designed to be a research project.
Pulse-code modulation (PCM) is a digital representation of an analog signal where the magnitude of the signal is sampled regularly at uniform intervals, then quantized to a series of symbols in a digital (usually binary) code [1]. Pulse-width modulation (PWM) of a signal or power source involves the modulation of its duty cycle, to either convey information over a communications channel or control the amount of power sent to a load [2].
On this project, the load is the speaker and it will create the analog representation of the digital PCM recording.
The microcontroller selected to this project is a PIC 18F1320 [3] with 8KBytes of flash memory and an ECCP unit. A smaller flash unit also exists (18F1220) but remember that those 8 KBytes of flash allow almost a second of PCM audio sampled at 8000Hz to be loaded into the PIC. Less memory equals less recording time.
One second of audio is nothing compared with modern digital audio recorders but is enough to prove that the concept works.
Audio samples can be found free of charge on the internet. They can be used with this project as long as they can be converted to WAV format at 8 bits per sample, with a sampling frequency of 8000Hz, with just 1 channel (mono) and have less than one second of audio, .
The circuit is composed of a power supply, the microcontroller and the speaker. The power supply consists of a 78L05 voltage regulator and a 100nF decoupling capacitor. The PIC connects to the speaker through a first order low-pass filter. The low-pass filter has its cutoff frequency at 3.3KHz.
The PIC microcontroller is programed to use the internal oscilator running at 8 MHz. That way we save a crystal and two capacitors.
The 78L05 is capable of supply 100mA of current which is enough to power the PIC and the speaker. It's even possible to connect a small amplifier (opamp) to provide more sound.
No PCB was made because this project was created to test an idea I had in my mind for a while and serves only as a base for anyone wishing to use it on any other project of their own.
The software for the PIC was developed in C (HI-TECH) and is available for download below. It uses the ECCP unit in PWM mode to generate the PWM waveform in hardware. Timer 2 is used to mark the PWM period without using interrupts. However, to create pauses between consecutive audio samples, the interrupt of timer 2 is configured to decrements a counter variable and serves no other purpose. This counter indicates the number of PWM periods to pause.
The sound waveform is stored in a H (header) file and is compiled together with the player code. An utility, called pcm2h, was created to read a PCM file and create the H file. Here's how it will look:
#ifndef DIESEL_H
#define DIESEL_H
const char diesel[7563]={0x7E, 0x7E, 0x81, 0x80, 0x80, 0x85, 0x83, 0x7F, 0x82, 0x80, 0x81, 0x7F,
0x79, 0x75, 0x79, 0x81, 0x84, 0x85, 0x84, 0x85, 0x85, 0x87, 0x93, 0x97, 0x96, 0x92, 0x8D, 0x91,
0x97, 0x9A, 0x9B, 0x9A, 0x97, 0x9B, 0xA0, 0x9A, 0x9A, 0xA0, 0x9D, 0x9D, 0x9E, 0xA2, 0xA8, 0xAC,
0xAF, 0xAD, 0xA8, 0xA3, 0xA5, 0xA6, 0xA6, 0xA8, 0xA6, 0x9D, 0x99, 0x9D, 0x9F, 0xA3, 0xA2, 0x9E,
0x9A, 0x97, 0x97, 0x91, 0x87, 0x86, 0x89, 0x86, 0x88, 0x8E, 0x94, 0x95, 0x95, 0x92, 0x90, 0x96,
0x9B, 0x9C, 0x9D, 0x9A, 0x9B, 0x9D, 0x97, 0x99, 0x9B, 0x98, 0x98, 0x96, 0x92, 0x89, 0x87, 0x84,
0x80, 0x78, ...
To convert a WAV file to a PCM file we can use the Linux Mplayer or Audacity.
If you decide to use Mplayer, these are the arguments I use: mplayer myfile.wav -ao pcm:nowaveheader:file=myfile.pcm
To convert directly in Audacity, check the video on this page.
After compiling the player code with the header file and loading it into the PIC, it plays the sound over and over as it's supposed.
Testing as shown that the first-order lowpass filter is not enough to attenuate the sampling frequency noise. This means that along with the sound comes the 8KHz sampling frequency noise tha is annoying. A second-order filter will remove it completely.
First order low-pass filter (fc=3.4KHz)
While the sound is perceptible simply by connecting the speaker and filter to the PIC, a small amplifer like LM386 or uA741 is definitely required if you want others to hear the sound.
Below are the source and binary files for this project.
Microcontroller firmware
PC Software
compile this with something like: gcc -W -Wall -o pcm2h pcm2h.c either in windows or linux
Other audio samples you may use
Microchip MPLAB projects with this project's code
[1] Pulse-code modulation from Wikipedia
[2] Pulse-width modulation from Wikipedia
[3] PIC18F1320 Datasheet from Microchip
[4] The Free Sound Project - Diesel train recording by amabok
Published on Friday 2007/08/17, last modified on Thursday 2015/06/04