using microphone to control 3v DC motor speed

I am trying to do two things:

  1. get a microphone input to control the speed of a 3v dc motor.
  2. read the values coming from a microphone via an LM386 amplifier via serial communication

It is almost working, as I understand it, as the signal from the mic-amplifier set up gets louder the motor should slow down (as the delay value gets larger). I have had this working with a 10k pot but results were too erratic so I inserted a 1k resistor in it place (explained below).
I am after any ideas people have on how to make this work better, check the values coming from the amplifier, check that the mic is actually working properly!

The circuit I have built to do this is in two parts:
The first part controls the motor and is exactly the same as this: This all works fine.

The second part is an amplifier consisting of this mic insert
and the circuit to be found on p. 357 of Physical Computing. This is built around the LM386 amplifier. Where there is a 10k pot is in the circuit, I have replaced it with a 1k resistor for now as I don’t want a pot in the final gizmo. This has also helped to make the changes in motor speed less erratic but has not solved my problems.
(If anyone has the Physical Computing book to hand…) I have basically wired the output of the amplifier to Analog in 0 on my Arduino.
I am then converting the values received on Analog0 to get the amplitude of the incoming sound.

The code given in PhysComp… is this:

' read an ADC value into the variable ADCVar, then do the following:

if adcVar >= 512 then
AmplitudeVar= adcVar - 512
AmplitudeVar = 512 - adcVar

I am not sure how this actually works but I have just re-written it as :

//read delay value from analog input (microphone)
  value = analogRead(potPin);
  //work out the amplitude (phys-comp book p.358)
  if (value >= 512) {amp = value - 512; }
  else {amp = 512 - value; }

I am then using amp to set the delay of my app and control the speed of the motor

As I said, it is kind of working, but I’d like to read what the amplifier is outputting, I’ve been reading from the serial port in processing (via the helpfile) and all I am getting are a string of very similar values: 48 49 52 53 57 all around that area. This is the same if I actually unplug the microphone’s + connection from the breeadboard, which leads me to think something is not right…

any clues, anyone done this before??
If it’s helpful I could stick a photo of the circuit up, or even a schematic of what I have if necessary…

here is the full arduino code, it is a slight modification of that found on the site linked above:

// need to convert amp into appropriate range.

int switchPin = 2;    // switch input
int motor1Pin = 3;    // H-bridge leg 1 
int motor2Pin = 4;    // H-bridge leg 2 
int speedPin = 9;     // H-bridge enable pin 
int ledPin = 13;      //LED 
int value = 0;        // store pot value
int amp = 0;
int potPin = 0;       // Analog In 0

void setup() {
  // set the switch as an input:
  pinMode(switchPin, INPUT); 
  // set all the other pins you're using as outputs:
  pinMode(motor1Pin, OUTPUT); 
  pinMode(motor2Pin, OUTPUT); 
  pinMode(speedPin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  // blink the LED 3 times. This should happen only once.
  // if you see the LED blink three times, it means that the module
  // reset itself,. probably because the motor caused a brownout
  // or a short.
  blink(ledPin, 3, 100);

void loop() {
  // turn motor on:
  digitalWrite(speedPin, HIGH); 
  //read delay value from analog input (microphone)
  value = analogRead(potPin);
  //work out the amplitude (phys-comp book)
  if (value >= 512) {amp = value - 512; }
  else {amp = 512 - value; }
  // if the switch is high, motor will turn on one direction:
  if (digitalRead(switchPin) == HIGH) {
    digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
  // if the switch is low, motor will turn in the other direction:
  else {
    digitalWrite(motor1Pin, HIGH);  // set leg 1 of the H-bridge high
    digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
  //turn motor off
  digitalWrite(speedPin, LOW);

  blinks an LED
void blink(int whatPin, int howManyTimes, int milliSecs) {
  int i = 0;
  for ( i = 0; i < howManyTimes; i++) {
    digitalWrite(whatPin, HIGH);
    digitalWrite(whatPin, LOW);


this sounds good in theory, but electronic circuitry is very difficult to explain and troubleshoot without pictures… wouold you have a block diagram and a schematic diagram to show us?


ok, this is the schematic for the motor driver circuit I'm using:

The only thing that is not in my circuit is the switch. Also, I am not using 12v, as the motor is only 3v I am doing it all using 5v so the "To Motor Power Supply" goes to +5v

Here is a Schematic for the amplifier sub-circuit I am using:

The "To Arduino Analog 0" goes to Analog 0 and is used to set the delay time in the code.

Here is a photo of the circuit:

( just in case you want to see larger images: )


nice pictures

a few ideas:

  • take out the 1K resistor on the 386 input, as it is not doing much except preventing signal getting to the 386. This should help you to get better readings. If you want amplitude control of the mic input, then replace the input pot, which is the proper voltage-divider configuration. You might also want to remove the gain cap between pins 1 and 8 if the readings are too high.

  • check the conversion time for the A/d converters in the Atmega datasheet. You might not be catching things quickly enough

  • consider using some kind of resistor and capacitor 'averaging circuit' on the amplifier output, to well, get the average value of the signal!

  • the motor driver chip has a voltage drop and minimum operating voltages as well- check the datasheet. I have a feeling that 5V may be too low.

  • you need REALLY good bypassing if you use the same supply for the motor as the Arduino. Typically the Arduino 5V supply should not be used for anything but the tiniest of motors. This is because motor noise and loading can interfere with the stability of the logic supply. You will need something like a 330Uf and a .1UF capacitor minimum on the 5V supply to counter noise generated by the motor. Generally it is a bad design idea ot use the 5v logic supply for noisy things like motors and solenoids.

hope this helps


PS: the resistor you are using between pins 1 and 8 seems to be a 10,000 ohm (10K) rather than a 10 ohm.. this will kill the gain in a second.


Many thanks, this is really helpful stuff, just was I was looking for...

I'll give all that a try in the next couple of days and post nack here to let you know how it all went.

PS: the resistor you are using between pins 1 and 8 seems to be a 10,000 ohm (10K) rather than a 10 ohm.. this will kill the gain in a second.

haha, I really need to do more of this stuff, I do that almost every time I dig out the arduinos.



sorry my mistake, they do use a 10R resistor in the standard design for the LM386, but on the output of pin 5, not between 1 and 8. So your 10K resitor is OK. It would set the gain to something between 20 and 50, according to the datasheet:

"To make the LM386 a more versatile amplifier, two pins (1 and 8) are provided for gain control. With pins 1 and 8 open the 1.35 k[ch937] resistor sets the gain at 20 (26 dB). If a capacitor is put from pin 1 to 8, bypassing the 1.35 k[ch937] resistor, the gain will go up to 200 (46 dB). If a resistor is placed in series with the capacitor, the gain can be set to any value from 20 to 200. Gain control can also be done by capacitively cou- pling a resistor (or FET) from pin 1 to ground. "



Yeah I just spotted that myself, so have kept the 10k.

I checked the sheet for the L293, it needs at least 4.5v so 5v might do, but I have taken your point on bad design and checked over the stuff on the ITP site and think that the 9V might be a better option? As long as I limit the speed of the 3v motor it doesn't get to hot, is this a good idea or is just lack of knowledge/laziness that is letting me believe it might be alright to supply 9V to a chip that is driving a 3V motor?

The conversion times for the a/d converters on the Atmega are "13 - 260 [ch956]s Conversion Time". I have to admit I'm all that sure what this means and what I need to do about it...? Adjust the baud rate perhaps, its running at 9600 at the moment...?

The whole system appears to be working on and off but, and this might be a stupid question coming up, the main problem I seem to be having is that even touching/knocking the pot can cause large jumps in the motor's speed (which is why I replaced the pot with a resistor as an experiment) . I am pretty sure the pot is soldered well, I've used it for other things recently, is this just loose wiring somewhere? With the 1K resistor replacing the pot the speed was consistent at least, so it appears to be the presence of the pot that is throwing some chaos in.

Which means I am kind of stuck where I started again...


how is the pot wired-- is one side of the fixed resistance going to ground? Sounds like the motor driver should work fine at 5V... perhaps the problems you are experiencing are just from the unstable landscape of the breadboard.. perhaps it is time to wire it up and eliminate problems one by one?

the pot had one leg to ground, one leg to the amp input, one leg going to the - leg of the 4.7 capacitor.

Yes I think it is unstable breadboard stuff... I removed the pot and wired the mic output directly into the amp input, and altered the code a little so the motor driver doesn't over do it. This all works now and is nice and stable, so time to wire it all up properly now I think.

Many thanks for your help.

Hello, all goes well with the project. I would, however, still like to be able to check up on the amplitude value coming from the amp via serial communication, in order to fine tune and understand things a little further.

in a previous reply you mention that I should "check the conversion time for the A/d converters in the Atmega datasheet. You might not be catching things quickly enough"

I was wondering if you (or anyone else) could elaborate on this a little as I'm not sure what to do about it. I checked the datasheet: The conversion times for the a/d converters on the Atmega are "13 - 260 [ch956]s Conversion Time" I'm not really sure what this means, or what to do about it. Baud rates? any help is greatly appreciated.

One other thing to do is instead of hooking the 386 output to the arduino analog pin, hook it up to a small speaker and listen to the sound. When you are comfortable that the microphone amplifier section is working correctly then would be a good time to begin testing it with the arduino.

When dealing with electronic circuits it is better to work with small isolated parts independently and get them working properly. It is even important to do this with circuits you have built and tested before also because it is easy to diagnose problems in small well defined pieces.

Leave the testing of the whole designs to the very end of the process--you'll have enough problems with the butterfly effect on whole circuits with known working subcircuits.

On the Analog circuits and baud rates. The type of analog to digital converter used in the arduino does not perform an instaneous conversion--it uses a type od iteration to perform the conversion. This is why the conversions take up some period (up to ~250uS). When the conversion is complete you just read a register that contains a value between 0 and 1023. No serial communication is nescessary.

Hi, thanks for the help.

I’ll try it with a speaker and see what results I get.

I am still keen to actually get a reading of the values coming from the set up though, just to further my understanding of how this is working and the values that are being thrown around. Surely I need serial communication in order to write these values out to my mac though? I was trying to use Serial.print(amp) to try and get an idea of what amp (see code included above in my original post) was in order to know how to appropriately manipulate the initial amplitude value to suit my needs. I got the same values (47 49 52… all around that area) regardless of whether microphone was present or not… although I’ve corrected this I would still like to see these values for the purpose of fine tuning and greater understanding.


I'm sorry I misunderstood. Yes you will need to use the Hardware serial library to communicate with your Mac. The key to working with any kind of new technology is to break things into small pieces and test and work with each piece (whether software or hardware) until you understand how it works and make sure it is working right. When you understand the pieces (Serial communication, analog signals, the electric circuits, etc...) it makes it much easier to put together the real projects you are interested in.

If your confused about serial communications with your mac be sure to work through the Serial examples included with the arduino distribution--particularly the analog_read_send.pde example.