Almost all small robots have a couple of DC motors to drive the wheels. This tutorial explains how to use those motors as speakers.
Basically a speaker consist of a permanent magnet mounted on the frame and an electromagnet mounted on the diaphram. When an audio signal (suitably amplified) is fed into the electromagnet it causes the electromagnet (and thus the diaphram) to be atracted to, or repelled by the permanent magnet.
A typical brushed DC motor as used in most small robots also has a permanent magnet and an electromagnet. The permanent magnet is in the body and the electromagnet is on the rotor. Our motor driver ("H" bridge) is our amplifier.
Normally an audio signal varies in both frequency and amplitude. Due to limitations of the "H" bridge we are simply going to vary the frequency. As the motor is not a very efficient speaker it is not very loud so an amplitude of 100% is usually fine.
Although the motor and "H" bridge will not produce great sound quality you can play simple melodies or just confirmation sounds when the robot receives a new command. This can be useful as a debugging tool.
The rotor of a small DC motor is not designed to vibrate at high frequencies but will generally produce good sound from about 1KHz to 4KHz. This will vary greatly depending on your motor. Smaller motors have lighter rotors so are more likely to produce higher notes.
I have adapted some sample code, originally written by Brett Hagman for the tone library. I did not use the tone library because it uses a fair bit of memory and an interrupt on Timer 2. My sample code uses less memory and leaves Timer 2 free for other functions such as IR receiver libraries.
The sample code calculates the time in microseconds that the speaker diaphram would normally be in or out based on the frequency. It then drives the motors forward or backward for that very short period of time. The time periods are too short for the motor to actually turn but enough for the rotor to vibrate.
The attached sample code will play "Row, row, row your boat" when you first turn the power on. It has been tested on Arduino 0022, 1.01, 1.04 and 1.05r2.
I have attached two versions of the sample code. For motor drivers that use 1 pin to control direction and 1 pin for PWM, use the Doodle Bot example. For motor drivers where there is 1 pin for each half of the "H" bridge such as an L293D use the Micro Magician example. In either case, you only need to change the I/O pins to suit your robot.
You will see in the code that I shaved a few microseconds off of each halve of the waveform to allow for the time it takes for the Arduino to process the motor control code. This improved the pitch of the notes and made them sound a little brighter.