0
\$\begingroup\$

Is there any way to use a PICAXE (08M2, to be precise) to play a small sound file (Not beeps and buzzes, but actual sound), perhaps loaded from an i2c EEPROM chip? I'm thinking something similar to the ThinkGeek EvilTron: two or three seconds of decent quality, mono-speaker sound. If not, is there a small/inexpensive slave chip that can accomplish this? I'm not looking for something fancy or complex, just enough to amount to a homemade EvilTron. Thanks for any pointers.

Here's a link to aforementioned EvilTron, just so you know: EvilTron

(also note I'm fully intending on using speakers well below the PICAXE's current limits, so no need for an amplifier circuit)

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

(1) The 'easy' way

Add this RAMTRON FM25V02 32k x 8 IIC non volatile memory


You could use Roman Black's BTC encoder to convert WAV files to 1 bit serial files that the processor can output.

User discussion

Typical background paper to PCM & friends - 1974 - old enough that what was leading edge hardware iis now almost trivial.

Roman Black inspired Circuit Cellar article for speech coding on an 89C4051

Relevantish

________________________________________________

(2) It's doable with on chip resources, with effort.

The PICAXE 08M2 has very limited memory capacity compared to what is needed for storing raw sounds files. PICAXE manual here in stock at Digikey $5.8=77/1

This will allow storage of 4 seconds of speech or similar quality sound at 8k samples x 8 bits per second - or a lot longer at lesser rates.


Recording speech and playing it back as bytes to an ADC is usually down at 8 kB/s x 8 bits/Byte = 64 kbps. You can get reasonable quality down to about 16 kbps with ADPCM and lower again with care. If you used say 1kB of the program memory for data storage that's 8 kbit so for 2 seconds = 4kbps and for 4 seconds = 2 kbps.

LPC will achieve this with ease - but a PICAxe will not like LPC decoding.

At 4 kbps you may be able to use say 2 bit ADPCM and get something approaching speech out.

Dinner time. Food for thought there. More later probably ...

Search for: Roman Black speech PIC
for about as good as you can probably do.

Failing that, an external IIC memory will allow you to do this easily.

enter image description here


(3) Complete speech recording and playback ICs are available.

"Chipcorder" / ISD / Nuvoton is one such and also here

\$\endgroup\$
1
  • \$\begingroup\$ Great thanks! Ya I'm definitly loading the sounds from external EEPROM, so this gives me a good starting point for figuring out how to encode it. \$\endgroup\$
    – Chris
    May 26, 2012 at 7:16
1
\$\begingroup\$

There might be libraries which can help you to play sounds, (basically a header file with the frequency in hertz for each note). You might want to consider doing this to save yourself the hassle of buying a new chip. [I have attached sample code albeit for the arduino below, it should be very easy to port over]

Otherwise you might want to consider investing in a SoundPAL. Though this was designed for the BASIC stamp, it is very easy to interface with and in the worst case scenario bitbanging always works :) You just have to send in the notes and it'll play it on the onboard buzzer. It also has a variety of tunes stored in the EEPROM that you can play.
SoundPAL


http://www.parallax.com/Store/Accessories/Sound/tabid/164/CategoryID/38/List/0/SortField/0/Level/a/ProductID/482/Default.aspx


// define the frequencies for each note
#define c 261
#define d 294
#define e 329
#define f 349
#define g 391
#define gS 415
#define a 440
#define aS 455
#define b 466
#define cH 523
#define cSH 554
#define dH 587
#define dSH 622
#define eH 659
#define fH 698
#define fSH 740
#define gH 784
#define gSH 830
#define aH 880
//this function will play each note, so you just call the fn beep for each note to be played
void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds)
{
   int x;    
    long delayAmount = (long)(1000000/frequencyInHertz);
    long loopTime = (long)((timeInMilliseconds*1000)/(delayAmount*2));
    for (x=0; x less than loopTime; x++){
        digitalWrite(speakerPin,HIGH);
        delayMicroseconds(delayAmount);
        digitalWrite(speakerPin,LOW);
        delayMicroseconds(delayAmount);
}
delay(20); //to separate the notes
}

PS: I wasn't able to copy the exact code here so if anyone can fix the less than to < please do so.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.