Speaker

Status
Not open for further replies.
A speaker is quite happy being driven from DC squarewave so you don't need a cap, you just need a series resistor to reduce current from the PIC pin and reduce the volume.

A 220 ohm resistor and a 500ohm trimpot are ideal (trimpot gives you a volume adjustment which you will appreciate).
 
This is what a microchip data sheet said
SOUND outputs TTL-level square waves. Thanks to the excellent I/O characteristics of the PICmicro MCU, a speaker can be driven through a capacitor. Piezo speakers can be driven directly.
 
It works as in the schematic. Wow i made a nice simple test app to play different tones based on buttons for up and down. Wow amazing how simple it was...

Code:
/* *****************************************************************************
;                                                                             *
;    Filename:                     				                              *
;    Date:                                         	                          *
;    File Version: 001                                                        *
;                                                                             *
;    Author:   Jason Lopez                                                    *
;    Company:  AtomSoft                                                       *
;                                                                             *
;***************************************************************************** */

#include <p18f248.h>
#include <delays.h>

#define SPK LATB
#define DWN PORTCbits.RC3
#define UP PORTCbits.RC2
#pragma config WDT = OFF, LVP = OFF, OSC = HS,OSCS = OFF


/************************************
Prototypes
*************************************/
void main(void);
void CheckBtn(void);

unsigned char Speed = 2;
/************************************
Main - 20MHZ OSC
*************************************/
void main(void){
    
	ADCON1 = 0x0F;			//Digital Pins (we dont need ADC)

	TRISB = 0x00;	//All Outputs
	LATB = 0x00;		//All Low

    TRISC = 0b00001100;
    
	while(1){
        SPK = 0xff;
        Delay100TCYx(Speed);
        CheckBtn();

        SPK = 0;
        Delay100TCYx(Speed);
        CheckBtn();
	}
}
void CheckBtn(void)
{
    if(UP)
    {
        Delay10KTCYx(50);//100ms
        if(Speed < 255)
        {
            Speed++;
        }
    }
    if(DWN)
    {
        Delay10KTCYx(50);//100ms
        if(Speed > 0)
        {
            Speed--;
        }
    }


}

EDIT: I have a speaker and a headphone on portB so to simplify it all i toggle entire port heh
 
Last edited:
Sound is easy to do with a pic i made a real nice piano with a 16 key keypad the tones played almost like the real thing.

I used a lookup table. The speaker is a little harder to find that gives good output at milliwatts for direct drive. But it also easy to find a good amp. Like the TDA2009A I used
Figure 15 : High Quality 20 +20W Two Way Amplifier for Stereo Music Center (one channel only)
 

Attachments

  • TDA2009.pdf
    193.4 KB · Views: 178
Works nice!!
as a test i made this for my son:
 

Attachments

  • tone.png
    15.7 KB · Views: 130
  • tone2.png
    7 KB · Views: 117
Last edited:
If you're so inclined, here's a fun thing to try - an NCO (Numerically Controlled Oscillator).

The code template needs (1) config statements, (2) code to turn off ADC and comparators, and (3) code to setup Timer 2 for 200 cycle interrupts.

While the code uses an 8388608-Hz crystal and 4xPLL for very precise frequency control, your 20-MHz crystal should be fine. You won't get precise frequency control but it'll be good enough to test and play with.

Pretty simple code, hiding a whole bunch of very cool theory (lol).

Cheerful regards, Mike

Code:
/********************************************************************
 *  NCO (numerically controlled oscillator) ouput range 1..5000 Hz  *
 *  use 8388608-Hz crystal and 4xPLL with speaker connected to RB2  *
 ********************************************************************/
#include <system.h>

unsigned long accum;            // 24-bit phase accumulator
unsigned long phase;            // 24-bit phase offset (tuning word)

//--< isr >----------------------------------------------------------

void interrupt()                // 200-cycles (41943.04-Hz)
{ pir1.TMR2IF = 0;              // clear TMR2 interrupt flag
  accum += phase;               // add phase offset to accum
  latb.2 = accum.23;            // square wave output
}

//--< main >---------------------------------------------------------

void main()
{
  trisb = 0;                    //
  latb = 0;                     //
//
// this is how you set tone output frequency
//
  phase = 25410<<2;             // phase offset for 254.10-Hz tone

  while(1)                      // loop forever
  {                             //
  }                             //
}
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…